【物联网蓝桥杯嵌入式】蓝桥杯嵌入式第十三届真题代码详解(超级详细)

一、CubeMx配置

GPIO配置

定时器配置

USART串口通信配置

二、LED模块

三、LCD显示屏和脉冲模块

四、KEY模块

五、USART串口通信模块

在user.c里配置LED和KEY按键接口

user.c如下


#include "main.h"
void LED_disp(u8 led)  //LED模块
    {
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); //把PD2引脚置高电平(不作用)
        HAL_GPIO_WritePin(GPIOC,0xFF00,GPIO_PIN_SET);  //PC8-PC15引脚置高电平
        HAL_GPIO_WritePin(GPIOC,led<<8,GPIO_PIN_RESET);  //RESET低电平有效
        HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); //PD2置低,锁存器有效
    
    
}

u8 key_up;
u8 key_down;
u8 key_old=0;
u8 key_value;
void KEY_read()   //按键模块
{
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
    {     HAL_Delay(10); //延时10MS消抖
        key_value=1;
    }
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
        
{     HAL_Delay(10); //延时10MS消抖
        key_value=2;
}
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
    {     HAL_Delay(10); //延时10MS消抖
        key_value=3;
    }
    else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
    {    
        HAL_Delay(10); //延时10MS消抖
        key_value=4;
    }
    else key_value=0;  //没有按键
    
    
    key_up=~key_value&(key_value^key_old);  //按键弹起
    key_down=key_value&(key_value^key_old);  //按键按下
    key_old=key_value;
    
}
 

在main.c里实现比赛要求

main.c内容如下

#include "main.h"
#include "gpio.h"
#include "user.h"
#include "stdio.h"   //sprintf头文件
#include "string.h"   //strlen头文件

unsigned char ui=0;  //LCD屏幕
unsigned char password[3]={'1','2','3'};
extern size_t strlen(const char *);  

u8 error_num=0;//错误次数

u8 b1_value='@';  //按键B1的值
u8 b2_value='@';
u8 b3_value='@';    
u32 lcd_tick=0;
u8 lcd_buf[30];

u8 pwm;

void LCD_proc()
{
    if(uwTick-lcd_tick<100)
        return;
    lcd_tick=uwTick;
    if(pwm==0)  //1KHZ,50%占空比
    {
        __HAL_TIM_SET_AUTORELOAD(&htim2,999);  //频率1000
        __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);  //因为1000分之x=0.5
    }
    else  //2KHZ,10%占空比
    {
        __HAL_TIM_SET_AUTORELOAD(&htim2,499);  //频率2000  ,499是counter的值
        __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);  //因为500分之x=0.1
        
    }
    if(ui==0){
  

    sprintf((char *)lcd_buf,"       PSD");
    LCD_DisplayStringLine(Line0,lcd_buf);
            
    sprintf((char *)lcd_buf,"    B1:%c",b1_value);
    LCD_DisplayStringLine(Line3,lcd_buf);
        
    sprintf((char *)lcd_buf,"    B2:%c",b2_value);
    LCD_DisplayStringLine(Line4,lcd_buf);


    sprintf((char *)lcd_buf,"    B3:%c",b3_value);
    LCD_DisplayStringLine(Line5,lcd_buf); 
    }
    if(ui==1)
    {
        sprintf((char *)lcd_buf,"       STA");
    LCD_DisplayStringLine(Line0,lcd_buf);
    sprintf((char *)lcd_buf,"    F:2000HZ");
    LCD_DisplayStringLine(Line3,lcd_buf);
        sprintf((char *)lcd_buf,"    D:10%%");
    LCD_DisplayStringLine(Line4,lcd_buf);
        LCD_ClearLine(Line5);
        pwm=0;

    }
}

