ISR_INT0_PD2无法正常工作,但主要功能无限地工作于ATMEGA32

时间:2019-12-06 20:14:43

标签: c microcontroller interrupt atmega32

以下是在按下PD2时启用中断INT0_vect的代码。该代码永远不会执行ISR,但始终会在主函数的PORT C的7段中执行从0到9的计数器循环。还尝试了sei();而不是在SREG中启用I位。有什么想法吗?


        #include <avr/io.h>
        #include <avr/interrupt.h>
        #include <util/delay.h>

        #define    ISR_INT0_PD2    INT0_vect  

        ISR( ISR_INT0_PD2 ){
            PORTC = 0x00;
           _delay_ms(100);
        }
        int main(void)
        {
            int i=0;
            DDRC=0xff;          //portc is o/p
            PORTC=0x00;         // all pins on portc is 0 volt
            MCUCR |= (1<<1);   // falling edge
            GICR |=(1<<6);     // enable INT0 set pin6
            SREG |=(1<<7);     // set GIE pin7
            while(1)
            {
                for(i=0;i<10;i++)
                {
                    PORTC=i;
                    _delay_ms(1000);
                }
            }
        }

[下面是我一直在使用的模拟器的屏幕截图]

1 个答案:

答案 0 :(得分:2)

要执行中断,您需要调用sei()中定义的<avr/interrupt.h>

https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#gaad5ebd34cb344c26ac87594f79b06b73

编辑:当我根据相当于SREG |= (1 << 7)的链接删除了行sei();时,我错了。写完下面的示例后,我意识到寄存器在ATMega32上的命名是不同的,因此很遗憾下面的代码无法运行。

根据ATMega32的数据表,您的代码应该可以工作,是否尝试过删除for循环并将PORTC驱动为逻辑高电平(例如PORTC = 255)?我在编写ATMega168的代码时注意到,我使用的LED与while循环中的代码非常暗淡。另外,还要检查INT0引脚是否通过上拉/下拉电阻连接。

这是在我的ATMega168上运行的代码,如果我将寄存器名称交换为在ATMega32上使用的寄存器名称,则最终得到您的代码:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define    ISR_INT0_PD2    INT0_vect  

ISR( ISR_INT0_PD2 ){
    // If there is a logic change on any pin hold the pins attached to PORTC low for 100ms.
    PORTC = 0;
    _delay_ms(100);
    // Relase PORTC to logic high.
    PORTC = 255;
}

int main(void)
{
    DDRC = 255;            // Set all pins on PORTC to be outputs.
    PORTC= 255;            // Set all pins on PORTC to be logic high.

    EIMSK = 0b00000001;    // Set external interupt request enable.

    EICRA = 0b00000001;    // Set the external interrupt control register A to so that 
                           // any logical change on INT0 generates an interrupt request.

    sei();                 // Set global interupts enable.

    while(1)
    {
        PORTC=255;         // Blink the entire PORTC bank.
        _delay_ms(20);
        PORTC=0;
        _delay_ms(20);
    }
}