行业知识
第十三届蓝桥杯嵌入式省赛程序设计详细题解
2026-11-07 03:25:26
来源:互联网转载
���十三届蓝桥杯嵌入式省赛题目相对于第十二届较为简单,没有那么多串口的数据处理以及判断!
第十三届省赛主要是制作一个可由串口设置密码的密码锁。本实验中,我们将用到LED模块、按键模块、串口模块、定时器的PWM模块以及官方会提供源码的LCD模块。
文末有小编写的代码
一、CubeMX配置
1.使能外部高速时钟:
2.配置时钟树:
3.GPIO输出
4.GPIO输入
5. TIM定时器
5.1 TIM2输出PWM脉冲
设置默认Pluse为50,即占空比为50%
5.2 TIM4实现定时5s
5.3 TIM3定时器实现微妙(us)延迟
6.USART(通信)
USART串口接收数据,我使用两种方法实现,大家选取其中一种即可!
1.定长接收数据
2,不定长接收数据+DMA方式
此种方法的核心是空闲中断!
二、代码实现
2.1 main函数实现
int main(void){ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); MX_USART1_UART_Init(); MX_TIM3_Init(); MX_TIM4_Init(); MX_TIM1_Init(); /* USER CODE BEGIN 2 */ LCD_Init(); LCD_Clear(Black); LCD_SetBackColor(Black); LCD_SetTextColor(White);HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);led(1,0);led(2,0);led(3,0);led(4,0);led(5,0);led(6,0);led(7,0);led(8,0); HAL_UART_Receive_IT(&huart1, buff, 7);HAL_TIM_Base_Start_IT(&htim4); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ Key_handle(); lcd(); if(key4_count>=3&&led_flag==0) {led(2,1);delay_us(50000);delay_us(50000);led(2,0);delay_us(50000);delay_us(50000); } } /* USER CODE END 3 */} 2.2 lcd函数实现
void lcd(){if(pass_flag==1){show_output();if(systick-PWMTick>5000){led(1,0);pwm1();first='@';first_flag=-1;second='@';second_flag=-1;third='@';third_flag=-1;pass_flag=0;LCD_Clear(Black);}}if(pass_flag==0){show_input();}}void show_input(){LCD_DisplayStringLine(Line1," PSD ");sprintf(B1," B1:%c",first);LCD_DisplayStringLine(Line3,B1);sprintf(B2," B2:%c",second);LCD_DisplayStringLine(Line4,B2);sprintf(B3," B3:%c",third);LCD_DisplayStringLine(Line5,B3);}char pl[50];char zkb[50];int c_pl;int c_ARR;int c_zkb;int c_pluse;void show_output(){LCD_DisplayStringLine(Line1," STA ");c_ARR=__HAL_TIM_GET_AUTORELOAD(&htim2);c_pl=100000/(c_ARR+1);sprintf(pl," F:%dHz",c_pl);LCD_DisplayStringLine(Line3,pl);c_pluse=__HAL_TIM_GET_COMPARE(&htim2,TIM_CHANNEL_2);c_zkb=c_pluse*100/(c_ARR+1);sprintf(zkb," S:%d%%",c_zkb);LCD_DisplayStringLine(Line4,zkb);} 2.3 按键扫描功能实现
int Keynum(){int key=0;if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==0){HAL_Delay(5);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==0){key=1; LCD_Clear(Black);}while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==0);}if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)==0){HAL_Delay(5);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)==0){key=2; LCD_Clear(Black);}while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)==0);}if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0){HAL_Delay(5);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0){key=3; LCD_Clear(Black);}while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0);}if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0){HAL_Delay(5);if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0){key=4; LCD_Clear(Black);}while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0);}return key;}char first='@';int first_flag=-1;char second='@';int second_flag=-1;char third='@';int third_flag=-1;char pass1='1';char pass2='2';char pass3='3';int pass_flag=0;int lcd_flag=0;int ledTick=0;void Key_handle(){int keynum=Keynum();if(keynum==1){first_flag++;switch(first_flag%10){case 0:first='0';break;case 1:first='1';break;case 2:first='2';break;case 3:first='3';break;case 4:first='4';break;case 5:first='5';break;case 6:first='6';break;case 7:first='7';break;case 8:first='8';break;case 9:first='9';break;}}if(keynum==2){second_flag++;switch(second_flag%10){case 0:second='0';break;case 1:second='1';break;case 2:second='2';break;case 3:second='3';break;case 4:second='4';break;case 5:second='5';break;case 6:second='6';break;case 7:second='7';break;case 8:second='8';break;case 9:second='9';break;}}if(keynum==3){third_flag++;switch(third_flag%10){case 0:third='0';break;case 1:third='1';break;case 2:third='2';break;case 3:third='3';break;case 4:third='4';break;case 5:third='5';break;case 6:third='6';break;case 7:third='7';break;case 8:third='8';break;case 9:third='9';break;}}if(keynum==4){led_flag=0;key4_count++;if(pass1==first&&pass2==second&&pass3==third){key4_count=0;pass_flag=1;pwm2();led(1,1);//定时器中断在回调函数中清屏函数不起作用//__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_UPDATE);// HAL_TIM_Base_Start_IT(&htim1);PWMTick=systick;}else{pass_flag=0;first='@';first_flag=-1;second='@';second_flag=-1;third='@';third_flag=-1;}if(key4_count>=3){__HAL_TIM_CLEAR_FLAG(&htim4,TIM_FLAG_UPDATE); HAL_TIM_Base_Start_IT(&htim4);}}} 2.4 PWM脉冲转换
void pwm2(){__HAL_TIM_SET_AUTORELOAD(&htim2,50-1);__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,5);}//方波void pwm1(){__HAL_TIM_SET_AUTORELOAD(&htim2,100-1);__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);} 2.5 某种状态持续5s的两种操作方法
1.利用系统滴答计时器
本实验中 实现输出2KHz 10%占空比的脉冲信号,持续5秒钟,切换为 1KHz 方波信号输出的功能 使用的是系统滴答计时器。
2.TIM定时器定时5s
本实验中实现 指示灯 LD2 以 0.1秒为间隔亮、灭闪烁报警,5 秒后熄灭的功能使用的是TIM4定时器定时5s。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){if(htim->Instance==TIM4){led_flag=1;HAL_TIM_Base_Stop_IT(&htim4);}} 2.6 延迟100ms
delay_us函数实现定时微妙(us)
void delay_us(int delay){HAL_TIM_Base_Start(&htim3); // 启动定时器 __HAL_TIM_SET_COUNTER(&htim3, 0); // 重置计数器 while (__HAL_TIM_GET_COUNTER(&htim3) delay_us(50000)代表延迟50000us即50ms,但因为定时器最大计数值为65535,如果delay_us(100000)就超过了定时器最大计数值,所以可以采取delay_us(50000)两次来实现100ms定时!
2.7 USART串口与修改密码
USART串口接收数据,我使用两种方法实现,大家选取其中一种即可!
1.接收固定长度数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(buff[0]==pass1&&buff[1]==pass2&&buff[2]&&buff[3]=='-'&&judge()==1){pass1=buff[4];pass2=buff[5];pass3=buff[6];HAL_UART_Transmit(&huart1,(unsigned char *)"Success\r\n", 9, 50);}else{HAL_UART_Transmit(&huart1,(unsigned char *)"error\r\n", 7, 50);}HAL_UART_Receive_IT(&huart1, buff, 7);}int judge(){for(int i=0;iif((buff[i]return 1;}}}
上一篇:人工服务器怎么找人?