文章目录

一、前言

二、第九届真题题目

三、按键长短按

时钟的基本配置

按键长短实现代码

四、LCD字体显示高亮

五、小结


一、前言

做第九届真题对我来说最大的收获就是学会了按键长短按的技巧,用定时器来实现。接下来将介绍按键长短按以及LCD的高亮显示。

我认为,既然开始做真题了,说明是有一定的基础了,所以在这里我就只分享我做题时还未掌握的技巧进行分享。

二、第九届真题题目

三、按键长短按

首先是长按短按的技巧,利用定时器的定时扫描,判断哪个按键被按下了,同时对按键进行判断是长按还是短按,返回相应的标志变量。在按下是开启计时,若时长大于规定的0.8s,则判定位长按,反之即为短按。具体实现如下:

时钟的基本配置

按键长短实现代码

struct keys{
		uchar judge_sta;
		bool key_sta;
		bool single_sta;//确认按下标识/*短按键标识*/
		bool long_sta;/*长按键标识*/
		uint16_t key_time;/*计时*/
	};

struct keys key[4]={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)	//如果第一次被按下,则让按键在10ms后进入下一次扫描
						{
							key[i].judge_sta=1;
							key[i].key_time=0;	//按键被按下了,时间清零
						}
				}
					break;
				case 1:
				{
					if(key[i].key_sta==0){	//10ms过后还是被按下
						key[i].judge_sta=2;	//准备进入下一个,判断是长按还是短按
									//key[i].single_sta=1;按下标志位置1,说明被按下
									//放到case2确认松开后再确认,防止长短按键冲突
					}else
						key[i].judge_sta=0;	//否则按下标志位置0,说明没被按下,继续回到case 0判断。
				}
					break;
				case 2:
				{
					if(key[i].key_sta==1)	//如果松开了,则清零
					{	
						key[i].judge_sta=0;
						if(key[i].key_time<700)
						{
							key[i].single_sta=1;	/*说明是短按键的情况*/
						}
					}
						else{			/*在没有松开的这段时间里让time++*/
						key[i].key_time++;	/*以确定被按下多长时间*/
						if(key[i].key_time>700){
							key[i].long_sta=1;	/*确认长按键被按下*/
							}
						}
				}
					break;
			}
			
			
		}
	}
}

再在主函数中进行按键判断即可,记得要开启时钟,以B1(即GPIOB,GPIO_PIN_0)为例:

if(key[0].single_sta==1){//如果k0被按下了,则进入
			//功能实现
			key[0].single_sta=0;//k0用完后要把标志位清零,证明用过,也防止出现一直循环的情况。
		}
		
		if(key[0].long_sta==1){/*如果k0被长按了*/
			//功能实现
			key[0].long_sta=0;//k0用完后要把标志位清零,证明用过,也防止出现一直循环的情况。
		}

四、LCD字体显示高亮

这里我用了一个“笨方法”,只要将每个变量分开显示,就可以比较简单的实现某一部分的高亮,原理代码如下:

if(num2%3==1){
				LCD_SetTextColor(Red);
				LCD_DisplayChar(Line4,320-96,(s/10)+'0');
				LCD_DisplayChar(Line4,320-112,(s%10)+'0');
				LCD_SetTextColor(White);
				LCD_DisplayChar(Line4,320-128,':');
				LCD_DisplayChar(Line4,320-144,(f/10)+'0');
				LCD_DisplayChar(Line4,320-160,(f%10)+'0');
				LCD_DisplayChar(Line4,320-176,':');
				LCD_SetTextColor(White);
				LCD_DisplayChar(Line4,320-192,(m/10)+'0');
				LCD_DisplayChar(Line4,320-208,(m%10)+'0');
			}
			if(num2%3==2){
				LCD_SetTextColor(White);
				LCD_DisplayChar(Line4,320-96,(s/10)+'0');
				LCD_DisplayChar(Line4,320-112,(s%10)+'0');
				LCD_DisplayChar(Line4,320-128,':');
				LCD_SetTextColor(Red);
				LCD_DisplayChar(Line4,320-144,(f/10)+'0');
				LCD_DisplayChar(Line4,320-160,(f%10)+'0');
				LCD_SetTextColor(White);
				LCD_DisplayChar(Line4,320-176,':');
				LCD_DisplayChar(Line4,320-192,(m/10)+'0');
				LCD_DisplayChar(Line4,320-208,(m%10)+'0');
			}
			if(num2%3==0){
				LCD_SetTextColor(White);
				LCD_DisplayChar(Line4,320-96,(s/10)+'0');
				LCD_DisplayChar(Line4,320-112,(s%10)+'0');
				LCD_DisplayChar(Line4,320-128,':');
				LCD_SetTextColor(White);
				LCD_DisplayChar(Line4,320-144,(f/10)+'0');
				LCD_DisplayChar(Line4,320-160,(f%10)+'0');
				LCD_DisplayChar(Line4,320-176,':');
				LCD_SetTextColor(Red);
				LCD_DisplayChar(Line4,320-192,(m/10)+'0');
				LCD_DisplayChar(Line4,320-208,(m%10)+'0');
				LCD_SetTextColor(White);
		}

可以将它封装成函数再放到主函数里,看着就不会很乱。

注:这只是一个提供思路的代码,具体要实现第九届的功能,需要自己再根据情况增加判断条件或者标识符。

五、小结

按键的记住一定要将标志位清零。其实长短按和lcd高亮的功能可以做到后,其他的基本上也就没什么大问题了。都是一些简单的实现,如LCD的显示,eeprom存储以及pwm的输出,选择开始做真题的话,这一部分简单的功能都基本可以实现了吧。这里我就不放代码了,因为我在做题时的功能实现都是一点点来的,有些东西没有封装成函数,标志位命名的也很随便,一大堆东西都堆在主函数里,看了可能会有些到你的思路,干脆就不放了。记住将学的东西运用上即可。如果还有其他功能没有掌握的话就需要再费点时间在没掌握的部分啦。

还有一个最重要的,标志变量一定要命名得简单易懂,不然自己后来读代码的时候也不知道当时自己写的是什么,这在开始学编程的时候一定就有人会给你强调的吧。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