标题: 求助:KBI消抖 [打印本页]
作者: huibin.chen 时间: 2009-5-22 15:58 标题: 求助:KBI消抖
各位老大:
1 最近在使用QE128的KBI,没有发现它有硬件方面消抖的功能。
问一下大家都是怎么消抖的呢。
2 由于我的KBI一部分作为按键使用,一部分用来计多路脉冲。
如果采用在中断中用delay(20) //20ms的方法软件延时消抖的话,那如果在20ms消抖过程中,另一路脉冲到来怎么办,
而且我有5路的脉冲。
作者: strongchen 时间: 2009-5-22 16:09
不能只是简单地延时,必须判断是那个引脚产生的信号,再针对相应的引脚进行去抖处理。
作者: huibin.chen 时间: 2009-5-22 16:24
版主你好,我判断出了是哪个引脚产生的脉冲信号后,那在针对它进行延时去抖的过程中,其他引脚的脉冲来了怎么办呢,这样肯定导致脉冲丢失吧。
作者: strongchen 时间: 2009-5-22 16:27
同一个引脚在一定延时内产生的中断,可认为是抖动信号;而不同引脚产生的中断,则不是抖动,可以采信。
作者: huibin.chen 时间: 2009-5-22 16:52
还是没明白什么意思。
我的程序流程是这样的:我是用的下降沿产生中断。
当引脚1产生KBI中断进入中断服务程序,查询到是该引脚产生的中断,此时延时20ms,再次判断引脚状态如果确实是按下的话,表明不是抖动。
我的问题是,当在引脚1的延时消抖在执行时,由于它一直占着中断服务程序,其他的引脚来脉冲时,将无法再进入中断程序,那岂不就丢脉冲了,这种情况应该怎么处理。
是不是存在这样的情况,引脚1产生中断,马上把KBI的中断标志位清除KBISC_KBACK = 1;这样当我做完引脚1的延时判断处理后,引脚2、引脚3等其他脉冲在引脚1延时消抖的时候产生的下降沿同样会再次导致进入中断呢。
感觉如果同时来了好几路脉冲的话,根本处理不过来啊。
作者: fish1330 时间: 2009-5-25 10:22
1.中断服务程序提供信号标志,但是不要进行其他操作;
2.main函数查询中断服务提供的信号标志,进行处理相关的操作;
3.消抖太简单了,可以采取延迟、计时、计次等操作进行处理。
根据我提供的方法,可以轻松解决上诉问题。
作者: strongchen 时间: 2009-5-25 10:23
去抖延时不应在中断中执行。中断产生后,应首先进行判断,然后尽快清中断标志后退出。其他的处理和延时都应该在主循环中进行。
[此贴子已经被作者于2009-5-25 10:23:42编辑过]
作者: fish1330 时间: 2009-5-25 10:29
我这边有个程序,2路采集脉冲信号(还需要计算脉冲的宽度),16路采集按键信号,8路采集AD信号。均有防抖处理。
其实防抖是个必要的过程。任何模拟量、脉冲信号的采集,都会有所误差和抖动,如果防抖没做好,那么数据就会产生实时性的偏移。
防抖处理绝对不能占用中断服务程序,不然会使整个系统失去实时性。
[此贴子已经被作者于2009-5-25 10:29:47编辑过]
作者: huibin.chen 时间: 2009-5-25 19:19
fish1330 你好
中断服务程序提供信号标志,MAIN函数的查询肯定比较慢,我的MAIN要50多ms才会转一圈,这样如果多个脉冲信号标志同时来的话,Main根本来不及呀。
你的消抖是不是这样做:MAIN查询到脉冲的信号标志后,延时若干毫秒,再读一次脉冲状态,如果还是高电平表示脉冲确实产生,否则视作抖动。这样像你说的那么多路的信号,那得延时多少时间呀。
能不能提供一个测试例程出来参考一下呢,非常感谢!
作者: strongchen 时间: 2009-5-26 10:18
如果主循环太慢,也可以用定时器来进行延时。
作者: fish1330 时间: 2009-5-26 16:58
for (;;)
{
WATCHDOG(); //喂狗
//---- 10MS 事件处理------------**
if(Time10MS == TRUE)
{
Time10MS = FALSE;
Main_10MS_Event();//按键、报警综合处理
}
//---- 100 MS事件处理------------**
if(Time100MS == TRUE)
{
Time100MS = FALSE;
if(u8TripShow == TRUE)
{
u8temp = Cantx_Milesep();
u8TripShow = FALSE;
}
//------- 蜂鸣器事件-----------
Pwm_Bzloop();
Main_100MS_SRVEvent(); //脉冲信号处理
//----- 1秒 事件处理------------**
tim1s ++;
if((m1s % 10) == 0) //1秒
{
Main_1S_Ad_Event();
Main_1S_Can_Event();
}
//----- 6秒 事件处理------------**
if((tm1s % 60) == 0)
{
Main_6S_Events(); //--
}
}
作者: fish1330 时间: 2009-5-26 17:04
我特意做了个计时,main主循环里面的计时误差极小,1小时的误差在10秒内。
中断部分,除了提供10MS、100MS基准时钟外,还进行脉冲信号采集、计数,防抖处理均在主循环调用的函数中进行。
你主循环太慢,是你的中断系统使用不当引起的问题,或者算法问题。
浮点数运算有吗?
作者: zhangyifei68 时间: 2009-7-3 10:47
个人认为多路采集脉冲等信号,使用KBI等外部中断没有意义,直接用定时器中断进行多次检测去抖比较合适,至于是在中断中就直接处理还是在主循环中处理无所谓(我所指的处理只限于去抖过程,至于去抖后的事件处理一定要在主循环中执行,这是必须的),比如检测一个20ms的脉冲,可以定时1ms的定时器中断,连续检测20次以上脉冲电平就置该标志,然后在主循环中查询标志进行处理即可,或者像楼上的说的一样,直接在中断中置1ms标志然后在主循环中查询标志再去抖也行(至于这两种方法那种实时性更好,大家可以讨论一下,就我个人而言,我认为前者好点或者说差不多,因为最后要做到的效果是不管哪种方法都要一次不能错过的检测到信号,所以我选择了前者,而两种的处理实时性我感觉应该是一致的,所以个人认为两者皆可),但楼主的做法是绝对不行的,中断中坚决不能有延时,就算支持多重嵌套,估计也能把你给套牢了哈哈!
作者: zhangyifei68 时间: 2009-7-3 10:55
补充:之所以认为前者(在中断中直接去抖)好,还有一个原因是因为,主循环中出现处理时间很长的子程序是很有可能的,所以在主循环中检测毫秒级的标志很有可能会错过。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) |
Powered by Discuz! 7.0.0 |