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

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

一.题目分析

(1).题目

(2).题目分析

1.按键功能分析

a.B1按下一次进入设定页面,再次按下退出设置页面同时保存设定

b.B2按下高亮选择三个待修改的阈值

c.增加阈值,每次增加5cm直到95cm

d.减少阈值,每次减少5cm直到5cm

2.输出分析

a.将上一次的数据缓存

b.判断这一次调整的等级与上一次是否一致

c.按题目所给的输出数据格式上报串口

(3).逻辑导图

二.CubeMX配置

由于蓝桥杯使用的板子都是STM32G431RBT6,配置都是相同的,模板已经在第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客配置完成,大家可以前往学习

三.相关代码实现

(1)MAIN

1.全局变量声明


//*减速变量
__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_Usart_Set_Point = 0;//控制Usart_Proc的执行速度
__IO uint32_t uwTick_Data_Set_Point = 0;//控制Data_Collect_Proc的执行速度

//*按键扫描专用变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;

//*LED专用变量
uint8_t ucLed;

//*LCD显示专用变量
uint8_t Lcd_Disp_String[21];//最多显示20个字符

//*串口专用变量
uint16_t counter = 0;
uint8_t str[40];
uint8_t rx_buffer;
//全局变量
uint8_t Interface_Num;//00-首界面,10-设置第一个阈值,11-设置第二个阈值,12-设置第三个阈值
float SUM_AD_R37;//求AD采集十次的数值的和
float AVE_AD_R37;//AD采集的平均值
uint8_t AD_Ctrl_Num;//AD控制采集次数的变量
uint8_t Height;//液位高度数值
uint8_t Level;//液面等级
uint8_t Level_Old;//液面等级,上一次的
uint8_t Compare_Level_Disp[3] = {30, 50, 70};//阈值初值
uint8_t Compare_Level_Ctrl[3] = {30, 50, 70};//阈值初值
_Bool Level_Change_Flag;//1-变化
uint8_t Buling_Times = 10;//变化次数为闪灭各5次
_Bool Uart_Get_Data;//1-变化
uint8_t Buling_Times_Uart = 10;//变化次数为闪灭各5次

//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);
void Usart_Proc(void);
void Data_Collect_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);		
	UART1_Init();
	I2CInit();
    ADC2_Init();
	/*外设使用基本配置*/	
	//*EEPROM测试
    iic_24c02_read(Compare_Level_Ctrl, 0, 3);	
	Compare_Level_Disp[0] = Compare_Level_Ctrl[0];
	Compare_Level_Disp[1] = Compare_Level_Ctrl[1];	
	Compare_Level_Disp[2] = Compare_Level_Ctrl[2];
	HAL_UART_Receive_IT(&huart1, (uint8_t *)(&rx_buffer), 1);	
  while (1)
  {
		Data_Collect_Proc();
		Key_Proc();
		Led_Proc();
		Lcd_Proc();
		Usart_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;
	if(unKey_Down == 1)
	{
		if(Interface_Num == 0x00)
		{
			Interface_Num = 0x10;
      LCD_Clear(White);
		}
		else
		{
			if((Compare_Level_Disp[0] < Compare_Level_Disp[1])&&(Compare_Level_Disp[1] < Compare_Level_Disp[2]))
			{
				Interface_Num = 0x00;
				LCD_Clear(White);					
				
   			iic_24c02_write(Compare_Level_Disp, 0, 3);	
				Compare_Level_Ctrl[0]= Compare_Level_Disp[0];
				Compare_Level_Ctrl[1]= Compare_Level_Disp[1];	
				Compare_Level_Ctrl[2]= Compare_Level_Disp[2];
			}
			else
			{
				sprintf((char *)Lcd_Disp_String, "       DATA ERROR");
				LCD_SetTextColor(Red);					
      	LCD_DisplayStringLine(Line0, Lcd_Disp_String);
				LCD_SetTextColor(Blue);					
			}
		}
	}
	
	if(unKey_Down == 2)
	{
		if((Interface_Num >> 4) == 0x1)
		{
			if(++Interface_Num == 0x13)
				Interface_Num = 0x10;
		}
	}
	
	if(unKey_Down == 3)//+
	{	
		if(Interface_Num == 0x10)
		{
			Compare_Level_Disp[0] += 5;
			if(Compare_Level_Disp[0] >= 100) Compare_Level_Disp[0] = 95;
		}
		
		if(Interface_Num == 0x11)
		{
			Compare_Level_Disp[1] += 5;
			if(Compare_Level_Disp[1] >= 100) Compare_Level_Disp[1] = 95;
		}		
		
		if(Interface_Num == 0x12)
		{
			Compare_Level_Disp[2] += 5;			
			if(Compare_Level_Disp[2] >= 100) Compare_Level_Disp[2] = 95;
		}		
	}
	
	if(unKey_Down == 4)//-
	{	
		if(Interface_Num == 0x10)
		{
			Compare_Level_Disp[0] -= 5;				
			if(Compare_Level_Disp[0] == 0) Compare_Level_Disp[0] = 5;
		}
		
		if(Interface_Num == 0x11)
		{
			Compare_Level_Disp[1] -= 5;					
			if(Compare_Level_Disp[1] == 0) Compare_Level_Disp[1] = 5;
		}		
		
		if(Interface_Num == 0x12)
		{
				Compare_Level_Disp[2] -= 5;		
			if(Compare_Level_Disp[2] == 0) Compare_Level_Disp[2] = 5;
		}			
	}

LED扫描子函数

a.逻辑框图

b.程序源码

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

	
	if(Level_Change_Flag == 1)
	{
		if(Buling_Times--)
			ucLed ^= 0x02;
		if(Buling_Times == 0)
		{
			Level_Change_Flag = 0;
			Buling_Times = 10;
			ucLed = 0;
		}
	}
	
	
	if(Uart_Get_Data == 1)
	{
		if(Buling_Times_Uart--)
			ucLed ^= 0x04;
		if(Buling_Times_Uart == 0)
		{
			Uart_Get_Data = 0;
			Buling_Times_Uart = 10;
			ucLed = 0;
		}
	}	
	
	LED_Disp(ucLed);
}

