导航菜单
首页 >  蓝桥杯嵌入式真题国赛  > 【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式省赛[第一场]程序设计题以及详细题解

【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式省赛[第一场]程序设计题以及详细题解

文章目录原题展示原题分析原题题解LED相关LCD相关按键相关ADC相关定时器相关PWM输入捕获小结文章福利

原题展示

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

原题分析

  今年的第一场比赛绝对np,官方将串口直接省掉了,将其替换成很多小功能,如:切换计时、频率均匀变化、锁机制等等,总的来说本届赛题的难度提升了不少。   本届试题需要用到的功能模块有LCD、LED、按键、定时器输入捕获、定时器PWM输出、ADC获取,虽然这届试题模块简单,但是功能实现一点也不简单,感觉跟十二届省赛一样😂😂😂。   还值得注意的是:本届试题有三个地方需要计时,即模式切换、LED闪烁与长按键,,这可能是蓝桥杯为了提升难度的一个方向。(小编感觉这计时真的是恶心🤣🤣🤣)

原题题解 LED相关

  通过查询产品手册知,LED的引脚为PC8~PC15,外加锁存器74HC573需要用到的引脚PD2。(由于题目要求除题目要求需要使用的LED外其他LED都处于熄灭状态,此处特意将所有的LED都初始化以便于管理其他的LED灯) CubeMX配置: 代码样例   由于G431的所有LED都跟锁存器74HC573连接,因此每次更改LED状态时都需要先打开锁存器,写入数据后再关闭锁存器。

/****************************************************** 函数功能:改变所有LED的状态* 函数参数:*char LEDSTATE: 0-表示关闭 1-表示打开* 函数返回值:无******************************************************/void changeAllLedByStateNumber(char LEDSTATE){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,(LEDSTATE==1?GPIO_PIN_RESET:GPIO_PIN_SET));//打开锁存器准备写入数据HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);//关闭锁存器 锁存器的作用为 使得锁存器输出端的电平一直维持在一个固定的状态HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);}/****************************************************** 函数功能:根据LED的位置打开或者是关闭LED* 函数参数:*uint16_t LEDLOCATION:需要操作LED的位置*char LEDSTATE: 0-表示关闭 1-表示打开* 函数返回值:无******************************************************/void changeLedStateByLocation(uint16_t LEDLOCATION,char LEDSTATE){HAL_GPIO_WritePin(GPIOC,LEDLOCATION,(LEDSTATE==1?GPIO_PIN_RESET:GPIO_PIN_SET));HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);}

  试题要求的LED显示其条件都比较单一,在满足点亮条件时直接点亮,否则,就直接熄灭即可,至于闪烁的周期控制,可以借助与sysTick中断实现,如果就此再开一个定时器就有点浪费资源了。(虽然小编以前经常这样子干🤣🤣🤣)

  小编写的LED工作逻辑函数:

/**************************************** 函数功能:LED显示逻辑函数* 函数参数:无* 函数返回值:无***************************************/static void ledWork(void){// 数据界面LED1电量if(mod == 0)changeLedStateByLocation(LED1,1);elsechangeLedStateByLocation(LED1,0);// 切换期间 LED2闪烁if(LED2Flag && sysCount[1] >= 100){rollbackLedByLocation(LED2);sysCount[1] = 0;}else if(!LED2Flag)changeLedStateByLocation(LED2,0);// 锁定模式下 LED3电量if(lock)changeLedStateByLocation(LED3,1);elsechangeLedStateByLocation(LED3,0);} LCD相关

样例代码     由于LCD的相关代码在官方给的比赛资源数据包中存在,因此,可以直接调用资源包中的.c、.h文件来完成LCD的相关初始化以及显示。这是一个简单的LCD初始化函数,其功能是将LCD显示屏初始化为一个背景色为黑色、字体颜色为白色的屏幕,具体代码如下:

/******************************************************************************* 函数功能:LCD初始化* 函数参数:无* 函数返回值:无*******************************************************************************/void lcdInit(void){//HAL库的初始化LCD_Init();//设置LCD的背景色LCD_Clear(Black);//设置LCD字体颜色LCD_SetTextColor(White);//设置LCD字体的背景色LCD_SetBackColor(Black);}

    在显示时,可以借助于sprintf()函数将需要显示的数据格式成一个字符串,再在LCD上显示这个字符串。

char temp[20];sprintf(temp," M=%c ",mTable[M]);LCD_DisplayStringLine(Line3,(u8*)temp);

    为了操作LED与LCD显示方便,不让其相互干扰,小编这里对LCD进行了部分源码改写,使得每次LCD显示时不改变LED的显示状态,具体的方法各位可以点击查看【蓝桥杯】一文解决蓝桥杯嵌入式开发板(STM32G431RBT6)LCD与LED显示冲突问题,并讲述LCD翻转显示。

    下面附上小编完成的LCD部分的详细代码:

/**************************************** 函数功能:LCD显示数据* 函数参数:无* 函数返回值:无***************************************/static void lcdDisplay(){char temp[20];extern uint32_t cclValue ;// 数据显示界面if(mod == 0){LCD_DisplayStringLine(Line1,(u8*)"DATA ");sprintf(temp," M=%c ",mTable[M]);LCD_DisplayStringLine(Line3,(u8*)temp);sprintf(temp," P=%d%% ",pa1Zhan[1]);LCD_DisplayStringLine(Line4,(u8*)temp);sprintf(temp," V=%.1f ",V);LCD_DisplayStringLine(Line5,(u8*)temp);}// 参数显示界面else if(mod == 1){LCD_DisplayStringLine(Line1,(u8*)"PARA ");sprintf(temp," R=%d ",RK[0]);LCD_DisplayStringLine(Line3,(u8*)temp);sprintf(temp," K=%d ",RK[1]);LCD_DisplayStringLine(Line4,(u8*)temp);LCD_ClearLine(Line5);}// 统计界面else if(mod == 2){LCD_DisplayStringLine(Line1,(u8*)"RECD");sprintf(temp," N=%d",N);LCD_DisplayStringLine(Line3,(u8*)temp);sprintf(temp," MH=%.1f ",MH);LCD_DisplayStringLine(Line4,(u8*)temp);sprintf(temp," ML=%.1f ",ML);LCD_DisplayStringLine(Line5,(u8*)temp);}}

(是不是非常简单粗暴。哈哈哈哈)

按键相关

    通过查询产品手册知,开发板上的四个按键引脚为PB0~PB2、PA0。 CubeMX配置 代码样例

  由于题中涉及到长按键,因此此处将不再使用延时消抖,可以使用三行按键完成长按键与短按键设计,其核心代码就是三行逻辑运算完成消抖等一系列操作,但是在轮询系统中可能会存在漏检的问题。其完整代码如下:

//

相关推荐: