设置标志在我的定时器中断中不起作用(当中断工作时)
Setting a flag does not work in my timer Interrupt (while the Interrupt is working)
我曾经在 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);
}
}
}
有人能帮帮我吗?
编译器在程序开始时看到 flag
设置为 0,并且不知道该变量可以通过中断处理程序更改(代码从未在程序中直接调用)。
所以它优化了 flag
签入 while
循环。
对从不同代码流(主代码和中断处理程序,多线程环境中的不同线程)访问的变量使用 volatile
限定符。
volatile unsigned char flag = 0;
我曾经在 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);
}
}
}
有人能帮帮我吗?
编译器在程序开始时看到 flag
设置为 0,并且不知道该变量可以通过中断处理程序更改(代码从未在程序中直接调用)。
所以它优化了 flag
签入 while
循环。
对从不同代码流(主代码和中断处理程序,多线程环境中的不同线程)访问的变量使用 volatile
限定符。
volatile unsigned char flag = 0;