0


蓝桥杯第十三届嵌入式省赛真题(STM32G431RBT6——基于HAL库)

文章目录


前言

相关说明:

开发板:CT117E-M4(STM32G431RBT6)
开发环境: CubeMX+Keil5
涉及题目:第十三届蓝桥杯嵌入式真题


CubeMX配置、主要函数代码及说明:

一、CubeMX配置(第十三届真题完整版)

1.使能外部高速时钟:
在这里插入图片描述
2.配置时钟树:
在这里插入图片描述
3.GPIO:
在这里插入图片描述
4.TIM2(通道2 PA1输出方波、脉冲信号):
在这里插入图片描述5.UART:
在这里插入图片描述
6.NVIC优先级配置在这里插入图片描述


二、代码相关定义、声明

1.变量声明

unsignedchar psd[3]={0x40,0x40,0x40};//定义输入密码数组 并初始化为@@@unsignedchar psd_now[3]={0x31,0x32,0x33};//定义正确密码数组 并初始化为1,2,3的ASCII码值unsignedchar jiemian;//显示界面  0为输入密码界面  1为状态输入界面unsignedchar led_ctrl;//正确输入密码后置1  LED1点亮unsignedchar uled;//LED显示参数unsignedchar error_num;//存储错误输入密码次数unsignedchar rx,rx_buf[7],dex;//串口相关变量unsignedchar led_alarm;//密码错误次数3次以上时置1  LED2闪烁unsignedchar pwm;//初始为0  默认输出方波  1为输出脉冲
__IO uint32_t PWM_Tick;//计时脉冲输出时间

2.函数声明

代码如下(示例):

voidKey_Proc();voidLcd_Proc();voidUart_Proc();voidLed_Proc();

三、主要函数

1.main函数

intmain(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();/* USER CODE BEGIN 2 */LCD_Init();LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);__HAL_TIM_SET_AUTORELOAD(&htim2,999);__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);HAL_UART_Receive_IT(&huart1,&rx,1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Key_Proc();Lcd_Proc();Uart_Proc();Led_Proc();}/* USER CODE END 3 */}

2.按键扫描

