AVR C为什么不会中断?

时间:2018-11-27 14:28:40

标签: c interrupt avr arduino-uno atmega

最近,我试图使用atmelstudio在atmega328p上进行中断,以使连接到Digitalpin 13 / PB5 / PCINT5的LED闪烁的速度比连接到5V输出和digitalpin 2的按钮的正常闪烁速度快四倍/ PD0 / PCINT18按下。

但是只要我运行代码并按一下按钮,它就永远不会(据我所知)变为真实的中断代码。

#include <avr/io.h>
#include <avr/interrupt.h>

volatile int t = 1;
int main(void)
{
    init();
    Serial.begin(9600);
    DDRB = (1 << 5);
    DDRD &= ~(1 << DDD2);     // Clear the PD2 pin
    // PD2 (PCINT0 pin) is now an input

    PORTD |= (1 << PORTD2);    // turn On the Pull-up
    // PD2 is now an input with pull-up enabled



    EICRA |= (1 << ISC00);    // set INT0 to trigger on ANY logic change
    EIMSK |= (1 << INT0);     // Turns on INT0

    sei();                    // turn on interrupts
    Serial.println("loop started");

    while(1)
    {
        PORTB ^= (1 << 5);
        delay(500*t);
    }
}



ISR (INT0_vect)
{
    Serial.println("interrupt");
    if(t=1){
        t=4;
    }
    else{
        t=1;
    }
}

我多次浏览了数据表,最终在网上偶然发现了这段代码(是的,我知道我是真正的作品),并添加了自己的作品。 但这甚至不起作用,有人知道为什么吗?

1 个答案:

答案 0 :(得分:1)

您的代码中可能存在一些问题:

  1. 最重要的是注释中已经提到的if条件中的分配。
  2. 显然,另一个是ISR中也提到的serial.print内容。
    ISR应该尽可能简短。

  3. 另一个是硬件。如果您按一个按钮,它们会弹起,通常会产生多次中断。因此,请寻找一些反跳代码,或者在arduino库中查找(如果有的话)。您可能必须更改代码,因为通常硬件逻辑本身是在中断中处理的,但是按钮状态的实际测试应属于主代码。

  4. 高级内容-如果您当前正在阅读教程并自学,请忽略此内容,但对于实际项目可能要牢记
    另一个问题是程序设计:您的处理器现在无法执行其他任何操作,而是切换LED,因为他的主程序流程正在等待。
    通常,您将需要使用硬件计时器来执行此类任务。 可以将其用作时基,通过易失性标志变量将传递的间隔信号通知主系统。或直接使用PWM功能通过输出比较引脚之一(OC [012] [AB])直接连接LED。