【问题标题】:avr external interrupt false triggeravr 外部中断误触发
【发布时间】:2014-04-22 03:37:51
【问题描述】:

我正在使用 ATmega128 为外部中断编程。我将外部中断 0 和 1 设置为下降沿触发中断。中断必须计算按下开关的次数。但是当按键被按下一次时,中断被调用了 2 或 3 次,因此计数更高。这里有什么问题?

我的中断代码在这里

ISR(INT1_vect){
    cli();  
    ++push_cntr1;printf("p1:%d,",push_cntr1);
    sei();  
}
ISR(INT0_vect){
    cli();
    ++push_cntr0;printf("p0:%d,",push_cntr0);
    sei();  
}
void interrupt_init(void)       //enable interrupt 0 and 1.
{   
    EICRA |= (1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10);
    EIFR = 0xFF;
    EIMSK |= (1<<INT1)|(1<<INT0);
    DDRD = 0x00;
}

int main(void)        //main program
{
    dev_init();
    while(1){
        process();
    }
    return 0;
} 

【问题讨论】:

    标签: interrupt avr


    【解决方案1】:

    您无需在中断处理程序中清除和设置 i 位。它将由编译器处理。

    至于多次点击,您可能会遇到“开关弹跳”。网上有很多关于此的参考,但要点是开关电路中的电压不会简单地从 0 变为最大跳跃。这通常是由电触点的实际物理弹跳引起的。

    有许多技术可用于“去抖动”开关。您可以尝试一些简单的方法,例如记录 tcnt 并在前一个中断之后过早忽略中断。

    【讨论】:

    • 我没有指定上拉或下拉,所以内部上拉寄存器未连接是否也会导致这种行为?我们是否需要使用 PORTD 引脚设置内部上拉/下拉寄存器?
    • 是的,您不应该让引脚悬空。将引脚设置为上拉或下拉,与开关闭合时相反。
    【解决方案2】:

    我能想到您可能遇到的两个问题。如前所述,您可能想尝试“去抖动”您的输入信号。

    您可能还想检查您的外部输入是否浮动;也就是说,您的输入是否连接了上拉或下拉电阻,允许在没有信号时分别将信号拉高或拉低?如果不是,您的输入是浮动的。

    添加上拉或下拉电阻可以消除随机噪声影响信号的大部分可能性。去抖动消除了由实际输入本身多次触发您的微控制器引起的错误。

    这是一个去抖动的例子:

    让我们以一个简单的瞬时开关为例。当开关第一次闭合时,信号不会干净地从 OFF 变为 ON。信号会在非常、非常短的时间内稳定下来。

    ** 参考来自示波器的这张非常有趣的图片,大致展示了机械开关在首次闭合时的行为:

    https://a.pololu-files.com/picture/0J790.600.jpg?c2e19ae7a5387b0870b4dbacf5cb7055

    如果您考虑微控制器如何解释此信号,它会在一切稳定之前看到多个尖峰。这些峰值是完全不可预测的,因此我们需要想出一个变通办法。

    解决方案: 去抖动。

    有很多复杂的算法用于硬件去抖动,但是您可以按照一个简单的过程来创建自己的去抖动函数。

    1. 检测到中断,记录输入值
    2. 等待(初学者尝试 10-20us)
    3. 再次检查输入。
    4. 之前记录的输入值是否与当前输入值相同?如果是,则信号已稳定:注册成功读取。如果信号不同,则您已检测到噪声。等待下一个中断,什么也不注册。

    这是一个非常基本的去抖动,但是随着它们变得更高级,方法并没有太大变化。

    我希望这有助于回答您的问题。

    【讨论】:

      猜你喜欢
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      • 2015-04-07
      相关资源
      最近更新 更多