【蓝桥杯嵌入式·真题解析】第七届蓝桥杯嵌入式设计与开发项目——程序设计试题 “模拟液位检测警告系统”

本文详细解析了第六届蓝桥杯嵌入式设计与开发项目的程序设计,涉及按键、ADC、EEPROM、LED、串口通信、SYSTIC和LCD等功能,旨在帮助参赛者复盘并提升技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:本文为作者对第六届蓝桥杯嵌入式设计与开发项目——程序设计试题的解析。本文包括“题目要求”、“程序设计”、“效果展示”3个部分。供复盘使用。若发现错误之处,请不吝赐教。

链接:蓝桥杯嵌入式方向备赛记录(STM32G431)为作者备赛蓝桥杯嵌入式过程中,整理的学习总结。包括各模块使用要点、各模块程序等,基本搭建好工程框架,给出了各模块处理程序。

 写在前面:第七届省赛真题和第十届后的题目风格差不多。

目录

一、题目要求

二、程序设计

(一)思路分析

(二)程序设计

1、按键

2、ADC

3、EEPROM

4、LED

5、串口

6、SYSTIC

7、LCD

8、整合

三、效果展示

一、题目要求

二、程序设计

(一)思路分析

        先空着,后续有空再写。读者可参考博主博客内其他届文章,大同小异。

(二)程序设计

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 */
}

三、效果展示

后续有空再上传。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值