voidKey_Proc(){static __IO uint32_t Key_Tick;//减速变量staticunsignedchar key_old;unsignedchar key_down,key_value;if(uwTick-Key_Tick<50)return;
    Key_Tick=uwTick;
    
    key_value=Key_Scan();
    key_down=key_value&(key_value^key_old);
    key_old=key_value;switch(key_down){case1:if(jiemian==0)//密码输入界面时有效{if(++psd[0]>=0x3A)//初始为@时(0x40>0x3A)  按下B1变为0的ASCII值
                    psd[0]=0x30;//限定为0~9循环}break;case2:if(jiemian==0)//密码输入界面时有效{if(++psd[1]>=0x3A)//初始为@时(0x40>0x3A)  按下B2变为0的ASCII值
                    psd[1]=0x30;//限定为0~9循环}break;case3:if(jiemian==0)//密码输入界面时有效{if(++psd[2]>=0x3A)//初始为@时(0x40>0x3A)  按下B3变为0的ASCII值
                    psd[2]=0x30;//限定为0~9循环}break;case4://密码确认键if((psd[0]==psd_now[0])&&(psd[1]==psd_now[1])&&(psd[2]==psd_now[2]))//密码输入正确{
                jiemian=1;//进入状态输出界面
                led_ctrl=1;//LED1点亮
                error_num=0;//错误次数清零
                pwm=1;//输出脉冲
                PWM_Tick=uwTick;//输出脉冲计时开始LCD_Clear(Black);//切换屏幕时清屏}else//密码输入错误  停留在密码输入界面{
                error_num++;//错误次数+1if(error_num>=3)//错误次数大于等于3时
                    led_alarm=1;//LED2开始闪烁报警
                psd[0]=psd[1]=psd[2]=0x40;//三位密码值重置为@}break;}}

3.屏幕显示和脉冲方波转换

voidLcd_Proc(){static __IO uint32_t Lcd_Tick;减速变量
    unsignedchar lcd_string[21];if(uwTick-Lcd_Tick<100)return;
    Lcd_Tick=uwTick;if(pwm==0)//密码输入界面时  输出方波{__HAL_TIM_SET_AUTORELOAD(&htim2,999);//设置频率1000Hz__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);//设置占空比50%}else//状态输出界面时  输出脉冲{__HAL_TIM_SET_AUTORELOAD(&htim2,499);//设置频率2000Hz__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);//设置占空比10%}if(uwTick-PWM_Tick>5000)//判断脉冲是否输出5秒{if(jiemian)//确保进入状态输出界面{
            pwm=0;//输出5秒后转换为方波
            jiemian=0;//进入密码输入界面
            psd[0]=psd[1]=psd[2]=0x40;//三位密码值重置为@LCD_Clear(Black);//切换屏幕时清屏}}if(jiemian==0)//密码输入界面时{sprintf((char*)lcd_string,"       PSD");LCD_DisplayStringLine(Line1,lcd_string);sprintf((char*)lcd_string,"    B1:%c",psd[0]);//密码第一位按字符输出LCD_DisplayStringLine(Line3,lcd_string);sprintf((char*)lcd_string,"    B2:%c",psd[1]);//密码第二位按字符输出LCD_DisplayStringLine(Line4,lcd_string);sprintf((char*)lcd_string,"    B3:%c",psd[2]);//密码第三位按字符输出LCD_DisplayStringLine(Line5,lcd_string);}else//状态输出界面时{sprintf((char*)lcd_string,"       STA");LCD_DisplayStringLine(Line1,lcd_string);if(pwm==0)//输出方波时{sprintf((char*)lcd_string,"    F:1000Hz");LCD_DisplayStringLine(Line3,lcd_string);sprintf((char*)lcd_string,"    D:50%%");LCD_DisplayStringLine(Line4,lcd_string);}else//输出脉冲时{sprintf((char*)lcd_string,"    F:2000Hz");LCD_DisplayStringLine(Line3,lcd_string);sprintf((char*)lcd_string,"    D:10%%");LCD_DisplayStringLine(Line4,lcd_string);}}}

4.判断串口接收数据是否合法

unsignedcharisRxCplt()//接收数据合法时返回值为1{unsignedchar i;if(dex!=7)//接收数据不为7个ASCII时不合法return0;if(rx_buf[3]==0x2D)//接收数据第四个为'-'时{for(i=0;i<3;i++){if((rx_buf[i]<'0')||(rx_buf[i]>'9'))//接收数据不为阿拉伯数字时不合法return0;}for(i=4;i<7;i++){if((rx_buf[i]<'0')||(rx_buf[i]>'9'))//接收数据不为阿拉伯数字时不合法return0;}return1;}else//接收数据第四个不为'-'时不合法return0;}

5.修改密码

voidUart_Proc(){static __IO uint32_t Uart_Tick;//减速变量unsignedchar tx[21];if(uwTick-Uart_Tick<100)return;
    Uart_Tick=uwTick;if(isRxCplt())//接收数据合法{if((rx_buf[0]==psd_now[0])&&(rx_buf[1]==psd_now[1])&&(rx_buf[2]==psd_now[2]))//当前密码正确{
            psd_now[0]=rx_buf[4];//修改密码
            psd_now[1]=rx_buf[5];//修改密码
            psd_now[2]=rx_buf[6];//修改密码sprintf((char*)tx,"Ok\n");HAL_UART_Transmit(&huart1,tx,strlen(tx),50);//向上位机发送OK表示修改成功}else//当前密码不正确{sprintf((char*)tx,"Error\n");HAL_UART_Transmit(&huart1,tx,strlen(tx),50);//向上位机发送Error表示修改失败}}
    
    dex=0;//清除串口接收数组索引}

6.串口中断

voidHAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
    rx_buf[dex]=rx;//一位一位存入缓存数组
    dex++;//索引+1HAL_UART_Receive_IT(&huart1,&rx,1);//重新开启接收中断}

7.LED闪烁

voidLed_Proc(){static __IO uint32_t Led_Tick,DLed_Tick;//减速变量staticunsignedchar flag;//报警灯标志位if(uwTick-Led_Tick<100)return;
    Led_Tick=uwTick;if(led_ctrl)//指示灯标志位为1表示开启LED1{
        DLed_Tick=uwTick;//计时开始
        led_ctrl=0;//指示灯LED1标志位清零,避免DLed_Tick重复赋值
        uled|=0x01;//点亮LED1}if(uwTick-DLed_Tick>=5000){
        uled&=~0x01;//指示灯LED1熄灭
        uled&=~0x02;//报警灯LED2熄灭
        flag=0;//报警灯标志位清零,LED2停止闪烁}if(led_alarm)//报警标志位为1时{
        led_alarm=0;//报警标志位清零  避免DLed_Tick重复赋值
        DLed_Tick=uwTick;//开始计时
        flag=1;//LED2闪烁标志位}if(flag)//LED2闪烁标志位为1{
        uled^=0x02;//LED2闪烁}Led_Disp(uled);//LED显示函数}

四、比赛感受

   本次比赛一波三折,赛前我去赛点测试,赛点CubeMx软件不支持64位,也没有32位java环境,也没有CubeMx G4安装包,Keil软件编译有问题,我刚好我的U盘里有安装包,解决了这些问题。
   比赛当天问题又出现了,我的电脑识别不了板子驱动,我检查驱动和更换电脑花费了1个半多小时,但是新电脑的Keil用调试器下载不进去,我就卸载了Keil进行重装,并安装Pack包和破解Keil,由于电脑有点卡,安装时间挺长的,安好已经两个多小时过去了,我代码只写好了底层的LED和按键,我心态挺好的,用了40分钟将程序写完,10分钟做完了选择题。
   当距离考试结束还有10分钟的时候我发现我的hex文件命名错误,我命名的是12345678.hex,官方要求G12345678.hex,否则零分,我赶紧把命名修改重新生成代码并提交。
   虽然有惊无险,但还是挺考验人心态的。


附件:第十三届蓝桥杯嵌入式程序设计、客观题PDF

https://pan.baidu.com/s/1dRRJ-YtspxH4qB_CJSohLA?pwd=wyff


本文转载自: https://blog.csdn.net/weixin_45949982/article/details/124065431
版权归原作者 魏丶 所有, 如有侵权,请联系我们删除。

“蓝桥杯第十三届嵌入式省赛真题(STM32G431RBT6&mdash;&mdash;基于HAL库)”的评论:

还没有评论