数据收集子函数

a.逻辑框图

b.程序源码

void Data_Collect_Proc(void)
{
	if((uwTick -  uwTick_Data_Set_Point)<1000)	return;//减速函数
		uwTick_Data_Set_Point = uwTick;

	//中值滤波处理
	for( AD_Ctrl_Num = 0;AD_Ctrl_Num <= 9; AD_Ctrl_Num++)
	{
//		SUM_AD_R37 += ((((float)getADC2())/4096)*3.3);	
			SUM_AD_R37 += ((float)getADC2());	
	}	
	SUM_AD_R37 /= 4096;
	SUM_AD_R37 *= 3.3;
	AVE_AD_R37 = SUM_AD_R37/10;
	SUM_AD_R37 = 0;
	
//	AVE_AD_R37 = ((((float)getADC2())/4096)*3.3);
	Height = (uint8_t)(AVE_AD_R37*30.3);
	
	Level_Old = Level;
	
	if(Height <= Compare_Level_Ctrl[0])
		Level = 0;
	if((Height <= Compare_Level_Ctrl[1])&&(Height > Compare_Level_Ctrl[0]))
		Level = 1;	
	if((Height <= Compare_Level_Ctrl[2])&&(Height > Compare_Level_Ctrl[1]))
		Level = 2;		
	if(Height > Compare_Level_Ctrl[2])
		Level = 3;		
	
	
	if(Level > Level_Old)
	{
			sprintf(str, "A:H%3d+L%1d+U\r\n",(unsigned int)Height,(unsigned int)Level);
	  	HAL_UART_Transmit(&huart1,(unsigned char *)str, strlen(str), 50);	
			Level_Change_Flag = 1;
	}
	else if(Level < Level_Old)
	{
			sprintf(str, "A:H%3d+L%1d+D\r\n",(unsigned int)Height,(unsigned int)Level);
	  	HAL_UART_Transmit(&huart1,(unsigned char *)str, strlen(str), 50);		
			Level_Change_Flag = 1;
	}	
	ucLed ^= 0x1;//让LD1翻滚变化	
}
LCD显示子函数

a.逻辑框图

b.程序源码

