蓝桥杯第一天的学习

冲击国赛争取保研

led和lcd

这是一个控制led的函数

#define uchar unsigned char
void LED_Disp(uchar dsLED)
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET);//移位确定LED状态
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

然后lcd部分记住不需要配置cube直接导入就能用 sprintf要引入头文件stdio.h

key

这部分算是比较麻烦的,涉及单击、双击、长按。 这部分还需要用到定时器,此单片机的定时器如下 Alt text

按键单击代码

struct keys
{
	uchar judge_sta;//判断到哪一步
	bool key_sta;//按键按下为0
	bool single_sta;//确认按键按下为1
};//此为.h文件中定义的结构体
struct keys key[4]={0,0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)
	{
		key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		for(int i=0;i<4;i++)
		{
			switch(key[i].judge_sta)
			{
				case 0://判断按键第一次被按下,相当于消抖
				{
					if(key[i].key_sta==0)
						key[i].judge_sta=1;//前往第二种状态
				}
				break;
				case 1:
				{
					if(key[i].key_sta==0)//判断按键第二次被按下
					{
						key[i].judge_sta=2;//前往第三种状态
						key[i].single_sta=1;//按键被单击标志,在main函数中用到时需将这个标志位清空
					}
					else
						key[i].judge_sta=0;//回到第一种状态
				}
				break;
				case 2:
				{
					if(key[i].key_sta==1)//判断按键被松开状态就重新会到1
					{
						key[i].judge_sta=0;//会到第一种状态
					}
				}
				break;
			}
		}
	}
}

按键长按代码

期中包括了按键单击

struct keys
{
	uchar judge_sta;//判断到哪一步
	uint key_time;//判断按下时间
	bool key_sta;//按键按下为0
	bool single_sta;//确认按键按下为1
	bool long_sta;//长按键
};//同样这里包含了.h文件
struct keys key[4]={0,0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)
	{
		key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		for(int i=0;i<4;i++)
		{
			switch(key[i].judge_sta)
			{
				case 0://判断按键第一次被按下,相当于消抖
				{
					if(key[i].key_sta==0)
					{
						key[i].judge_sta=1;//前往第二种状态
						key[i].key_time=0;//按键按下时间清零
					}
				}
				break;
				case 1:
				{
					if(key[i].key_sta==0)//判断按键第二次被按下
					{
						key[i].judge_sta=2;//前往第三种状态
						
					}
					else
						key[i].judge_sta=0;//回到第一种状态
				}
				break;
				case 2:
				{
					if(key[i].key_sta==1)//判断按键被松开状态就重新会到1
					{
						key[i].judge_sta=0;//回到第一种状态
						if(key[i].key_time<70)//时间小于700ms就相当于短按键
							key[i].single_sta=1;//按键被单击标志,在main函数中用到时需将这个标志位清空
					}
					else
					{
						key[i].key_time++;//按键没有松开时间就加
						if(key[i].key_time>70)//时间大于700ms就相当于长按键 
							key[i].long_sta=1;
					}
				}
				break;
			}
		}
	}
}

按键双击

这部分在csdn上找到的,还没测试过

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)			//判断中断信号是否来自定时器3
	{
		key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);		//读按键PB0现在的状态,如果被按下,PB0  = 0;如果没有被按下,PB0 = 1;
		key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		
		for(int i = 0;i < 4; i++ )		//确认是哪个或哪些按键被按下了
		{
			switch (key[i].judge_sta)
			{
				case 0:
				{
					if(key[i].key_sta==0) key[i].judge_sta = 1;	//第一次判断是否按下
				}
				break;
				case 1:
				{
					if(key[i].key_sta==0)	//进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖
					{
						if(a == i && key[a].key_time < 70)	//小于70,说明上次按下后到这次按下时间间隔小于0.7秒
						{
							key[i].double_key_flag = 1;		//这是一次双击事件
						}
						else
						{
							key[i].key_flag = 1;
							a = i;							//记录这一次是上面按键被按下
						}
						key[i].judge_sta = 2;
					}
					else		//否则就是抖动,本次不算按键被按下
						key[i].judge_sta = 0;
				}
				break;
				case 2:
				{
					if(key[i].key_sta==1) key[i].judge_sta = 0;	//判断是否松手,松手后按键状态重置
					key[i].key_time = 0;
				}
				break;
			}
		}
		key[a].key_time++;		//第一次被按下之后,开始计时
	}
}

本文章使用limfx的vscode插件快速发布