在 ISR 结束时使用 reti()
Using reti() at the end of an ISR
我有这个代码不起作用的问题..
ISR 正在工作..我在其他代码中测试了它的闪烁..
但是将 x++ 放入 ISR 并在 main() 函数中读取 X 它永远不会闪烁。 ..
我不熟悉 asm 我认为这是编译器优化,所以我把变量 volatile 但它没有工作..
#define F_CPU 16000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
volatile static uint8_t x = 1;
ISR( TIMER0_OVF_vect )
{
x++;
reti();
}
int main(void)
{
/* Replace with your application code */
DDRB = DDRB | 0B00100000 ; // pinMode(13,OUTPUT);
TCCR0A = 0;
TCCR0B = (1 << CS00 ) | (1 << CS02 ); //1024 prescaler
TIMSK0 |= 1 << TOIE0 ;
sei();
while (1)
{
if (x >= 61) //never happens ?
{
PORTB ^= 0B00100000;
x=0;
}
}
}
对于普通的 ISR,您的编译器会生成一些 "boilerplate" 代码,例如包括保存和恢复 CPU 寄存器,并将您自己编写的代码包围在 ISR 主体中。声明 ISR "naked".
时不会发生这种情况
在您的代码中,ISR 不是裸露的,此样板代码存在,但您仍然使用 reti()
,这会立即离开 ISR。因此,您的 ISR 将执行 "prologue" 部分,但不会执行 "epilogue" 部分,这可能会导致各种问题,例如弄乱寄存器内容。
顺便说一句,结语样板文件中的最后一条指令无论如何都是 reti
。仅在编写裸 ISR 时才使用 reti()
。
我有这个代码不起作用的问题.. ISR 正在工作..我在其他代码中测试了它的闪烁..
但是将 x++ 放入 ISR 并在 main() 函数中读取 X 它永远不会闪烁。 ..
我不熟悉 asm 我认为这是编译器优化,所以我把变量 volatile 但它没有工作..
#define F_CPU 16000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
volatile static uint8_t x = 1;
ISR( TIMER0_OVF_vect )
{
x++;
reti();
}
int main(void)
{
/* Replace with your application code */
DDRB = DDRB | 0B00100000 ; // pinMode(13,OUTPUT);
TCCR0A = 0;
TCCR0B = (1 << CS00 ) | (1 << CS02 ); //1024 prescaler
TIMSK0 |= 1 << TOIE0 ;
sei();
while (1)
{
if (x >= 61) //never happens ?
{
PORTB ^= 0B00100000;
x=0;
}
}
}
对于普通的 ISR,您的编译器会生成一些 "boilerplate" 代码,例如包括保存和恢复 CPU 寄存器,并将您自己编写的代码包围在 ISR 主体中。声明 ISR "naked".
时不会发生这种情况在您的代码中,ISR 不是裸露的,此样板代码存在,但您仍然使用 reti()
,这会立即离开 ISR。因此,您的 ISR 将执行 "prologue" 部分,但不会执行 "epilogue" 部分,这可能会导致各种问题,例如弄乱寄存器内容。
顺便说一句,结语样板文件中的最后一条指令无论如何都是 reti
。仅在编写裸 ISR 时才使用 reti()
。