外部中断的按键,软件滤波实现方法
来源:互联网 发布:python epoll 编辑:程序博客网 时间:2024/06/07 17:47
按键分为机械按键和触摸按键,每种按键都有不同程度的抖动。
这里我们来说下机械按键吧,新手都会接触到。我用的板子是MSP430G2553 的那块红色的板子做的。
上面的独立按键有一个,接在P13口上,我自己制作了一个LCD5110的转接板,渣手工。
下面讨论我们的重点,按键。
对于机械按键,抖动的原因是因为刚性接触时候会发生碰撞之类的,所以并不是可靠地接触,所以会产生抖动,那么我们的软件就要进行滤波。
那么我们要怎么做呢?
一般的方法是进行延时,就是等待,Delay(...)大家估计不陌生。但是这样做的结果是CPU的可耻浪费,那么我们要如何去做呢?
不用等待,又能精确定时,那么就是定时器了。使用定时器进行扫描,中断进行触发,就是我们对付按键的方法。
具体步骤如下:
1、中断服务程序,检测按键是否被触发。
2、定时器运行,扫描按键状态,完成消抖动作。
对于MSP430来说,P13是一个外部中断的中断源,所以我们可以直接将P13设置为外部中断输入就可以进行检测,代码如下:
void P1_inter_Init(void)
{
P1IES|=BIT3; //选择下降沿触发
P1REN |=BIT3; //上啦电阻
P1IFG &=~BIT3; //P1IES的切换可能使P1IFG置位,需清除
P1IE|=BIT3; //打开中断允许
}
然后就可以完成第一步了,第二步,定时器,那么首先要配置定时器的周期,这里我用了CCR1的中断来扫描,CCR0来设置扫描周期,(不会的去看看MSP430的定时器A部分)
void Time0_A0_Init(void)
{
TACCR0 = 327; //10ms
TACCTL0 = CCIE; //允许中断
TACCR1 = 32;
// TACCTL1= CCIE;
TA0CTL = TASSEL_1+TACLR+MC_1; //模式设置
}
需要特别注意的是,我并没有直接开启CCR1的中断任务,因为一直处于扫描状态是会给CPU带来极大的压力。我们只在按键被触发了的时候,才进行扫描(精髓所在)。
所以在外部中断里面,我们才打开定时器的CCR1中断,进行扫描。
#pragma vector=PORT1_VECTOR
__interrupt void P1_In(void)
{
if(P1IFG&BIT3)
{
//处理P1IN.3中断
P1IFG &= ~BIT3; //清除中断标志
P1OUT ^= BIT0;
//以下填充用户代码
TACCTL1= CCIE; //开CCR1中断来扫描状态
P1IE&=~BIT3; //关闭外部中断
}
LPM3_EXIT; //不喜欢低功耗的小伙伴不要这句
}
然后,再在定时器中断中添加我们的扫描代码
#pragma vector=TIMER0_A1_VECTOR
__interrupt void T0_A1_Inter()
{
switch(TA0IV)
{
case 2: //CCR1
//ii++;
if(Switch_scan(&steep)) //键盘状态机
ii++;
break;
case 4: //CCR2
break;
case 10: //OVER
break;
}
}
其中扫描的函数我们采用状态机来编写,这对于一些新手来说可能比较少见
char Switch_scan(char *steep)
{
switch(*steep)
{
case 0:
if(P1IN&BIT3) //表示如果下降后直接上升,表示为抖动
{
TACCTL1 &= ~CCIE; //把定时器扫描关掉
P1IE|=BIT3; //把中断打开
(*steep) = 0;
}
else //表示电平为低
{
(*steep)++;
}
break;
case 1:
if(P1IN&BIT3) //表示为抖动
(*steep) = 0;
else //这句保证2次认证按键的电平无误
(*steep)++;
break;
case 2: //这里是检测松手
if(P1IN&BIT3)
(*steep) =3; //松手了往下走
else //不然就在这里等松手
;
break;
case 3:
if(P1IN&BIT3) //的确松手了
{
(*steep)=0; //重置状态机状态
return 1; //返回键值有效信号
}
else
;
break;
default : break;
}
return 0;
}
我们将按键的状态分解成 按下→ 保持→ 松开 分别检测状态,制作条件语句和跳转逻辑,当第一次扫描发现按键只是抖动的时候,果断的关闭定时器的CCR1中断,并且重新打开外部的按键触发中断,这样一来,既节省了系统的开支,又可以可靠地进行按键的滤波。程序写进去发现效果很好,希望可以帮到大家。
这里我们来说下机械按键吧,新手都会接触到。我用的板子是MSP430G2553 的那块红色的板子做的。
上面的独立按键有一个,接在P13口上,我自己制作了一个LCD5110的转接板,渣手工。
下面讨论我们的重点,按键。
对于机械按键,抖动的原因是因为刚性接触时候会发生碰撞之类的,所以并不是可靠地接触,所以会产生抖动,那么我们的软件就要进行滤波。
那么我们要怎么做呢?
一般的方法是进行延时,就是等待,Delay(...)大家估计不陌生。但是这样做的结果是CPU的可耻浪费,那么我们要如何去做呢?
不用等待,又能精确定时,那么就是定时器了。使用定时器进行扫描,中断进行触发,就是我们对付按键的方法。
具体步骤如下:
1、中断服务程序,检测按键是否被触发。
2、定时器运行,扫描按键状态,完成消抖动作。
对于MSP430来说,P13是一个外部中断的中断源,所以我们可以直接将P13设置为外部中断输入就可以进行检测,代码如下:
void P1_inter_Init(void)
{
P1IES|=BIT3; //选择下降沿触发
P1REN |=BIT3; //上啦电阻
P1IFG &=~BIT3; //P1IES的切换可能使P1IFG置位,需清除
P1IE|=BIT3; //打开中断允许
}
然后就可以完成第一步了,第二步,定时器,那么首先要配置定时器的周期,这里我用了CCR1的中断来扫描,CCR0来设置扫描周期,(不会的去看看MSP430的定时器A部分)
void Time0_A0_Init(void)
{
TACCR0 = 327; //10ms
TACCTL0 = CCIE; //允许中断
TACCR1 = 32;
// TACCTL1= CCIE;
TA0CTL = TASSEL_1+TACLR+MC_1; //模式设置
}
需要特别注意的是,我并没有直接开启CCR1的中断任务,因为一直处于扫描状态是会给CPU带来极大的压力。我们只在按键被触发了的时候,才进行扫描(精髓所在)。
所以在外部中断里面,我们才打开定时器的CCR1中断,进行扫描。
#pragma vector=PORT1_VECTOR
__interrupt void P1_In(void)
{
if(P1IFG&BIT3)
{
//处理P1IN.3中断
P1IFG &= ~BIT3; //清除中断标志
P1OUT ^= BIT0;
//以下填充用户代码
TACCTL1= CCIE; //开CCR1中断来扫描状态
P1IE&=~BIT3; //关闭外部中断
}
LPM3_EXIT; //不喜欢低功耗的小伙伴不要这句
}
然后,再在定时器中断中添加我们的扫描代码
#pragma vector=TIMER0_A1_VECTOR
__interrupt void T0_A1_Inter()
{
switch(TA0IV)
{
case 2: //CCR1
//ii++;
if(Switch_scan(&steep)) //键盘状态机
ii++;
break;
case 4: //CCR2
break;
case 10: //OVER
break;
}
}
其中扫描的函数我们采用状态机来编写,这对于一些新手来说可能比较少见
char Switch_scan(char *steep)
{
switch(*steep)
{
case 0:
if(P1IN&BIT3) //表示如果下降后直接上升,表示为抖动
{
TACCTL1 &= ~CCIE; //把定时器扫描关掉
P1IE|=BIT3; //把中断打开
(*steep) = 0;
}
else //表示电平为低
{
(*steep)++;
}
break;
case 1:
if(P1IN&BIT3) //表示为抖动
(*steep) = 0;
else //这句保证2次认证按键的电平无误
(*steep)++;
break;
case 2: //这里是检测松手
if(P1IN&BIT3)
(*steep) =3; //松手了往下走
else //不然就在这里等松手
;
break;
case 3:
if(P1IN&BIT3) //的确松手了
{
(*steep)=0; //重置状态机状态
return 1; //返回键值有效信号
}
else
;
break;
default : break;
}
return 0;
}
我们将按键的状态分解成 按下→ 保持→ 松开 分别检测状态,制作条件语句和跳转逻辑,当第一次扫描发现按键只是抖动的时候,果断的关闭定时器的CCR1中断,并且重新打开外部的按键触发中断,这样一来,既节省了系统的开支,又可以可靠地进行按键的滤波。程序写进去发现效果很好,希望可以帮到大家。
0 0
- 外部中断的按键,软件滤波实现方法
- 外部中断的按键,软件滤波实现方法
- 【stm32f407】外部中断实现按键中断方式
- 基于mini2440外部中断的按键驱动
- 外部中断按键驱动
- 按键与外部中断
- TMS320F28335---外部按键中断
- 基于S5PV210的中断和外部按键中断
- STM32按键扫描/按键中断/外部中断
- 软件滤波方法与实现
- 用龙芯1c库在RT-Thread下实现外部中断(GPIO中断、按键中断)
- 用龙芯1c库在裸机编程中实现外部中断(GPIO中断、按键中断)
- s3c6410 的外部中断实现
- mini240外部按键中断程序
- mini240外部按键中断程序
- 外部中断按键驱动程序编写
- 外部中断(按键1)
- S3C2440 外部按键中断解析
- OpenGL系列教程之十二:OpenGL Windows图形界面应用程序
- Android6.0系统ScrollView嵌套RecyclerView冲突问题
- js中的逻辑与(&&)和逻辑或(||)以及==和===的区别
- 第二届全球区块链峰会随记
- java设计模式详解--工厂模式
- 外部中断的按键,软件滤波实现方法
- JMeter负载测试入门教程 – 终极指南
- 图并行计算实践(二)(spark streaming+graphx+kafka)
- 任务2:编写第一个Java程序
- Java基本程序设计结构2
- 在VC开发中使用简单灵巧的压缩/解压工具包LiteZip/LiteUnzip
- VS2010使用Release进行调试的三个必须设置选项
- [李景山php]算法系列|php 进行栈操作 之 回文字符串 判定
- 浅谈json