第七届 蓝桥杯 嵌入式设计与开发项目 省赛

赛题

请添加图片描述

部分程序

主函数

  /* USER CODE BEGIN 2 */
	EEPROM_init();	
	LED_init();
	KEY_init();
	LCD_Init();
	USER_DATA_init();		//数据初始化
	TASK_TIMES_init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		KEY_function();
		ADC_function();
		UART_function();
		LED_function();
		LCD_function();
  }
  /* USER CODE END 3 */

按键功能函数、


u8 KEY_SCAN(void)
{
	u8 val,key;
	static u8 com;
	
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET) 			val=1;
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET) val=2;
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET) val=3;
	else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET) val=4;
	else  																											val=0;
	
	key=val&(val^com);
	com=val;
	
	return key;
}

void KEY_function(void)
{
	u8 key;
	
	if(get_time_task(TASK_TIMES.KEY_TIME)==0)
	{
		TASK_TIMES.KEY_TIME=get_time()+KEY_time;
		
		key=KEY_SCAN();
		
		if(key==1)	//切换界面
		{
			if(!LCD_display)	//数据显示界面	
			{			
				Threshold_temporary[0]=Threshold[0];	//获取阈值数据
				Threshold_temporary[1]=Threshold[1];
				Threshold_temporary[2]=Threshold[2];
				flag_set=0;			//每次进入设置阈值界面时,从阈值1开始
			
				sprintf((char *)LCD_Line2_buf,"   Parameter Setup  ");
				sprintf((char *)LCD_Line3_buf," Threshold 1: %2dcm  ",Threshold_temporary[0]);
				sprintf((char *)LCD_Line4_buf," Threshold 2: %2dcm  ",Threshold_temporary[1]);
				sprintf((char *)LCD_Line5_buf," Threshold 3: %2dcm  ",Threshold_temporary[2]);	
 			
			}
			else							//阈值设置界面
			{
				Threshold[0]=Threshold_temporary[0];	//保存阈值数据
				Threshold[1]=Threshold_temporary[1];
				Threshold[2]=Threshold_temporary[2];		
				//保存到E2PROM
				EEPROM[0]=123;
				EEPROM[1]=Threshold[0];
				EEPROM[2]=Threshold[1];
				EEPROM[3]=Threshold[2];
				EEPROM_write(0,EEPROM,4);
				
				sprintf((char *)LCD_Line2_buf,"    Liquid Level    ");
				sprintf((char *)LCD_Line3_buf," Height: 50cm       ");
				sprintf((char *)LCD_Line4_buf," ADC   : 1.65V      ");
				sprintf((char *)LCD_Line5_buf," Level : 1          ");					
			}
			LCD_DisplayStringLine(Line2,LCD_Line2_buf);
			LCD_display=!LCD_display;
		}
		else if(key==2)	//切换选择
		{
			if(LCD_display)	//仅在阈值设置界面下有效
			{
				if(++flag_set==3) {flag_set=0;}	//切换被选中的阈值
			}
		}
		else if(key==3)	//加
		{
			if(LCD_display)	//仅在阈值设置界面下有效
			{
				if(flag_set==2) {if(Threshold_temporary[flag_set]!=95) {Threshold_temporary[flag_set]+=5;}}	//最大阈值95
				else
				{
					if(Threshold_temporary[flag_set+1]-Threshold_temporary[flag_set]>5)	//阈值不能大于等于上级阈值
					{ Threshold_temporary[flag_set]+=5; }
				}
			}
		}
		else if(key==4)	//减
		{
			if(LCD_display)	//仅在阈值设置界面下有效
			{
				if(flag_set==0) {if(Threshold_temporary[flag_set]!=5) {Threshold_temporary[flag_set]-=5;}}	//最小阈值5
				else
				{
					if(Threshold_temporary[flag_set]-Threshold_temporary[flag_set-1]>5)	//阈值不能小于等于下级阈值
					{ Threshold_temporary[flag_set]-=5; }
				}		
			}	
		}			
	}
}

ADC功能函数


void ADC_function(void)
{
	u8 a;
	u32 data=0;
	if(get_time_task(TASK_TIMES.ADC_TIME)==0)
	{
		TASK_TIMES.ADC_TIME=get_time()+ADC_time;
		HAL_ADC_Stop_DMA(&hadc2);
		for(a=0;a<50;a++)
		{
			data+=ADC_buf[a];
		}
		HAL_ADC_Start_DMA(&hadc2,(u32 *)&ADC_buf,50);	//使能ADC DMA转换
		data/=50;	//ADC近50次均值
		
		ADC=data*330/4095;	//传感器输出 放大100倍,保留2位小数
		Height=ADC/3.3;	//液位高度   K=100/3.3 Height=Vr37*K=((ADC/100)*100)/3.3  四舍五入
		
		if(Height<=Threshold[0]) 			Level=0;
		else if(Height<=Threshold[1]) Level=1;
		else if(Height<=Threshold[2]) Level=2;
		else                          Level=3;
		
		if((flag_Level&0X03)!=Level)	//液位等级改变
		{		
			if((flag_Level&0X03)>Level)	//下降
			{ sprintf((char *)UART1_TX_buf,"A:H%d+L%d+D\r\n ",Height,Level); }
			else	//上升
			{ sprintf((char *)UART1_TX_buf,"A:H%d+L%d+U\r\n ",Height,Level); }
			
			HAL_UART_Transmit_DMA(&huart1,UART1_TX_buf,14);
			flag_Level=(Level&0x03);		//保存本次液位等级
			flag_Level|=0x80;						//液位等级改变标志位置1
		}
	}
}

