当前位置: 首页 > article >正文

第九届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)

一.题目分析

(1).题目

(2).题目分析

  1. 按键功能分析----存储位置切换键

a.  B1按下切换存储位置切换定时时间设定当前位置存储时间

b.  B2短切换时分秒+高亮,设置完成后设置时间保存当前位置如果设置定时时间需要存储,直接按定时器启动按键

c.  B3短按单次递增时分秒长按超过8s开始迅速递增

d.  B4,定时器启动,运行期间短按,定时器暂停再次按下定时器恢复运行B4超过0.8s取消定时器运行

(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 "I2C\bsp_i2c.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_Long_Short_Judge = 0;//短长按键判断专用
uint8_t ucState;//系统整体运行状态
uint8_t ucHour_Min_Sec[3];//小时分钟秒
uint8_t Storage_Num = 1;//存储序号
__IO uint32_t Sec_Boss = 0;//全局的秒变量
__IO uint32_t uwTick_Sec_Boss = 0;//控制秒的递减
__IO uint32_t uwTick_LED_BULING = 0;//控制LED闪烁
//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);

2.系统主函数

int main(void)
{
  SystemClock_Config();

    /*bsp资源的初始化*/
    KEY_LED_Init();   
    LCD_Init();
    LCD_Clear(White);
  LCD_SetBackColor(White);
  LCD_SetTextColor(Blue);        
    I2CInit();
    PWM_OUTPUT_TIM3_Init();

    /*外设使用基本配置*/    
    iic_24c02_read(ucHour_Min_Sec, 0, 3);         
  while (1)
  {
        Key_Proc();
        Led_Proc();
        Lcd_Proc(); 
  }

}

3.子函数

B3扫描子函数

a.逻辑分析

由于按键3没有长按短按的判断,因此单独写一个函数,此函数的功能是判断是在状态几的时候按下的B3,以此对时分秒进行置零操作(每24小时/每60分钟/ 每60秒就置零)

b.程序源码

#include "main.h"
#include "RCC\bsp_rcc.h"
#include "KEY_LED\bsp_key_led.h"
#include "LCD\bsp_lcd.h"
#include "I2C\bsp_i2c.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_Long_Short_Judge = 0;//短长按键判断专用
uint8_t ucState;//系统整体运行状态
uint8_t ucHour_Min_Sec[3];//小时分钟秒
uint8_t Storage_Num = 1;//存储序号
__IO uint32_t Sec_Boss = 0;//全局的秒变量
__IO uint32_t uwTick_Sec_Boss = 0;//控制秒的递减
__IO uint32_t uwTick_LED_BULING = 0;//控制LED闪烁
//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);
按键扫描子函数

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(unKey_Down)
    {
        uwTick_Long_Short_Judge = uwTick;
    }    
    
    if((uwTick - uwTick_Long_Short_Judge) < 800)//短按识别
    {
        switch(ucKey_Up)
        {
            case 2://如果B2短按
                    if( ++ucState == 4)
                        ucState = 1;
                    
                break;
            
            case 4://如果B4短按
                if(ucState != 4)
                {    
                    ucState = 4;
                  Sec_Boss = (__IO uint32_t)(3600*ucHour_Min_Sec[0] + 60*ucHour_Min_Sec[1] +ucHour_Min_Sec[2]);
                    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);    //PA6,启动PWM的产生
                }
                else 
                {
                    ucLed = 0x00;        //关闭LED闪烁
                    HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1); //关闭PWM生成
                    ucState = 5;
                }
            break;
                
            case 3://如果B3短按,时分秒进行+1操作(一会儿写)
                B3_Ctrl();
            break;
            
            case 1://如果B1短按,切换存储位置(一会儿写)
                if(++Storage_Num == 6) Storage_Num = 1;
                iic_24c02_read(ucHour_Min_Sec, (3*(Storage_Num-1)), 3);                    
            break;        
            
        }
    }
    else //长按
    {
        switch(ucKey_Val)
        {
            case 2://如果B2长按,进入状态0
                if((ucState == 1)||(ucState == 2)||(ucState == 3))
                {                
                    iic_24c02_write(ucHour_Min_Sec,(3*(Storage_Num-1)) , 3);            
                    ucState = 0;
                }
                break;
            
            case 3://如果B3长按,时分秒连续进行+1操作(一会儿写)
                B3_Ctrl();                
            break;    
            
            case 4://如果B4长按,运行状态下进入状态0
                if(ucState == 4)
                {
                    ucLed = 0x00;        //关闭LED闪烁
                    HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1); //关闭PWM生成        
                    iic_24c02_read(ucHour_Min_Sec, (3*(Storage_Num-1)), 3);                        
                    ucState = 0;
                }                
            break;            

        }
    }
LED扫描子函数

a.程序源码

void Led_Proc(void)
{
    if((uwTick -  uwTick_Led_Set_Point)<200)    return;//减速函数
        uwTick_Led_Set_Point = uwTick;  
    LED_Disp(ucLed);
}

 LCD扫描子函数

a.逻辑分析

