第十三届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(第一场)
b. 密码确认功能B4,密码正确就跳转到输出状态页面,不正确就停留在输入界面,同时显示界面的三位密码值。b.输入正确密码时,PA1输出2KHz 10%占空比的脉冲信号持续5秒,之后切换回密码输入界面@@@发送指定格式:当前密码-新密码,可修改密码,如果当前密码不正确就无法修改。a. 密码调整功能,按下B1,B2,B3三位密码值分别加1,按键。b.连续三次及以上的密码输入错误,LD2以0.1秒闪烁5
一.题目分析
(1).题目




(2).题目分析
1.按键功能分析
a. 密码调整功能,按下B1,B2,B3三位密码值分别加1,按键刚上电显示界面的密码值为@
b. 密码确认功能B4,密码正确就跳转到输出状态页面,不正确就停留在输入界面,同时显示界面的三位密码值重置为@
2.脉冲输出功能分析
a.无正确密码提交时,PA1输出1KHz的方波信号
b.输入正确密码时,PA1输出2KHz 10%占空比的脉冲信号持续5秒,之后切换回密码输入界面@@@
3.串口通信功能分析
发送指定格式:当前密码-新密码,可修改密码,如果当前密码不正确就无法修改
4.LED指示功能分析
a.密码验证成功,LD1亮5秒之后熄灭
b.连续三次及以上的密码输入错误,LD2以0.1秒闪烁5秒熄灭
(3).逻辑导图

二.CubeMX配置
由于蓝桥杯使用的板子都是STM32G431RBT6,配置都是相同的,模板已经在第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客配置完成,大家可以前往学习
三.相关代码实现
(1)MAIN
1.全局变量声明
#include "main.h"
#include "RCC\bsp_rcc.h"
#include "KEY_LED\bsp_key_led.h"
#include "LCD\bsp_lcd.h"
#include "UART\bsp_uart.h"
#include "TIM\bsp_tim.h"
//***全局变量声明区
//*减速变量
__IO uint32_t uwTick_Key_Set_Point = 0;//控制Key_Proc的执行速度
__IO uint32_t uwTick_Led_Set_Point = 0;//控制Led_Proc的执行速度
__IO uint32_t uwTick_Lcd_Set_Point = 0;//控制Lcd_Proc的执行速度
__IO uint32_t uwTick_Usart_Set_Point = 0;//控制Usart_Proc的执行速度
//*按键扫描专用变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;
//*LED专用变量
uint8_t ucLed;
//*LCD显示专用变量
uint8_t Lcd_Disp_String[21];//最多显示20个字符
//*串口专用变量
uint8_t counter = 0;
uint8_t str[40];
uint8_t rx_buffer;
uint8_t RX_Buff[7];
//全局变量
unsigned char B1_value = 255;
unsigned char B2_value = 255;
unsigned char B3_value = 255;
unsigned char Screen_Disp_Flag;
unsigned char Password[3] = {1, 2, 3};
__IO uint32_t uwTick_PWM_Output = 0;//控制PWM输出为5s
unsigned char PWM_Output_Just_Do_One_Time;
unsigned char KEY_input_error = 0;
__IO uint32_t uwTick_LED_BULING = 0;//控制LED在连续三次以上出错后的闪烁
unsigned char LED_BULING_Ctrl;
//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);
void Usart_Proc(void);
2.系统主函数
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/*bsp资源的初始化*/
KEY_LED_Init();
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
UART1_Init();
MX_TIM2_Init();
//*串口接收中断打开
HAL_UART_Receive_IT(&huart1, (uint8_t *)(&rx_buffer), 1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2); //PA1
while (1)
{
Key_Proc();
Led_Proc();
Lcd_Proc();
Usart_Proc();
}
}
3.按键扫描子函数
a. 逻辑框图

