一.题目分析
(1).题目
(2).题目分析
1.参考配置界面
注意上限和下限的调整,上限值必须大于下限值,低于下限LD2会闪烁,低于上限LD1会闪烁
2.按键功能分析
B1:显示界面和设置界面相互切换,同时将数据保存到E2PROM里面
B2:切换选择参数选项
B3:加按键(指示灯序号和电压参数)---要有边界保护,电压参数设置范围是0~3.3V,LED设置为LD1~LD8
B4:减按键(指示灯序号和电压参数)---要有边界保护,电压参数设置范围是0~3.3V,LED设置为LD1~LD8
3.LED功能分析
a. 输出电压高于上限,上限指示灯闪烁
b.输出电压低于下限,下限指示灯闪烁
c. 输出电压在上下限之间,两灯熄灭
d.除了上下限指示灯以外的其他灯熄灭
(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 "ADC\bsp_adc.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的执行速度//*按键扫描专用变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;//*LED专用变量
uint8_t ucLed = 0x0;
uint8_t ucLed_Bor = 0x01;//*LCD显示专用变量
uint8_t Lcd_Disp_String[21];//最多显示20个字符//*EEPROM的相关变量
uint8_t EEPROM_String_1[5] = {0x11,0x22,0x33,0x44,0x55};
uint8_t EEPROM_String_2[5] = {0};//系统全局变量
uint8_t Sys_State;//整体状态
float Voltage;//R37的电压值
uint8_t Vot_State;//电压状态 0-低于 1-中间 2-高于
uint8_t Max_Min_LED[4] = {24,12,1,2};//0-上限值 1-下限值 2-高报警灯 3-低报警灯//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_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(White);LCD_SetBackColor(White);LCD_SetTextColor(Blue); I2CInit();ADC2_Init(); while (1){Key_Proc();Led_Proc();Lcd_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;switch(unKey_Down){case 1://B1按键if(Sys_State == 0) {Sys_State = 1;}else {Sys_State = 0; iic_24c02_write(Max_Min_LED, 0, 4);} LCD_Clear(White);break;case 2://B2按键if(Sys_State){if(++Sys_State == 5)Sys_State = 1;}break;// uint8_t Max_Min_LED[4];//0-上限值 1-下限值 2-高报警灯 3-低报警灯case 3://B3按键+switch(Sys_State){case 1://上限值+0.3Max_Min_LED[0] += 3;if((Max_Min_LED[0] >= 33)&&(Max_Min_LED[0] <= 40))Max_Min_LED[0] = 33;break;case 2://下限值+0.3if((Max_Min_LED[1]+3) < Max_Min_LED[0])Max_Min_LED[1] += 3; break; case 3:if(++Max_Min_LED[2] >=8) Max_Min_LED[2] = 8;if(Max_Min_LED[2] == Max_Min_LED[3]){if(Max_Min_LED[3] == 8)Max_Min_LED[2] = 7;else {if(++Max_Min_LED[2] >=8) Max_Min_LED[2] = 8; } } break; case 4:if(++Max_Min_LED[3] >=8) Max_Min_LED[3] = 8;if(Max_Min_LED[3] == Max_Min_LED[2]){if(Max_Min_LED[2] == 8)Max_Min_LED[3] = 7;else {if(++Max_Min_LED[2] >=8) Max_Min_LED[2] = 8; } } break; } break;case 4://B4按键-switch(Sys_State){case 1://上限值-0.3if((Max_Min_LED[0]-3) > Max_Min_LED[1])Max_Min_LED[0] -= 3; break;case 2://下限值-0.3Max_Min_LED[1] -= 3;if(Max_Min_LED[1] >= 200)Max_Min_LED[1] = 0; break; case 3://-if(--Max_Min_LED[2] == 0) Max_Min_LED[2] = 1;if(Max_Min_LED[2] == Max_Min_LED[3]){if(Max_Min_LED[3] == 1)Max_Min_LED[2] = 2;else {if(--Max_Min_LED[2] == 0) Max_Min_LED[2] = 1; } } break; case 4://-if(--Max_Min_LED[3] == 0) Max_Min_LED[3] = 1;if(Max_Min_LED[3] == Max_Min_LED[2]){if(Max_Min_LED[2] == 1)Max_Min_LED[3] = 2;else {if(--Max_Min_LED[2] ==0) Max_Min_LED[2] = 1; } } break; }break;}
}
3.LED扫描子函数
a.逻辑分析
根据上下限和中间值控制灯的亮灭
b.程序源码
//***LED扫描子函数
void Led_Proc(void)
{if((uwTick - uwTick_Led_Set_Point)<200) return;//减速函数uwTick_Led_Set_Point = uwTick;
//Max_Min_LED 2-高报警灯 3-低报警灯 LD8 ucLed 1000 0000switch(Vot_State){case 0://低于下限ucLed ^= ( ucLed_Bor << (Max_Min_LED[3]-1));break;case 1://中间ucLed = 0x00;break; case 2://高于上限ucLed ^= ( ucLed_Bor << (Max_Min_LED[2]-1)); break; }LED_Disp(ucLed);
}
3.LCD扫描子函数
a.逻辑框图
b.程序源码
void Lcd_Proc(void)
{if((uwTick - uwTick_Lcd_Set_Point)<100) return;//减速函数uwTick_Lcd_Set_Point = uwTick;//采集数据专用区域
// uint8_t Max_Min_LED[4];//0-上限值 1-下限值 2-高报警灯 3-低报警灯Voltage = ((((float)getADC2())/4096)*3.3);if((Voltage*10) > Max_Min_LED[0])Vot_State = 2;else if((Voltage*10) < Max_Min_LED[1])Vot_State = 0; else Vot_State = 1; //我的代码if(!Sys_State)//在主界面{sprintf((char *)Lcd_Disp_String, " Main ");LCD_DisplayStringLine(Line1, Lcd_Disp_String); sprintf((char *)Lcd_Disp_String, " Volt:%4.2fV",Voltage);LCD_DisplayStringLine(Line4, Lcd_Disp_String); switch(Vot_State){case 0:sprintf((char *)Lcd_Disp_String, " Status:Lower ");break;case 1:sprintf((char *)Lcd_Disp_String, " Status:Normal ");break; case 2:sprintf((char *)Lcd_Disp_String, " Status:Upper ");break; }LCD_DisplayStringLine(Line6, Lcd_Disp_String); }else//在设置界面{
// uint8_t Max_Min_LED[4];//0-上限值 1-下限值 2-高报警灯 3-低报警灯 sprintf((char *)Lcd_Disp_String, " Setting ");LCD_DisplayStringLine(Line1, Lcd_Disp_String); sprintf((char *)Lcd_Disp_String, " Max Volt:%3.1fV ",((float)Max_Min_LED[0]/10.0));if(Sys_State == 1) LCD_SetBackColor(Green);LCD_DisplayStringLine(Line4, Lcd_Disp_String); LCD_SetBackColor(White);sprintf((char *)Lcd_Disp_String, " Min Volt:%3.1fV ",((float)Max_Min_LED[1]/10.0));if(Sys_State == 2) LCD_SetBackColor(Green);LCD_DisplayStringLine(Line5, Lcd_Disp_String); LCD_SetBackColor(White);sprintf((char *)Lcd_Disp_String, " Upper:LD%1d ",(unsigned int)Max_Min_LED[2]);if(Sys_State == 3) LCD_SetBackColor(Green); LCD_DisplayStringLine(Line6, Lcd_Disp_String); LCD_SetBackColor(White); sprintf((char *)Lcd_Disp_String, " Lower:LD%1d ",(unsigned int)Max_Min_LED[3]);if(Sys_State == 4) LCD_SetBackColor(Green); LCD_DisplayStringLine(Line7, Lcd_Disp_String); LCD_SetBackColor(White); }
}
(2)BSP
在第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客里面有详细的讲解,大家可前往此链接学习