void Lcd_Proc(void)
{
	if((uwTick -  uwTick_Lcd_Set_Point)<100)	return;//减速函数
		uwTick_Lcd_Set_Point = uwTick;
		if(Interface_Num == 0x00)
		{
				LCD_SetBackColor(White);		
			
				sprintf((char *)Lcd_Disp_String, "    Liquid Level");
      	LCD_DisplayStringLine(Line1, Lcd_Disp_String);
			
				sprintf((char *)Lcd_Disp_String, "  Height:%3dcm",(unsigned int)Height);
				LCD_DisplayStringLine(Line3, Lcd_Disp_String);	
		
				sprintf((char *)Lcd_Disp_String, "  ADC:%4.2fV",AVE_AD_R37);
				LCD_DisplayStringLine(Line5, Lcd_Disp_String);		

				sprintf((char *)Lcd_Disp_String, "  Level:%1d",Level);
				LCD_DisplayStringLine(Line7, Lcd_Disp_String);				
		}
		else if((Interface_Num>>4) == 0x1)
		{
				sprintf((char *)Lcd_Disp_String, "    Parameter Setup");
			  LCD_SetBackColor(White);				
      	LCD_DisplayStringLine(Line1, Lcd_Disp_String);		
		
				sprintf((char *)Lcd_Disp_String, "  Threshold 1: %2dcm  ",(unsigned int)Compare_Level_Disp[0]);
				if(Interface_Num == 0x10)
					  LCD_SetBackColor(Yellow);
				else 
					  LCD_SetBackColor(White);					
				LCD_DisplayStringLine(Line3, Lcd_Disp_String);		
			
				sprintf((char *)Lcd_Disp_String, "  Threshold 2: %2dcm  ",(unsigned int)Compare_Level_Disp[1]);
				if(Interface_Num == 0x11)
					  LCD_SetBackColor(Yellow);
				else 
					  LCD_SetBackColor(White);					
				LCD_DisplayStringLine(Line5, Lcd_Disp_String);
			
				sprintf((char *)Lcd_Disp_String, "  Threshold 3: %2dcm  ",(unsigned int)Compare_Level_Disp[2]);
				if(Interface_Num == 0x12)
					  LCD_SetBackColor(Yellow);
				else 
					  LCD_SetBackColor(White);					
				LCD_DisplayStringLine(Line7, Lcd_Disp_String);		
		}

串口扫描子函数

a. 程序源码

void Usart_Proc(void)
{
	if((uwTick -  uwTick_Usart_Set_Point)<1000)	return;//减速函数
	uwTick_Usart_Set_Point = uwTick;
}

串口接收中断回调函数

a.逻辑框图

b.程序源码

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(rx_buffer == 'C')
	{
		Uart_Get_Data = 1;
		sprintf(str, "C:H%3d+L%1d\r\n",(unsigned int)Height,(unsigned int)Level);
		HAL_UART_Transmit(&huart1,(unsigned char *)str, strlen(str), 50);		
	}
	else if(rx_buffer == 'S')
	{
	   Uart_Get_Data = 1;
		sprintf(str, "S:TL%2d+TM%2d+TH%2d\r\n",(unsigned int)Compare_Level_Ctrl[0],(unsigned int)Compare_Level_Ctrl[1],(unsigned int)Compare_Level_Ctrl[2]);
		HAL_UART_Transmit(&huart1,(unsigned char *)str, strlen(str), 50);			
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)(&rx_buffer), 1);	
}

(2)BSP

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


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

相关文章:

  • ubuntu 24.04如何分配内存
  • 前端知识汇总(持续更新)
  • Flask-SQLAlchemy:在Flask应用中优雅地操作数据库
  • 如何利用多线程提高计算密集型任务的性能
  • 计算机网络实验5——静态路由的相关配置
  • 等保测评:如何进行安全的远程访问控制
  • ubuntu 安装neo4j
  • Electrodoc 5.2 专业电工工具集合,支持多种计算器和资料查询!
  • Golang | Leetcode Golang题解之第438题找到字符串中所有字母异位词
  • vue2与vue3知识点
  • 尾矿库安全监测系统:守护矿山安全的关键技术
  • 蛋白质结构中模型的提取
  • CSS 效果:实现动态展示双箭头
  • Android Button “No speakable text present” 问题解决
  • CUDA Dynamic Parallelism测试
  • Django-form表单
  • 【JAVA高级】如何使用Redis加锁和解锁(二)做分布式锁案例(防误删锁)
  • https访问报错:net::ERR_CERT_DATE_INVALLD
  • 【Simulink仿真】两级式三相光伏并网发电系统
  • Linux启动mysql报错
  • 【QT Quick】C++交互:QML对象操作
  • Linux应急响应技巧整理
  • 如何确定光纤用几芯 用光纤与网线区别在哪里
  • TensorRT-LLM高级用法
  • 五子棋双人对战项目(1)——WebSocket介绍
  • ubuntu 开启root
  • 太速科技-FMCJ457-基于JESD204B的2路2Gsps AD 2路2Gsps DA FMC子卡
  • LED驱动电路
  • SQL | 查询带有单引号的异常数据和replace与insert插入的区别
  • YOLO11震撼发布!