Установка флага не работает в моем таймере прерывания (пока работает прерывание) - PullRequest
0 голосов
/ 08 февраля 2019

Раньше я писал свои коды в ICCAVR, и у меня там не было проблем, но не по какой-то причине я должен перейти на AtmelStudio.в следующем коде светодиод мигает в прерывании, но когда я только устанавливаю флаг в прерывании и хочу мигать светодиодом при опросе (используя флаг), он не будет работать:

#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 голосов
/ 09 февраля 2019

Компилятор увидел, что flag установлен в 0 при запуске программы, и не может знать, что переменная может быть изменена обработчиком прерывания (код никогда не вызывался непосредственно в программе).Таким образом, она оптимизировала flag проверку в while цикле.

Использование volatile квалификатора для переменных, к которым обращались из разных потоков кода (основной код и обработчик прерываний, разные потоки в многопоточной среде).

volatile unsigned char flag = 0;
...