b. 程序源码

void Lcd_Proc(void)
{
    if((uwTick -  uwTick_Lcd_Set_Point)<100)    return;//减速函数
        uwTick_Lcd_Set_Point = uwTick;
    
    if(ucState == 4)//此状态控制递减操作
    {
        if((uwTick - uwTick_Sec_Boss) >= 1000)//1s到来了,控制倒计时
        {
            uwTick_Sec_Boss = uwTick;
            Sec_Boss--;
            
            ucHour_Min_Sec[0] = Sec_Boss/3600;
            ucHour_Min_Sec[1] = Sec_Boss%3600/60;        
            ucHour_Min_Sec[2] = Sec_Boss%3600%60;        
        }
    
        if((uwTick - uwTick_LED_BULING) >= 500)//0.5s到来了,控制LED闪烁
        {
            uwTick_LED_BULING = uwTick;        
            ucLed ^= 0x01;    
        }
    }

        sprintf((char *)Lcd_Disp_String, "  No %1d",Storage_Num);
        LCD_DisplayStringLine(Line3, Lcd_Disp_String);    
        
        
        if(ucState == 1)   LCD_SetBackColor(Yellow);
        LCD_DisplayChar(Line5, 224, (ucHour_Min_Sec[0]/10 + 0x30));
        LCD_DisplayChar(Line5, 208, (ucHour_Min_Sec[0]%10 + 0x30));    
        LCD_SetBackColor(White);
        
        LCD_DisplayChar(Line5, 192, ':');    

        if(ucState == 2)   LCD_SetBackColor(Yellow);
        LCD_DisplayChar(Line5, 176, (ucHour_Min_Sec[1]/10 + 0x30));
        LCD_DisplayChar(Line5, 160, (ucHour_Min_Sec[1]%10 + 0x30));    
        LCD_SetBackColor(White);
        
        LCD_DisplayChar(Line5, 144, ':');        
        
        if(ucState == 3)   LCD_SetBackColor(Yellow);
        LCD_DisplayChar(Line5, 128, (ucHour_Min_Sec[2]/10 + 0x30));
        LCD_DisplayChar(Line5, 112, (ucHour_Min_Sec[2]%10 + 0x30));            
        LCD_SetBackColor(White);

    switch(ucState)//仅用来表示状态信息
    {
        case 0:
            sprintf((char *)Lcd_Disp_String, "    Standby     ");
            LCD_DisplayStringLine(Line7, Lcd_Disp_String);            
            break;
        
        case 1:
        case 2:
        case 3:
            sprintf((char *)Lcd_Disp_String, "    Setting     ");
            LCD_DisplayStringLine(Line7, Lcd_Disp_String);        
            break;    
    
        case 4:
            sprintf((char *)Lcd_Disp_String, "    Running     ");
            LCD_DisplayStringLine(Line7, Lcd_Disp_String);            
            break;

        case 5:
            sprintf((char *)Lcd_Disp_String, "    Pause     ");
            LCD_DisplayStringLine(Line7, Lcd_Disp_String);            
            break;
    }
}

(2)BSP

第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客里面有详细的讲解,大家可前往此链接学习


http://www.kler.cn/news/324728.html

相关文章:

  • 可视化服务编排:jvs-logic API出参加密实战教程
  • 基于springboot vue 大学生竞赛管理系统设计与实现
  • LoRA - 大模型的低秩适应方法
  • springboot第74集:设计模式
  • 在二维平面中,利用时差定位(TDOA)技术,结合N个锚点,通过三边法进行精确定位,采用MATLAB实现
  • 2015年国赛高教杯数学建模A题太阳影子定位解题全过程文档及程序
  • django开发流程2
  • 如何借助Java批量操作Excel文件?
  • 实验一 网络基础及仿真模拟软件Packet Tracer 入门
  • Web Components 代码示例
  • 理解互联网链路:从本地ISP到Tier 1 ISP运营商
  • [算法】模拟:(leetcode)1419.数青蛙(medium)
  • 5 apache poi实现excel的动态下拉框功能
  • 1.1.5 计算机网络的性能指标(上)
  • 力扣 最小覆盖子串
  • 胤娲科技:AI程序员——重塑编程世界的魔法师
  • Spring Boot影院管理系统:小徐的创新
  • 02_OpenCV图片写入
  • select和epoll的详细区别
  • 基于Springboot+Vue的高校教室资源管理系统的设计与实现(含源码+数据库)
  • Oracle表空间管理(三)
  • Open WebUI部署自己的大模型
  • 基于微信小程序的智慧社区的设计与实现
  • 如何使用Kimi编写商品管理设计文档:包含流程图和用例图
  • Springboot+PostgreSQL+MybatisPlus存储JSON或List、数组(Array)数据
  • 【数据治理-设计数据标准】
  • 数据库入门不再难:克服学习障碍的实用技巧与演示
  • 《北方牧业》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • 甄选范文“论软件架构建模技术与应用”,软考高级论文,系统架构设计师论文
  • 工程设备包括哪些内容?