b. 程序源码
//***按键扫描子函数
void Key_Proc(void)
{
if((uwTick - uwTick_Key_Set_Point)<50) return;//减速函数
uwTick_Key_Set_Point = uwTick;
ucKey_Val = Key_Scan();
unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val);
ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);
ucKey_Old = ucKey_Val;
if(Screen_Disp_Flag == 0)
{
if(unKey_Down == 1)
{
if(++B1_value == 10)
B1_value = 0;
}
if(unKey_Down == 2)
{
if(++B2_value == 10)
B2_value = 0;
}
if(unKey_Down == 3)
{
if(++B3_value == 10)
B3_value = 0;
}
if(unKey_Down == 4)
{
if((B1_value == Password[0])&&(B2_value == Password[1])&&(B3_value == Password[2]))
{
Screen_Disp_Flag = 1;
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);//输出修改
__HAL_TIM_SET_AUTORELOAD(&htim2,499);
ucLed |= 0x01;
uwTick_PWM_Output = uwTick;
PWM_Output_Just_Do_One_Time = 1;
KEY_input_error = 0;
}
else
{
B1_value = 255;
B2_value = 255;
B3_value = 255;
KEY_input_error++;
if(KEY_input_error >= 3)
{
uwTick_LED_BULING = uwTick;
LED_BULING_Ctrl = 1;
}
}
}
}
if(((uwTick - uwTick_PWM_Output) >= 5000)&&(PWM_Output_Just_Do_One_Time == 1))
{
Screen_Disp_Flag = 0;
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);//输出修改
__HAL_TIM_SET_AUTORELOAD(&htim2,999);
B1_value = 255;
B2_value = 255;
B3_value = 255;
ucLed &= (~0x01);
PWM_Output_Just_Do_One_Time = 0;
}
}
4.LED扫描子函数
a. 逻辑分析
根据闪烁标志位控制LD2闪烁五秒熄灭
b. 程序源码
void Led_Proc(void)
{
if((uwTick - uwTick_Led_Set_Point)<100) return;//减速函数
uwTick_Led_Set_Point = uwTick;
if(((uwTick - uwTick_LED_BULING) <= 5000)&&(LED_BULING_Ctrl == 1))
{
ucLed ^= 0x02;
}
else
{
LED_BULING_Ctrl = 0;
ucLed &= (~0x02);
}
LED_Disp(ucLed);
}
5.LCD扫描子函数
a. 逻辑导图

b. 程序源码
void Lcd_Proc(void)
{
if((uwTick - uwTick_Lcd_Set_Point)<100) return;//减速函数
uwTick_Lcd_Set_Point = uwTick;
if(Screen_Disp_Flag == 0)
{
sprintf((char *)Lcd_Disp_String, " PSD ");
LCD_DisplayStringLine(Line1, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, " B1:%d ",(unsigned int)B1_value);
if(B1_value == 255)
sprintf((char *)Lcd_Disp_String, " B1:@ ");
LCD_DisplayStringLine(Line3, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, " B2:%d ",(unsigned int)B2_value);
if(B2_value == 255)
sprintf((char *)Lcd_Disp_String, " B2:@ ");
LCD_DisplayStringLine(Line4, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, " B3:%d ",(unsigned int)B3_value);
if(B3_value == 255)
sprintf((char *)Lcd_Disp_String, " B3:@ ");
LCD_DisplayStringLine(Line5, Lcd_Disp_String);
}
else
{
sprintf((char *)Lcd_Disp_String, " STA ");
LCD_DisplayStringLine(Line1, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, " F:2000Hz ");
LCD_DisplayStringLine(Line3, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, " D:10%% ");
LCD_DisplayStringLine(Line4, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, " ");
LCD_DisplayStringLine(Line5, Lcd_Disp_String);
}
}
6.串口接收中断回调函数
a. 逻辑导图

b. 程序源码
//串口接收中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
RX_Buff[counter] = rx_buffer;
counter++;
if(counter == 7)
{
if(((RX_Buff[0]-'0') == Password[0])&&((RX_Buff[1]-'0') == Password[1])&&((RX_Buff[2]-'0') == Password[2]))
{
Password[0] = (RX_Buff[4]-'0');
Password[1] = (RX_Buff[5]-'0');
Password[2] = (RX_Buff[6]-'0');
sprintf(str, "success\r\n");
}
else
{
sprintf(str, "error\r\n");
}
HAL_UART_Transmit(&huart1,(unsigned char *)str, strlen(str), 50);
counter = 0;
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)(&rx_buffer), 1);
}
(2)BSP
在第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客里面有详细的讲解,大家可前往此链接学习
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)