首页 > 解决方案 > AVR C 为什么不会中断?

问题描述

我最近尝试使用 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;
    }
}

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

标签: cinterruptavrarduino-unoatmega

解决方案


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

  1. 最重要的是if在评论中已经提到的条件下的分配。
  2. 显然另一个是 ISR 中也提到的 serial.print 东西。
    ISR 应尽可能简短。

  3. 另一个是硬件。如果您按下一个按钮,它们会弹跳并通常会产生多次中断。所以找一些去弹跳的代码或者看看 arduino 库,如果有的话。您可能需要更改代码,因为通常硬件逻辑本身是在中断中处理的,但按钮状态的实际测试应该属于主代码。

  4. 高级的东西 - 如果你目前正在阅读教程并自学 - 忽略这一点,但可能会在实际项目中记住
    另一个问题是程序设计:你的处理器现在除了切换 LED 之外不能做任何其他事情,因为他的主程序流程正在等待。
    通常,您会希望使用硬件计时器来执行此类任务。要么将其用作时间基准,即通过 volatile 标志变量向主函数发送间隔信号。或直接使用 PWM 功能通过输出比较引脚 (OC[012][AB]) 之一直接连接 LED。


推荐阅读