最近,我试图使用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;
}
}
我多次浏览了数据表,最终在网上偶然发现了这段代码(是的,我知道我是真正的作品),并添加了自己的作品。 但这甚至不起作用,有人知道为什么吗?
答案 0 :(得分:1)
您的代码中可能存在一些问题:
if
条件中的分配。显然,另一个是ISR中也提到的serial.print内容。
ISR应该尽可能简短。
另一个是硬件。如果您按一个按钮,它们会弹起,通常会产生多次中断。因此,请寻找一些反跳代码,或者在arduino库中查找(如果有的话)。您可能必须更改代码,因为通常硬件逻辑本身是在中断中处理的,但是按钮状态的实际测试应属于主代码。
高级内容-如果您当前正在阅读教程并自学,请忽略此内容,但对于实际项目可能要牢记
另一个问题是程序设计:您的处理器现在无法执行其他任何操作,而是切换LED,因为他的主程序流程正在等待。
通常,您将需要使用硬件计时器来执行此类任务。
可以将其用作时基,通过易失性标志变量将传递的间隔信号通知主系统。或直接使用PWM功能通过输出比较引脚之一(OC [012] [AB])直接连接LED。