完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
按键消抖原理
一、首先来回顾一下按键延时消抖 按键由于是机械结构,按下的时候难免产生抖动,一般抖动会在按下的时候与松开的时候产生,抖动时间大概是10ms 于是针对按键抖动就有了延时消抖的一种简单的解决方法: 二、按键消抖代码 方法一: 按下按键损耗的时间取决于按下按键到松开的时间,至少10ms,按下按键后CPU不再执行其他指令,直到按键松开,应用能力弱 代码作用:按下按键led状态取反,按下按键需要等待松开 #include ***it key=P1^0; //定义key为P1.0 ***it led=P2^0; //定义LED为P2.0 void delay_ms(unsigned int t) //ms延时 { unsigned int i,j; for(i=0; i } void main(void) { while(1) { if(key==0) //读P1.0引脚,如果引脚为低电平,则进入if { delay_ms(10); //延时10ms消抖 if(key==0) //再次判断按键是否按下,防止干扰,增强稳定 { led = !led;//led状态改变 while(key==0);//等待按键松开,防止往下执行 } } } } 方法二: (无while)按下按键损耗的时间大约10ms,无需等待,按下按键期间可以进行其他操作,应用能力较强 代码作用:按下按键led状态取反,按下按键不需要等待松开 #include ***it key=P1^0; //定义key为P1.0 ***it led=P2^0; //定义LED为P2.0 void delay_ms(unsigned int t) //ms延时 { unsigned int i,j; for(i=0; i } void main(void) { int key_up=1; //按键松开标志位 while(1) { if(key==0 && key_up==1)//判断按键是否按下 { delay_ms(10);//延时消抖 key_up=0;//防止循环执行按键控制程序 if(key==0) //再次判断,排除是松开状态或外界杂波干扰 { led1=!led1; } } else if(key==1) key_up=1;//无按键按下改为松开状态 } } 可以看到,延时消抖最大的弊端就是有延时,至少要消耗10ms~20ms的时间,对于我们来说10ms或许很短,但对于一些高性能的MCU来说,那就是能执行几万条指令的时间 按键定时器消抖 一、按键消抖 按键消抖一般分为4步: 1、判断按键是否按下 2、消抖 3、再次判断按键是否按下 4、等待按键松开 二、定时器消抖原理 1、判断按键是否按下, 2、若检测到有按键按下,则开启定时器,开启定时中断,定时时间为10ms 左右,使得按键按下10ms后进入定时中断,进入中断的时候按键抖动时间已过 3、在定时器中断中再次判断按键是否按下 4、关闭定时器,等待按键松开 代码: #include ***it key=P1^0; //定义key为P1.0 ***it led=P2^0; //定义LED为P2.0 void main(void) { TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。 TH0=(65536-10000)/256; //给定时器赋初值,定时10ms TL0=(65536-10000)%256; ET0=1;//打开定时器0中断允许 EA=1;//打开总中断 TR0=0;//关闭定时器 while(1) { if(key==0) //读P1.0引脚,如果引脚为低电平,则进入if { TR0=1;//打开定时器 } } } /*定时器中断*/ void Timer0() interrupt 1 { TH0=(65536-10000)/256; //给定时器赋初值,定时10ms TL0=(65536-10000)%256; TR0=0;//关闭定时器 if(key==0) //再次判断按键是否按下 { led=!led; while(key==0); //等待按键松开 } } 可以看到,上面的代码依然有"while(key==0); //等待按键松开"这句代码,会让程序等待 程序升级!最终代码 更改电路,加入外部中断: 代码: #include ***it key=P3^2; //定义key为P1.0 ***it led=P2^0; //定义LED为P2.0 void main(void) { TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。 TH0=(65536-10000)/256; //给定时器赋初值,定时10ms TL0=(65536-10000)%256; ET0=1;//打开定时器0中断允许 TR0=0;//关闭定时器 IT0=1;//跳变沿出发方式(下降沿) EX0=1;//打开INT0的中断允许。 EA=1;//打开总中断 while(1) { } } /*定时器中断*/ void Timer0() interrupt 1 { TH0=(65536-10000)/256; //给定时器赋初值,定时10ms TL0=(65536-10000)%256; TR0=0;//关闭定时器 if(key==0) //再次判断按键是否按下 { led=!led; //控制led状态取反 } } /*外部中断0*/ void Int0() interrupt 0 //外部中断0的中断函数 { TR0=1;//打开定时器 } 可以看到整个程序没有延时,也没用等待,实现了按键功能。 END。 |
|
|
|
只有小组成员才能发言,加入小组>>
2597 浏览 0 评论
794浏览 1评论
240浏览 1评论
558浏览 0评论
305浏览 0评论
517浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-24 06:42 , Processed in 0.998892 second(s), Total 44, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号