单片机最简单的独立按键写法(个人理解)

发布时间:2024年01月03日

我们初学者在学些写51或者类似的单片机的时候总会为了写独立按键消抖,单击,长按,多连击而苦恼,网上都是什么中断,状态机之类的写法,也各有千秋。但是经常用的无非那几种。

我也是准备了几种简单的对应方法,适用于几种人群。

以下内容均为本人学习的时间自行研究的,若有什么不对地方请多多包含。

通过main函数运行时长进行消抖(小白级)

bit click = 0;//单击标志位
u8 key=0;//按键状态
u32 count=0;//计数

void main(){
	
	while(1){
/*按键扫描代码*/
		if(P0!=0xff){				//按键按下执行
			if(count==8)			//消抖后拿到按键状态值(消抖时间一般10ms以内)
				key = ~P0;			//这里是按键按下为低电平,取反是为了下面方便判断
			count++;					//消抖
		}else if(count>8){	//按键松开后执行
			count=0;					//结束计数清零
			click=1;					//单击标志位置1
		}else
			count = 0;				//抖动误触清零
		
/*单机后处理代码*/
		if(click){					//如果按键单击
			
			if(key==0x01)			//判断按键执行操作,从0000 0001 依次左移1位
				//执行内容...
			else if(key==0x02)
				//执行内容...
			else if(key==0x04)
				//执行内容...
			
			click=0;					//执行完标志置0
		}
		
		delay(1);						//假设主函数运行一次的时长为1ms
	}
}

这里按键是P0端口8个,如果不同可以自行更改。默认高电平,按下低电平。

这里是通过估计main函数运行一次的时长来进行消抖的,只写了单击,因为估算终究是估算,后面的长按之类的时间并不能做到特别准确就不写了。

原理就是每执行一次计数加1,当到了差不多10ms的值的时候就会消抖完成,然后拿到按键状态(只适用于同一时刻一个按键按下),然后如果是抖动的话下面的else就会清空重新计数,只有在计数在消抖完成后抬起才能进入单击的处理,代码简短,适用于只追求效果的方案。

基于上面方案实现多按键按下(入门级)

u8 	click=0;	//单击标志位
u8 	key[8]={0,0,0,0,0,0,0,0};		//按键状态
u16 count[8]=0;									//计数

void main(){
	u8 i;
	while(1){
		for(i=0;i<8;i++){
			if(!(P0&0x01<<i)){	//判断每一个按键的状态
				if(count[i]==8)			//消抖后拿到按键状态值(消抖时间一般10ms以内)
					key[i] = 1;			//这里是按键按下为低电平,取反是为了下面方便判断
				count[i]++;					//消抖
			}else if(count[i]>8){	//按键松开后执行
				count[i]=0;					//结束计数清零
				click=1;					//单击标志位置1
			}else
				count[i] = 0;				//抖动误触清零
		}
		
		if(click){					//如果按键单击
			if(key[0]){}			//判断按键执行操作,从key[0]~key[7]
				//执行内容...
			if(key[1]){}
				//执行内容...
			if(key[2]){}
				//执行内容...
			
			click=0;					//执行完标志置0
		}
		
		delay(1);						//假设主函数运行一次的时长为1ms
	}
}

这里就是用了一个for循环进行了8次按键的扫描,来实现多按键同时判断。

这时候下面判断就可以用多个if判断,因为可能会遇到多种情况了。但是如果不用定时器来计数,终归不是太过于严谨了。

最后,因为这也是本人的第一篇文章,也不太发过多篇幅,后面会在多多分享个人的经验的,有错的地方也希望能够指点。

文章来源:https://blog.csdn.net/qq_73787534/article/details/135306940
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。