2016-02-17 60 views
2

当一个5v输入提供给int0时,应该发生一个外部中断向量。 中断应更改一个易失性整数标志,以允许指示灯连接到PORTB上的某个引脚。在Atmel工作室中编译没有错误。当5v电源发送到int0引脚时,问题不会发生变化。这是中断不触发吗?ATMEGA328P外部中断avr gcc不会发生

#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 
    } 

回答

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 
0

如果你试图从PORTB引脚提供5V电源的LED那么也许这是你的问题。大多数微控制器引脚可以吸收比他们所能提供的更多的电流。也许你的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 
} 
+0

AVR可以为LED提供充足的电流。 – JimmyB

+0

对于一个小的是的,但我仍然认为最好的做法是沉入电流而不是提供电流。 – DeeCee

+0

这是个人偏好还是一般性建议? - 尽管如此,AVR的数据表显示“端口B输出缓冲器具有对称的驱动特性,同时具有高吸收和源功能。”所以在这方面没有太多的错误要做。 – JimmyB