本文主要是介绍第十届蓝桥杯嵌入式省赛程序设计题(HAL库版),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
蓝桥杯嵌入式(HAL库版)省赛系列文章
第六届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第九届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十一届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十三届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十届蓝桥杯嵌入式省赛程序设计题(HAL库版)
- 蓝桥杯嵌入式(HAL库版)省赛系列文章
- 前言
- 一、赛题要求
- 1.硬件框图
- 2.功能描述
- 二、配置工程
- 1.配置流程
- 1.1选择芯片
- 1.2配置引脚
- 1.3配置时钟
- 1.4建立工程
- 三、软件实现(模块化编程)
- 1. 按键扫描
- 2. 按键控制电压参数改变(配合扫描函数使用)
- 3. 按键控制指示灯序号改变(配合扫描函数使用)
- 4. 读取ADC数值(启动->读取->返回)
- 5. 上限报警
- 6. 下限报警
- 7. 正常工作情况
- 8. 数据显示界面
- 9. 参数设置界面
- 10. 界面切换
- 总结
前言
报名参加蓝桥杯嵌入式组别,通过做往年省赛例题的方式进行能力整体提升,需要的小伙伴可以简单看一下哈,写的不好,还请大家多多包涵,欢迎大佬指出问题!
需要其他届赛题的朋友可以从顶部链接直达喔!
闲话少说,进入正题!
一、赛题要求
1.硬件框图
2.功能描述
初始状态:
- 默认输出提醒指示灯。
超过上限提醒指示灯:LD1
低于下限提醒指示灯:LD2 - 默认电压阈值参数。
电压的上限值:2.4V
电压的下限值:1.2V
根据上述任务要求,使用STM32CubeMX生成Keil文件进行程序编写。
二、配置工程
1.配置流程
使用STM32CubeMX的流程可以概括为四个步骤,分别为:选择芯片、配置引脚、配置时钟、建立工程
1.1选择芯片
蓝桥杯嵌入式平台所使用的芯片为STM32G431RBTx,故我们进行搜索并建立工程。
1.2配置引脚
LED灯由PC8-PC15控制,低电平点亮,由PD2引脚控制锁存,低电平变为高电平开锁,高电平变为低电平上锁,设置引脚模式为输出模式。
开发板上共配备了4个按键,分别连接在PB0,PB1,PB2,PA0引脚上,设置引脚模式为输入模式。
由于题目中设计电压测量,故需要配置ADC,参考原理图可知,R37与PB15相连,PB15为ADC2_IN15
1.3配置时钟
时钟配置这里考虑到芯片最高频率为170MHz,所以我直接选择将HCLK一栏设置为最大值170MHz
1.4建立工程
一定要将Toolchain/IDE更改为MDK-ARM,版本号根据大家的实际情况确定即可
这里我勾选的是只将必要的库文件粘贴过来,可以减小工程建立的大小。
至此,建立工程阶段结束,可以开始写代码啦!
三、软件实现(模块化编程)
1. 按键扫描
uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN)
{if(HAL_GPIO_ReadPin(GPIOx,GPIO_PIN) == RESET){while(HAL_GPIO_ReadPin(GPIOx,GPIO_PIN) == RESET);return 2;}elsereturn 1;
}
2. 按键控制电压参数改变(配合扫描函数使用)
void Key_Volt_Change(double *Volt)
{if (Key_Scan(B3_Plus_GPIO_Port,B3_Plus_Pin) == 2){*Volt += 0.3;if(*Volt >= 3.3)*Volt = 3.3;}if(Key_Scan(B4_Minus_GPIO_Port,B4_Minus_Pin) == 2){*Volt -= 0.3;if(*Volt <= 0)*Volt = 0;}
}
3. 按键控制指示灯序号改变(配合扫描函数使用)
void Key_LD_Change(uint16_t *LD)
{if (Key_Scan(B3_Plus_GPIO_Port,B3_Plus_Pin) == 2){*LD += 1;if(*LD >= 8)*LD = 8;}if(Key_Scan(B4_Minus_GPIO_Port,B4_Minus_Pin) == 2){*LD -= 1;if(*LD <= 1)*LD = 1;}
}
4. 读取ADC数值(启动->读取->返回)
double Get_ADC(void)
{HAL_ADC_Start(&hadc2); //启动ADC2adc = HAL_ADC_GetValue(&hadc2); //定义变量adc,用于获取ADC2的值return (adc*3.3/4096); //函数返回值为adc*3.3/4096,3.3V为最大电压值,4096为12位的LSB
}
5. 上限报警
void LD_Upper_Warning(uint8_t Upper)
{GPIOC -> ODR = ~(0x0001 << (Upper + 7));HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);HAL_Delay(200);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);
}
6. 下限报警
void LD_Lower_Warning(uint8_t Lower)
{GPIOC -> ODR = ~(0x0001 << (Lower + 7));HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);HAL_Delay(200);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);
}
7. 正常工作情况
void LD_Normal()
{HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);
}
8. 数据显示界面
if(KEYB1_FLAG == 0){LCD_SetBackColor(Blue);LCD_SetTextColor(White);LCD_DisplayStringLine(Line0,(uint8_t*)" ");LCD_DisplayStringLine(Line1,(uint8_t*)" Main ");LCD_DisplayStringLine(Line2,(uint8_t*)" ");LCD_DisplayStringLine(Line3,(uint8_t*)" ");LCD_DisplayStringLine(Line4,(uint8_t*)" Volt: ");LCD_DisplayStringLine(Line5,(uint8_t*)" ");LCD_DisplayStringLine(Line6,(uint8_t*)" ");LCD_DisplayStringLine(Line7,(uint8_t*)" ");LCD_DisplayStringLine(Line8,(uint8_t*)" ");LCD_DisplayStringLine(Line9,(uint8_t*)" ");V = Get_ADC();sprintf(ADC_TEXT," Volt:%.2fV ",V);LCD_DisplayStringLine(Line4,(uint8_t*)ADC_TEXT);if( V >= Max_Volt){LCD_DisplayStringLine(Line6,(uint8_t*)" Status:Upper ");LD_Upper_Warning();}if( V < Max_Volt && V > Min_Volt){LCD_DisplayStringLine(Line6,(uint8_t*)" Status:Normal ");LD_Normal();}if( V <= Min_Volt){LCD_DisplayStringLine(Line6,(uint8_t*)" Status:Lower ");LD_Lower_Warning();}if(Key_Scan(B1_Setting_GPIO_Port,B1_Setting_Pin) ==2){KEYB1_FLAG += 1;}}
9. 参数设置界面
else{if(Key_Scan(B2_Selection_GPIO_Port,B2_Selection_Pin) == 2)KEYB2_FLAG += 1;if(KEYB2_FLAG > 4)KEYB2_FLAG = 0;LCD_SetBackColor(White);LCD_SetTextColor(Blue);LCD_DisplayStringLine(Line0,(uint8_t*)" ");LCD_DisplayStringLine(Line1,(uint8_t*)" Setting ");LCD_DisplayStringLine(Line2,(uint8_t*)" ");LCD_DisplayStringLine(Line5,(uint8_t*)" ");LCD_DisplayStringLine(Line8,(uint8_t*)" ");LCD_DisplayStringLine(Line9,(uint8_t*)" ");sprintf(LCD_TEXT," Max Volt:%.2fV ",Max_Volt);if(KEYB2_FLAG == 1){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line3,(uint8_t*)LCD_TEXT);LCD_SetBackColor(White);Key_Volt_Change(&Max_Volt);}elseLCD_DisplayStringLine(Line3,(uint8_t*)LCD_TEXT);sprintf(LCD_TEXT," Min Volt:%.2fV ",Min_Volt);if(KEYB2_FLAG == 2){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line4,(uint8_t*)LCD_TEXT);LCD_SetBackColor(White);Key_Volt_Change(&Min_Volt);}elseLCD_DisplayStringLine(Line4,(uint8_t*)LCD_TEXT);sprintf(LD_TEXT," Upper:LD%d ",Upper);if(KEYB2_FLAG == 3){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line6,(uint8_t*)LD_TEXT);LCD_SetBackColor(White);Key_LD_Change(&Upper);}elseLCD_DisplayStringLine(Line6,(uint8_t*)LD_TEXT);sprintf(LD_TEXT," Lower:LD%d ",Lower);if(KEYB2_FLAG == 4){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line7,(uint8_t*)LD_TEXT);LCD_SetBackColor(White);Key_LD_Change(&Lower);}elseLCD_DisplayStringLine(Line7,(uint8_t*)LD_TEXT);if(Key_Scan(B1_Setting_GPIO_Port,B1_Setting_Pin) ==2){KEYB1_FLAG += 1;}if(Upper == Lower){LCD_SetTextColor(Red);LCD_DisplayStringLine(Line5,(uint8_t*)" LD Conflicted! ");}elseLCD_DisplayStringLine(Line5,(uint8_t*)" ");}
10. 界面切换
if(KEYB1_FLAG >1)KEYB1_FLAG = 0;
总结
通过上述代码基本可以实现任务的全部要求,但存在频繁闪烁的问题,我也不是很清楚是因为硬件原因还是软件原因,还望各路大佬指出!
如果需要全部代码可以直接私信我哈,文章已经很长啦,就不放全部代码啦!希望与各位小伙伴一同进步呀!
这篇关于第十届蓝桥杯嵌入式省赛程序设计题(HAL库版)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!