蓝桥杯嵌入式十届省赛

该文主要介绍了基于STM32的项目配置,包括RCC、SYS、按键、ADC、LCD和LED的配置。在代码编写部分,详细阐述了如何进行数据定义、显示功能、按键处理和LED指示灯功能的实现,同时展示了如何在主循环中更新ADC值、状态判断及显示结果。文章还提到了使用定时器进行LED闪烁控制,并强调了在编程过程中可能需要的修改和验证过程。
摘要由CSDN通过智能技术生成

链接:https://pan.baidu.com/s/1cHxmXBmJgmD1muW8rbWmgw?pwd=6666 
提取码:6666

目录

1.赛题

 2.分析及配置

2.1 RCC配置

 2.2 SYS配置

 2.3 按键配置

 2.4 ADC配置

2.5 LCD配置

 2.6 LED配置

3.编写代码及解释

数据定义

3.2显示功能的编写

3.3按键功能

3.4 LED 指示灯功能

3.5初始状态说明

while主循环

结果展示

结尾


1.赛题

 

 2.分析及配置

直接观察用到的模块和引脚即可。

ADC、按键、LED、LCD。

然后配置。

2.1 RCC配置

 

 2.2 SYS配置

 2.3 按键配置

 

 2.4 ADC配置

2.5 LCD配置

用到的引脚配置为Out_put

 2.6 LED配置

LED和LCD公用引脚,只需配置PD2即可,配置为Out_put

默认LED关闭。

配置完毕生成代码。 

3.编写代码及解释

代码的编写不是一次成型的写着写着要修改很正常,我们按顺序写就行。

LCD和ADC直接移植官方给的历程即可。

数据定义

typedef struct
{
	bool Switch;//界面切换标志位
	unsigned char Status;//状态标志位
	double ADC;//ADC的数值
	double Max_Volt;//电压的上限值
	double Min_Volt;//电压的下限值
	unsigned char Upper;//电压超过上限的提醒指示灯
	unsigned char Lower;//电压低于下限的提醒指示灯
	unsigned char Choose;//设置里面的高亮
	unsigned int UpperCount;//LED上限中断计数
	unsigned int LowerCount;//LED下限中断计数
}Data_TypeDef;
Data_TypeDef Data;


typedef struct
{
	unsigned int Value;//按键的值(0或1)
	bool Flag;//是否按下的标志
	unsigned char State;//按键检测步骤
}Key_TypeDef;
Key_TypeDef B[4];//四个按键

3.2显示功能的编写

用到什么定义什么数据,这里只进行显示,数据的更改放到其他位置。 

写道后面可能会修改不过没事一个模块一个模块的写就好。

void Show(void)
{
	char arr[30];
	if(Data.Switch)//参数配置界面
	{
		/* 界面名字 */
		LCD_DisplayStringLine(Line1, (uint8_t *)"          Setting      ");
		
		/* Max Volt显示 */
		sprintf(arr,"  Max Volt: %.1fV      ",Data.Max_Volt);
		if(Data.Choose == 0)//如果选择的是Max Volt则他高亮
			LCD_SetBackColor(Blue);
		LCD_DisplayStringLine(Line2, (uint8_t *)arr);
		LCD_SetBackColor(Black);//高亮完毕之后恢复黑色
		
		/* Min Volt显示 */
		sprintf(arr,"  Min Volt: %.1fV      ",Data.Min_Volt);
		if(Data.Choose == 1)//如果选择的是Min Volt则他高亮
			LCD_SetBackColor(Blue);
		LCD_DisplayStringLine(Line4, (uint8_t *)arr);
		LCD_SetBackColor(Black);//高亮完毕之后恢复黑色
		
		/* Upper显示 */
		sprintf(arr,"  Upper: LD%d      ",Data.Upper);
		if(Data.Choose == 2)//如果选择的是Upper则他高亮
			LCD_SetBackColor(Blue);
		LCD_DisplayStringLine(Line6, (uint8_t *)arr);
		LCD_SetBackColor(Black);//高亮完毕之后恢复黑色
		
		/* Lower显示 */
		sprintf(arr,"  Lower: LD%d      ",Data.Lower);
		if(Data.Choose == 3)//如果选择的是Lower则他高亮
			LCD_SetBackColor(Blue);
		LCD_DisplayStringLine(Line8, (uint8_t *)arr);
		LCD_SetBackColor(Black);//高亮完毕之后恢复黑色
	}
	else//数据显示界面 
	{
		LCD_DisplayStringLine(Line1, (uint8_t *)"          Main      ");
		sprintf(arr,"  Volt: %.2fV      ",Data.ADC);
		LCD_DisplayStringLine(Line4, (uint8_t *)arr);
		if(Data.Status == 0)
			LCD_DisplayStringLine(Line6, (uint8_t *)"  Status: Upper");
		else if(Data.Status == 1)
			LCD_DisplayStringLine(Line6, (uint8_t *)"  Status: Lower");
		else if(Data.Status == 2)
			LCD_DisplayStringLine(Line6, (uint8_t *)"  Status: Normal");
	}
}

3.3按键功能

这里只有单机。