串口功能函数


void UART_function(void)
{
	u8 len;
	if(flag_UART1_over)
	{
		flag_UART1_over=0;
		if(UART1_RX_num==1)	//判断是的正确指令长度
		{
			flag_uart=1;
			if(UART1_RX_buf[0]=='C')	//返回当前液位高度和液位等级
			{		
				sprintf((char *)UART1_TX_buf,"C:H%d+L%d\r\n  ",Height,Level);
				len=12;
			}
			else if(UART1_RX_buf[0]=='S')	//返回当前设定三个阈值
			{
				sprintf((char *)UART1_TX_buf,"S:TL%d+TM%d+TH%d\r\n  ",Threshold[0],Threshold[1],Threshold[2]);
				len=18;			
			}
			else 		flag_uart=0;
			if(flag_uart) HAL_UART_Transmit_DMA(&huart1,UART1_TX_buf,len);
		}
		
		HAL_UART_Receive_DMA(&huart1,UART1_RX_buf,UART1_TX_LEN);
	}
}

LED功能函数


void LED_function(void)
{
	static u8 LED_state_last=0XFF;
	static u8 time_num=0;
	static u8 flag_LD2=0;	//bit 7 LD2闪烁标志位 6:4 保留 3:0 闪烁次数
	static u8 flag_LD3=0;	//bit 7 LD2闪烁标志位 6:4 保留 3:0 闪烁次数	
	if(get_time_task(TASK_TIMES.LED_TIME)==0)
	{
		TASK_TIMES.LED_TIME=get_time()+LED_time;
			
		if(++time_num%5==0) {LED_state^=(1<<0);}	//运行状态指示灯,1秒间隔闪烁
		
		if(flag_Level&0x80)	//液位等级发生改变,LD2以0.2秒间隔闪烁5次
		{
			flag_Level&=0X7F;	//液位等级发生改变标志位清零
			flag_LD2&=0xF0;		//闪烁次数清零
			flag_LD2|=0x80;		//闪烁标志位置1
		}
		
		if(flag_uart)
		{
			flag_uart=0;
			flag_LD3&=0xF0;		//闪烁次数清零
			flag_LD3|=0x80;		//闪烁标志位置1			
		}
		
		if(flag_LD2&0x80)
		{
			flag_LD2++;	//闪烁次数加1
			if((flag_LD2&0x0F)==10) {flag_LD2&=0x70;}
			LED_state^=(1<<1);
		}
		else {LED_state|=0x02;}
		
		if(flag_LD3&0x80)
		{
			flag_LD3++;	//闪烁次数加1
			if((flag_LD3&0x0F)==10) {flag_LD3&=0x70;}
			LED_state^=(1<<2);
		}		
		else {LED_state|=0x04;}
		
		if(LED_state_last!=LED_state)	//LED状态,发生改变
		{
			LED_state_last=LED_state;
			LED_write(LED_state);
		}		
	}	
}


LCD功能函数

void LCD_function(void)
{
	if(get_time_task(TASK_TIMES.LCD_TIME)==0)
	{
		TASK_TIMES.LCD_TIME=get_time()+LCD_time;
 	
		if(!LCD_display)	//数据显示界面
		{
			LCD_Line3_buf[9]=Height/10+48;LCD_Line3_buf[10]=Height%10+48;
			LCD_Line4_buf[9]=ADC/100+48;LCD_Line4_buf[11]=ADC/10%10+48;LCD_Line4_buf[12]=ADC%10+48;
			LCD_Line5_buf[9]=Level+48;
		}
		else							//阈值设置界面
		{	
			LCD_Line3_buf[14]=Threshold_temporary[0]/10+48;LCD_Line3_buf[15]=Threshold_temporary[0]%10+48;
			LCD_Line4_buf[14]=Threshold_temporary[1]/10+48;LCD_Line4_buf[15]=Threshold_temporary[1]%10+48;
			LCD_Line5_buf[14]=Threshold_temporary[2]/10+48;LCD_Line5_buf[15]=Threshold_temporary[2]%10+48;
		}
		//阈值设置界面下,被选中的高亮
		if(LCD_display&&(flag_set==0)) {LCD_SetTextColor(Green);LCD_DisplayStringLine(Line3,LCD_Line3_buf);LCD_SetTextColor(White);}	
		else 													 {LCD_DisplayStringLine(Line3,LCD_Line3_buf);}
		if(LCD_display&&(flag_set==1)) {LCD_SetTextColor(Green);LCD_DisplayStringLine(Line4,LCD_Line4_buf);LCD_SetTextColor(White);}
		else 													 {LCD_DisplayStringLine(Line4,LCD_Line4_buf);}
		if(LCD_display&&(flag_set==2)) {LCD_SetTextColor(Green);LCD_DisplayStringLine(Line5,LCD_Line5_buf);LCD_SetTextColor(White);}
		else 													 {LCD_DisplayStringLine(Line5,LCD_Line5_buf);}		
	}
}

完整程序下载

下载链接:
链接:https://pan.baidu.com/s/1LMECSy3GuABduu42YUJdSQ
提取码:qy2o

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值