【发布时间】:2019-04-29 07:50:00
【问题描述】:
我最近尝试使用 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;
}
}
我多次浏览数据表,最终在网上偶然发现了这段代码(是的,我知道我是一个真正的作品)并将我自己的部分添加到其中。 但即使这样也不起作用,有人知道为什么吗?
【问题讨论】:
-
if(t=1)启用/读取编译器警告。没有办法用 gcc 干净地编译。此外,从 ISR 内部删除打印,切换引脚或其他东西。 -
如果在数字输入上启用上拉,则必须通过按钮将其连接到 GND,而不是 5V。
-
在中断中调用像
Serial.println这样的库函数是非常危险的并且不太可能工作,除非库被设计为从这样的中断中调用。例如,println函数可能会在一个循环中等待所有要发送的字节,但它们无法发送,因为 USART 中断发送它们并且一次只能发生一个中断。我建议在您的中断中写入volatile变量并返回。您的主循环可以检查变量的值,并在检测到 ISR 写入后将其改回。
标签: c interrupt avr arduino-uno atmega