回调函数的编写,10毫秒检测一次,按键也消抖了。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM4)
	{
		B[0].Value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		B[1].Value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		B[2].Value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		B[3].Value = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		for(int i=0;i<4;i++)
		{
			switch(B[i].State)
			{
				case 0:	if(B[i].Value == 0)
							B[i].State = 1;
				break;
				case 1:	if(B[i].Value == 0)
						{
							B[i].State = 2;
							B[i].Flag = 1;
						}
						else
							B[i].State = 0;
				break;
				case 2:	if(B[i].Value == 1)
							B[i].State = 0;
				break;
				default:break;
			}
		}
		LED();
	}
}
void Key_Handle(void)
{
	if(B[0].Flag==1)
	{
		LCD_Clear(Black);
		Data.Switch = 1 - Data.Switch;
		B[0].Flag = 0;
	}
	if(B[1].Flag==1)
	{
		if(Data.Switch)
		{
			Data.Choose++;
			if(Data.Choose>=4)
				Data.Choose = 0;
		}
		B[1].Flag = 0;
	}
	if(B[2].Flag==1)
	{
		if(Data.Switch)//只在该界面的按键有效
		{
			if(Data.Choose == 0)
			{
				Data.Max_Volt += 0.3;
				if(Data.Max_Volt>3.3)//数值保护
					Data.Max_Volt = 3.3;
			}
			else if(Data.Choose == 1)
			{
				Data.Min_Volt += 0.3;
				if(Data.Min_Volt>Data.Max_Volt)//不能大于最多相等
					Data.Min_Volt = Data.Max_Volt;
			}
			else if(Data.Choose == 2)
			{
				Data.Upper++;
				//加完之后相等就再加一次
				if(Data.Upper == Data.Lower)
				{
					Data.Upper++;
					//再加一次超出数值就还原到初值
					if(Data.Upper>=9)
						Data.Upper -= 2;
				}
				//防止超出数值
				if(Data.Upper>=9)
					Data.Upper = 8;
			}
			else if(Data.Choose == 3)
			{
				Data.Lower++;
				if(Data.Lower == Data.Upper)
				{
					Data.Lower++;
					if(Data.Lower>=9)
						Data.Lower -= 2;
				}
				if(Data.Lower>=9)
					Data.Lower = 8;
			}
		}
		B[2].Flag = 0;
	}
	if(B[3].Flag==1)
	{
		if(Data.Switch)
		{
			if(Data.Choose == 0)
			{
				Data.Max_Volt -= 0.3;
				//不能小于最多相等
				if(Data.Max_Volt<Data.Min_Volt)
					Data.Max_Volt = Data.Min_Volt;
			}
			else if(Data.Choose == 1)
			{
				Data.Min_Volt -= 0.3;
				//不能小于0
				if(Data.Min_Volt<0)
					Data.Min_Volt = 0;
			}
			else if(Data.Choose == 2)
			{
				Data.Upper--;
				//相等就再减一次
				if(Data.Upper == Data.Lower)
				{
					Data.Upper--;
					//如果小于1就让它还原
					if(Data.Upper<1)
						Data.Upper += 2;
				}
				if(Data.Upper<1)
					Data.Upper = 1;
			}
			else if(Data.Choose == 3)
			{
				Data.Lower--;
				if(Data.Lower == Data.Upper)
				{
					Data.Lower--;
					if(Data.Lower<1)
						Data.Lower += 2;
				}
				if(Data.Lower<1)
					Data.Lower = 1;
			}
		}
		B[3].Flag = 0;
	}
}

3.4 LED 指示灯功能

这里我们把LED函数放到定时器4的中断中方便0.2s闪烁。

void LED(void)
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	if(Data.Status == 0)//高
	{
		Data.UpperCount++;
		//十毫秒进来一次
		//前20*10 = 200ms = 0.2s灭
		//20-40亮
		if(Data.UpperCount<=40&&Data.UpperCount>=20)
		{
			switch(Data.Upper)
			{
				case 1:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);break;
				case 2:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);break;
				case 3:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);break;
				case 4:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);break;
				case 5:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET);break;
				case 6:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);break;
				case 7:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);break;
				case 8:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);break;
				default:break;
			}
		}
		if(Data.UpperCount>40)
			Data.UpperCount = 0;
	}
	if(Data.Status == 1)//低
	{
		Data.LowerCount++;
		if(Data.LowerCount<=40&&Data.LowerCount>=20)
		{
			switch(Data.Lower)
			{
				case 1:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);break;
				case 2:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);break;
				case 3:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);break;
				case 4:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);break;
				case 5:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET);break;
				case 6:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);break;
				case 7:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);break;
				case 8:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);break;
				default:break;
			}
		}
		if(Data.LowerCount>40)
			Data.LowerCount = 0;
	}
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

3.5初始状态说明

初始化,进行数值的初始化,以及定时器中断的开启,LCD初始化

void Init(void)
{
	HAL_TIM_Base_Start_IT(&htim4);
	LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	Data.Upper = 1;
	Data.Lower = 2;
	Data.Max_Volt = 2.4;
	Data.Min_Volt = 1.2;
}

while主循环

把函数都写进去,以及一些数值的获取和大小的判断

		Data.ADC = getADC()*3.3/4096;
		if(Data.ADC<Data.Min_Volt)
			Data.Status = 1;
		else if(Data.ADC>Data.Max_Volt)
			Data.Status = 0;
		else
			Data.Status = 2;
		Show();
		Key_Handle();

结果展示

结尾

在按顺序写的过程中可能需要修改之前的地方不过没事,修改着来就可以,不要忘记验证,写一个就验证一个,方便查错误。

到此蓝桥杯嵌入式十届省赛完毕,如有错误还请指正,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值