0

以下是按下 PD2 时启用中断 INT0_vect 的代码。该代码从不执行 ISR,但始终在 main 函数的 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);
                }
            }
        }

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

4

1 回答 1

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);
    }
}
于 2019-12-06T20:27:58.880 回答