u32 key_tick;
int LD1 = 0; //记录LD1亮灭状态(在stm32g4xx_it.c 文件 SysTick_Handler 函数中使用)
int LD2_Flag = 0; //用来便捷LD2是否要闪烁(在stm32g4xx_it.c 文件 SysTick_Handler 函数中使用)
void KEY_proc()
{
    if(uwTick-key_tick<20)
        return;
    key_tick=uwTick;
    KEY_read();
    
if(ui==0){
    if(key_down==1)   
    {
            if(b1_value=='@')
                b1_value=48;   //0的ASCLL码是48,@是64,9是57,输出%c字符型
        
            else
            if(++b1_value>57)
            b1_value=48;
            
        }
     if(key_down==2)
    {
            if(b2_value=='@')  
                b2_value=48;
            else
            if(++b2_value>57)
            b2_value=48;
        
    }
     if(key_down==3)
    {
    
            if(b3_value=='@')  
                b3_value=48;
            else
            if(++b3_value>57)
            b3_value=48;
        
    }
     if( key_down==4){
             LCD_Clear(Black);
         if((b1_value==password[0])&&(b2_value==password[1])&&(b3_value==password[2]))
    {
            error_num=0; //输错次数清零
        sprintf((char *)lcd_buf,"       STA");
    LCD_DisplayStringLine(Line0,lcd_buf);
    sprintf((char *)lcd_buf,"    F:2000HZ");
    LCD_DisplayStringLine(Line3,lcd_buf);
        sprintf((char *)lcd_buf,"    D:10%%");
    LCD_DisplayStringLine(Line4,lcd_buf);
        LCD_ClearLine(Line5);
        
        pwm=!0;
        
        //LD1亮
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All , 1);
                        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8 , 0);
                        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 1);
                        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 0);
        LD1= 1;    //防止LD2闪烁时哪LD1关掉
        
        HAL_Delay(5000); //延迟5s
        LCD_Clear(Black);
        
                
         //LD1 灭
                        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All , 1); 
                        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 1);
                        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 0);
                LD1 = 0;        
                        b1_value='@';
                        b2_value='@';
                        b3_value='@';
    }
    else
    {
        b1_value=b2_value=b3_value='@';  //这样密码错误就可以到@@@
     error_num++;
        if(error_num > 2) //密码错误三次及以上
                        {
                            //LED2 以0.1秒闪烁
                            LD2_Flag = 1;//在stm32g4xx_it.c 文件 SysTick_Handler 函数中使用执行闪烁
                        }
           }
    }
}
}

uint8_t str [40];
 uint8_t rx_buffer;  //字节接收处  ///存的是原本的
 uint8_t counter=0;//等于3代表传进去的数字为3
 uint8_t RX_buff[7];//存新装进去的
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    RX_buff[counter++]=rx_buffer;
    if(counter==7)
    {
        if((RX_buff[0]==password[0])&&(RX_buff[1]==password[1])&&(RX_buff[2]==password[2]))
        {
            password[0]=(RX_buff[4]);
            password[1]=(RX_buff[5]);
            password[2]=(RX_buff[6]);
            sprintf(str,"sucess\r\n");
    }
        else
        {
            sprintf(str,"error\r\n");
        }
        HAL_UART_Transmit(&huart1,(unsigned char *)str,strlen(str),50);  
    }
    HAL_UART_Receive_IT(&huart1,(uint8_t *)(&rx_buffer),1);
}

int main(void)
{
 
  SystemClock_Config();


  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
 

   //初始化
     LED_disp(0);
    LCD_Init();

    UART_Start_Receive_IT(&huart1,(uint8_t *)(&rx_buffer),1);    //开启串行端口  1次接一个字节
 HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_2);  //打开定时器2用于PWM脉冲输出

    LCD_Clear(Black);
    LCD_SetBackColor(Black);
    LCD_SetTextColor(White);


    while (1)
    {
 
      //函数声明
            LCD_proc();
            KEY_proc();       
    }
 

stm32g4xx_it.c

实现LED2以0.1s闪烁

在stm32g4xx_it.c 文件 SysTick_Handler 函数内容如下

int time_ms = 0;
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

    extern int LD2_Flag;
    extern int LD1;
    if(LD2_Flag == 1)
    {
        if(time_ms == 5000) //5秒钟到
        {
            time_ms = 0;
            LD2_Flag = 0;
            return;
        }
        
        if((time_ms % 200) == 0) //灯亮
        {
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All , 1);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9 , 0);
            
                if(LD1 == 1) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8 , 0);
                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 1);
                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 0);
        }
        else if((time_ms % 100) == 0) //灭
        {
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All , 1);
                if(LD1 == 1) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8 , 0);
                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 1);
                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2 , 0);
        }
        time_ms ++ ;
    }
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值