您的位置 首页 知识

一个简略的按键去抖延时程序

按键去抖,一般采用普通延时,如if((GPIOC->IDR0x01)==0){delay_ms(20);if(GPIOC->IDR0x01)==0{进行按键处

按键去抖,一般选用一般延时,如

if((GPIOC->IDR & 0x01)== 0)
{
delay_ms(20);
if(GPIOC->IDR & 0x01)== 0

//进行按键处理函数

}

这个程序,需求有一个一般的延时程序,来检测去颤动,这个延时一般选用for循环和while循环。这样的话,就有一个问题,在延时的这20ms中,cpu一直在判别时刻有没有到。假设不是中止,是不会打断cpu的程序的。这样的话,去抖延时,就会糟蹋cpu的功率。
假设,按键扫描的后边跟一个协议处理的函数。
即:

while(1)

scan_key(); //按键扫描
exe(); //协议解析

这个时分,若接纳中止,在按键扫描时现已处理完结,正好按下按键,这个时分就必须要有20ms的距离,在判别完按键后,才能够进入协议解析函数。也便是说,假设没有扫描函数,协议会当即履行解析并回来呼应数据。而增加按键扫描后,协议有或许会在20ms后,进行解析并回来数据,这样的话,就会使产品的实时性无法确保。

所以我想了另一个办法,选用美丽位,来完结延时,当然这个办法,必定不是我第一个想出来的。如有雷同,可选用翻钢镚办法进行挑选。
便是选用if句子来完结延时,只不过写程序时比较费事,但稳定性在stm8上测试了一下,感觉还能够。

代码如下
首要请求几个全局变量
unsigned int time_ms,time_us,time_ns,time_flag;
//以上这几个是守时标志和守时计数变量
unsigned key_old, key_new;
//这两个是按键键值

/*******************************************************************************
函数名:delay_ms()
函数功用:延时
参数:ms 毫秒
回来:无
补白:此延时函数选用if完结,使用时,必须先请求flag变量然后调用延时函数,最终在
履行中参加flag判别
例:u16 time_flag,time_ms,time_us,time_ns;
delay_ms(u16 ms);
if(time_flag>0){time_flag=0;……内容}
*******************************************************************************/
void key_delay(unsigned int ms)
{
if(time_ms{
if(time_us<10) //在应用时,不同的单片机,不同的频率,需求进行调整
{
if(time_ns<8) //在应用时不同的单片机,不同的频率,需求进行调整
{
time_ns++;
}
else
{
time_us++;
time_ns=0;
}
}
else
{
time_ms++;
time_us=0;
}
}
else
{
time_flag=1;
time_ms=0;
}
}

以上代码,有一个time_flag,变量,这个变量便是守时美丽变量。一旦这个美丽置一,则阐明守时器届时刻
使用时能够

///////////////////////////////////////////////////////////
//函数名:scan()
//功用:按键扫描
//参数:无
//回来值:无
//补白:
///////////////////////////////////////////////////////////
void scan()
{
u8 key_new;
key_new = GPIOC->IDR;
if(key_old != key_new)
{
key_delay(150);
if(time_flag == 1)
{
time_flag = 0;
if(key_old != key_new)
{
switch()
{
case 1: k1_exe(); break;
case 2: k2_exe(); break;
case 3: k3_exe(); break;
case 4: k4_exe(); break;
default: break;
}
key_old = key_new;
}
else

time_ms=0;

}
}
}

以上便是代码
在大循环中,直接调用即可,和一般的按键函数相同,只不过,这个的实时性,应该相对较高一些。
while(1)

scan_key(); //按键扫描
exe(); //协议解析

让咱们来剖析一下,为啥这个函数相对较好一些。
首要,咱们来看
scan_key();
首要,扫描IO端口,寄存如新按键变量
key_new = GPIOC->IDR;
然后将新按键与老按键号进行比照,假设新的按键号与老按键号不同,阐明有按钮按下。
if(key_old != key_new)
当有按钮按下的时分进入,延时函数,
key_delay(150);
这时,进入多个if判别,进行time_ns++;这个函数,最主要的功用便是判别,当时的时刻time_ms,与参数时刻,是否共同,若不共同,则退出函数。这时time_flag不为1,当时的时刻time_ms,与参数时刻共同 ,这时time_flag为1。
if(time_flag == 1)
这个判别便是判别届时美丽,假设届时,则阐明去抖时刻完结,则在判别一次if(key_old != key_new),假设为否,则阐明按键的确按下,不然则为没有按下。有按键按下时,则会履行按键处理函数。
若没有按键按下,则清楚计数器。程序持续履行。
也便是说,不论是否在延时状况,程序,都会向下履行,而不会卡在某一个函数或循环内不动。这样的话,程序就会向下持续履行。
在程序中,若既有按键,又有一些对待实时性较高,但又不乐意放在中止里的程序。能够选用这种办法来完结按键延时,能够相对的进步程序的运转功率。现在这个程序,不支持长按,但能够完结简略的组合按键。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/318711.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部