设置标志在我的计时器中断中不起作用(当中断正在工作时)

时间:2019-02-08 05:35:38

标签: timer interrupt avr avr-gcc atmelstudio

我曾经用ICCAVR编写代码,但在那里没有问题,但出于某种原因,我不应该迁移到AtmelStudio。 在下面的代码中,LED在中断中闪烁,但是当我仅在中断中设置一个标志并想在轮询中使用该标志闪烁该LED时,它将不起作用:

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

#define LED PA1


ISR (TIMER1_OVF_vect)    // Timer1 ISR
{
    //PORTA ^= (1 << LED);
    TCNT1 = 63974;   // for 1 sec at 16 MHz
    PORTA ^= (1 << LED);
}

int main()
{
    DDRA = (0x01 << LED);     //Configure the PORTD4 as output

    TCNT1 = 63974;   // for 1 sec at 16 MHz

    TCCR1A = 0x00;
    TCCR1B = (1<<CS10) | (1<<CS12);;  // Timer mode with 1024 prescler
    TIMSK = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)
    sei();        // Enable global interrupts by setting global interrupt enable bit in SREG

    while(1)
    {

    }
}

此更改将使其不闪烁:

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

#define LED PA1

unsigned int counter=0;
unsigned char flag=0;

ISR (TIMER1_OVF_vect)    // Timer1 ISR
{
    //PORTA ^= (1 << LED);
    TCNT1 = 63974;   // for 1 sec at 16 MHz
    counter++;
    if(counter>=10)
    {
        flag=1;
        counter=0;
    }
}

int main()
{
    DDRA = (0x01 << LED);     //Configure the PORTD4 as output

    TCNT1 = 63974;   // for 1 sec at 16 MHz

    TCCR1A = 0x00;
    TCCR1B = (1<<CS10) | (1<<CS12);;  // Timer mode with 1024 prescler
    TIMSK = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)
    sei();        // Enable global interrupts by setting global interrupt enable bit in SREG

    while(1)
    {
        if(flag)
        {
            flag=0;
            PORTA ^= (1 << LED);
        }
    }
}

有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

编译器发现flag在程序开始时设置为0,并且不知道该变量可以被中断处理程序更改(该代码从未在程序中直接调用过)。 因此,它优化了flag的{​​{1}}循环检入。

对从不同代码流(主代码和中断处理程序,多线程环境中的不同线程)访问的变量使用while限定符。

volatile