当向int0提供5v输入时,应发生外部中断向量。 中断应改变易失性整数标志,以允许LED点亮连接到PORTB上的引脚。在Atmel工作室编译没有错误。问题是当向int0引脚发送5v电源时不会发生变化。这是中断没有触发吗?
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
volatile int pwm_flag=0;
int main(void)
{
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)|(1 << ISC10); // set INT0 to trigger on Rising edge
EIMSK |= (1 << INT0); // Turns on INT0
sei(); // turn on interrupts
DDRB = 0xFF;
PORTB = 0x00;
while(1)
{
if(pwm_flag==1)//if flag is raised
{
PORTB = 0xFF;//turn on all pins of portb
pwm_flag=0;//reset flag to 0
}
}
}
ISR (INT0_vect)
{
/* interrupt code here */
pwm_flag =1;//raise flag
}
答案 0 :(得分:1)
问题是当5v电源发送到int0引脚时没有发生变化。
如何将5V送到INT0引脚?您的代码将INT0引脚设置为输入带上拉,所以除非您将它短接到地它处于5V 。
另外,你是什么意思没有发生变化? LED是打开还是关闭?
另一件事是该行:
EICRA |= (1 << ISC00)|(1 << ISC10);
将INT0和INT1设置为在相应引脚上的任何逻辑更改时发生。 名称为ISC0x控制INT0的位,名为ISC1x的位用于配置INT1。在您的代码中混合两者,最终得到以下配置:
ISC01 | ISC00 | meaning
-------------------------------------------------------------------------
0 | 1 | any logical change on INT0 generates an interrupt request
ISC11 | ISC10 | meaning
-------------------------------------------------------------------------
0 | 1 | any logical change on INT1 generates an interrupt request
答案 1 :(得分:0)
如果您尝试从PORTB上的引脚向LED提供5v,那么这可能就是您的问题。大多数微控制器引脚可以吸收比它们给出的电流更多的电流。也许你的LED没有得到它需要的电流?
您的接线应如下: 将LED的正极连接到5V。将负极连接到100-500欧姆的小电阻。将电阻的另一脚连接到PORTB上的引脚。
现在您可以将PORTB写入0x00以打开LED或0xFF以将其关闭。
要测试LED是否正常工作,请将PORTB写入低电平和高电平,测试主回路中的LED,并在两者之间有明显的延迟。
如果有效。然后测试你的ISR。如果ISR在这一点上不起作用,那么ISR就是问题所在。
请记住,在当前的EICRA配置中,您将在上升沿触发中断。因此,如果引脚已经为高电平,则不会发生中断。
我已经更改了下面的代码,因此LOW为ON,HIGH为OFF。
int main(void){
DDRD &= ~(1 << DDD2); // set PD2 DDR as input
PORTD |= (1 << PORTD2); // set PD2 as input pull-up
EICRA |= (1 << ISC00)|(1 << ISC10); // set INT0 to trigger on rising edge
EIMSK |= (1 << INT0); // Turns on INT0
DDRB = 0xFF; // set PORTB as all outputs
PORTB = 0xFF; // set PORTB high
sei(); // turn on interrupts
while(1){
if(pwm_flag!=0){ // check flag
PORTB = 0x00; // set PORTB low
pwm_flag=0; // reset flag
}
}
ISR (INT0_vect){
pwm_flag = 1; // raise flag
}