摘要:本文为作者对第六届蓝桥杯嵌入式设计与开发项目——程序设计试题的解析。本文包括“题目要求”、“程序设计”、“效果展示”3个部分。供复盘使用。若发现错误之处,请不吝赐教。
链接:蓝桥杯嵌入式方向备赛记录(STM32G431)为作者备赛蓝桥杯嵌入式过程中,整理的学习总结。包括各模块使用要点、各模块程序等,基本搭建好工程框架,给出了各模块处理程序。
写在前面:第七届省赛真题和第十届后的题目风格差不多。
目录
一、题目要求
二、程序设计
(一)思路分析
先空着,后续有空再写。读者可参考博主博客内其他届文章,大同小异。
(二)程序设计
1、按键
void KEY_Proc(void)
{
if(key[0].ucJudgeKeyState == 1)
{
if(ucState==0)
{
ucState = 1;
}
else
{
//保存
if((usThre1 < usThre2) && (usThre2 < usThre3))
{
putTh[0] = usThre1;
putTh[1] = usThre2;
putTh[2] = usThre3;
MEM_Write(putTh,0,3);
ucState = 0;
}
else
{
printf("ERROR\r\n");
}
}
key[0].ucJudgeKeyState = 0;
}
if(key[1].ucJudgeKeyState == 1)
{
if(ucState==1)
{
if(++ucMode==4)
ucMode = 1;
}
key[1].ucJudgeKeyState = 0;
}
if(key[2].ucJudgeKeyState == 1)
{
if(ucState==1)
{
switch(ucMode)
{
case 1:
{
if(usThre1<95)
usThre1 += 5;
}
break;
case 2:
{
if(usThre2<95)
usThre2 += 5;
}
break;
case 3:
{
if(usThre3<95)
usThre3 += 5;
}
break;
default:break;
}
}
key[2].ucJudgeKeyState = 0;
}
if(key[3].ucJudgeKeyState == 1)
{
if(ucState==1)
{
switch(ucMode)
{
case 1:
{
if(usThre1>5)
usThre1 -= 5;
}
break;
case 2:
{
if(usThre2>5)
usThre2 -= 5;
}
break;
case 3:
{
if(usThre3>5)
usThre3 -= 5;
}
break;
default:break;
}
}
key[3].ucJudgeKeyState = 0;
}
Led_Disp(ucLed);
}
2、ADC
void ADC_Proc(void)
{
if( ucAdc < 1000)
return;
ucAdc = 0;
// if(!ucState && ucSec1 != ucSec) //1秒执行一次
// {
// ucSec1 = ucSec;
uint16_t adc2 ;
HAL_ADC_Start(&hadc2);
adc2 = HAL_ADC_GetValue(&hadc2);
VR37 = adc2*3.3/4096;
Height = VR37*100/3.3;
if(Height<=(usThre1/1.0))
{
ucLevel = 0;
}
else if((Height>(usThre1/1.0))&&(Height<=(usThre2/1.0)))
{
ucLevel =1;
}
else if((Height>(usThre2/1.0))&&(Height<=(usThre3/1.0)))
{
ucLevel =2;
}
else
ucLevel =3;
// }
if(ucLevel != ucLevel1) //等级变化
{
if(ucLevel > ucLevel1) //液位升高
printf("A:H%d+L%d+U\r\n",(int)Height,ucLevel);
else //液位降低
printf("A:H%d+L%d+D\r\n",(int)Height,ucLevel);
ucLevel1 = ucLevel; //把当前等级赋给
ucLD2_Flag = 1;
}
}
3、EEPROM
//保存阈值部分在按键处理函数中
//初始化及掉电不丢失部分
I2CInit();
MEM_Read(putTh,0,7);
HAL_Delay(100);
//上电后,要修改,就把这些随机值变一下
if((putTh[4]==0x76)&&(putTh[5]==0x7A)&&(putTh[6]==0x64))//设备不是第一次运行
{
usThre1 = putTh[0];
usThre2 = putTh[1];
usThre3 = putTh[2];
}
else//设备第一次运行
{
putTh[4]=0x76;
putTh[5]=0x7A;
putTh[6]=0x64;//自定义的数据
putTh[0]=30;
putTh[1]=50;
putTh[2]=70;
MEM_Write(putTh,0,7);
}
4、LED
void LED_Proc(void)
{
if(usms==1000)//LD1运行状态指示灯,以1秒为间隔闪烁
{
ucLed ^= 1 ;
usms=0;
}
if(ucLD2_Flag)//LD2液位变化等级指示灯,液位等级发生变化时,LD2以0.2秒为间隔闪烁5次
{
if(usTwickms==200)
{
if(ucNum--)
{
ucLed ^= 2;
}
else
{
ucLD2_Flag = 0;
ucNum = 10;
}
usTwickms = 0;
}
}
if(ucLD3_Flag)//LD3 通信状态指示灯,系统接收到查询指令时,LD3 以 0.2s 为间隔闪烁 5 次
{
if(usTwickms==200)
{
if(ucNum--)
{
ucLed ^= 4;
}
else
{
ucLD3_Flag = 0;
ucNum = 10;
}
usTwickms = 0;
}
}
Led_Disp(ucLed);
}
5、串口
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if( huart->Instance == USART1 )
{
RxBuffer[Rxindex++] = RxDate;
HAL_UART_Receive_IT(&huart1,&RxDate,1);
}
}
uint8_t isRxlegal()
{
unsigned char i;
if(Rxindex==0)
return 0;
if(Rxindex!=1)
return 2;
if((RxBuffer[0]=='C')||(RxBuffer[0]=='S'))
return 1;
else
return 2;
}
void UART_Proc(void)
{
if(ucUar < 100)
return;
ucUar = 0;
if(isRxlegal()==1)
{
ucLD3_Flag = 1;
if(RxBuffer[0]=='C')
printf("C:H%d+L%d\r\n",(int)Height,ucLevel);
if(RxBuffer[0]=='S')
printf("S:TL%d+TM%d+TH%d\r\n",usThre1,usThre2,usThre3);
}
//memset(RxBuffer,0,sizeof(RxBuffer));
Rxindex = 0;
}
6、SYSTIC
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
extern uint16_t usTms;
extern uint8_t ucSec;
extern uint16_t ucAdc;
extern uint8_t ucLcd;
extern uint8_t ucUar;
extern uint16_t usms;
extern uint16_t usTwickms;
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
if (++usTms == 1000)
{
usTms = 0;
ucSec++;
}
if(usms<1000)
{
usms++;
}
if(usTwickms<200)
{
usTwickms++;
}
ucAdc++;
ucLcd++;
ucUar++;
/* USER CODE END SysTick_IRQn 1 */
}
7、LCD
void LCD_Proc(void)
{
if(ucLcd < 100)
return;
ucLcd = 0;
switch(ucState)
{
case 0:
{
LCD_DisplayStringLine(Line0,(unsigned char*)" ");
LCD_DisplayStringLine(Line1,(unsigned char*)" Liquid Level ");
LCD_DisplayStringLine(Line2,(unsigned char*)" ");
sprintf(buf1," Height:%dcm ",(int)Height);
LCD_DisplayStringLine(Line3,(unsigned char*)buf1);
sprintf(buf1," ADC :%.2fV ",VR37);
LCD_DisplayStringLine(Line4,(unsigned char*)buf1);
sprintf(buf1," Level :%d ",ucLevel);
LCD_DisplayStringLine(Line5,(unsigned char*)buf1);
}
break;
case 1:
{
LCD_DisplayStringLine(Line0,(unsigned char*)" ");
LCD_DisplayStringLine(Line1,(unsigned char*)" Parameter Setup");
LCD_DisplayStringLine(Line2,(unsigned char*)" ");
if(ucMode == 1) LCD_SetBackColor(Red);
sprintf(buf1," Threshold1:%dcm ",usThre1);
LCD_DisplayStringLine(Line3,(unsigned char*)buf1);
LCD_SetBackColor(Blue);
if(ucMode == 2) LCD_SetBackColor(Red);
sprintf(buf1," Threshold2:%dcm ",usThre2);
LCD_DisplayStringLine(Line4,(unsigned char*)buf1);
LCD_SetBackColor(Blue);
if(ucMode == 3) LCD_SetBackColor(Red);
sprintf(buf1," Threshold3:%dcm ",usThre3);
LCD_DisplayStringLine(Line5,(unsigned char*)buf1);
LCD_SetBackColor(Blue);
}
break;
default : break;
}
LCD_DisplayStringLine(Line6,(unsigned char*)" ");
LCD_DisplayStringLine(Line7,(unsigned char*)" ");
LCD_DisplayStringLine(Line8,(unsigned char*)" ");
LCD_DisplayStringLine(Line9,(unsigned char*)" ");
}
8、整合
uint8_t Rxindex;
uint8_t RxDate;
uint8_t RxBuffer[7];
uint8_t ucLed=0;
uint8_t ucState=0;
char buf1[30];
uint8_t ucMode=0;
float VR37;
float Height;
uint8_t ucLevel;//新的 等级变化
uint8_t ucLevel1;//旧的
uint8_t ucLD2_Flag;
uint8_t ucLD3_Flag;
uint16_t usThre1 = 30;
uint16_t usThre2 = 50;
uint16_t usThre3 = 70;
uint8_t putTh[8];
uint8_t ucSec1;
uint16_t usTms;
uint8_t ucSec;
uint16_t ucAdc;
uint8_t ucLcd;
uint8_t ucUar;
uint16_t usms;//LD1
uint16_t usTwickms;//LD2
uint8_t ucNum=10;
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC2_Init();
MX_TIM4_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim4);
HAL_UART_Receive_IT(&huart1,&RxDate,1);
LCD_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
I2CInit();
MEM_Read(putTh,0,7);
HAL_Delay(100);
//上电后,要修改,就把这些随机值变一下
if((putTh[4]==0x76)&&(putTh[5]==0x7A)&&(putTh[6]==0x64))//设备不是第一次运行
{
usThre1 = putTh[0];
usThre2 = putTh[1];
usThre3 = putTh[2];
}
else//设备第一次运行
{
putTh[4]=0x76;
putTh[5]=0x7A;
putTh[6]=0x64;//自定义的数据
putTh[0]=30;
putTh[1]=50;
putTh[2]=70;
MEM_Write(putTh,0,7);
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
ADC_Proc();
KEY_Proc();
LCD_Proc();
LED_Proc();
UART_Proc();
}
/* USER CODE END 3 */
}
三、效果展示
后续有空再上传。