C 在ISR结束时使用reti()
我有一个问题,这个代码不起作用。。 ISR正在工作。。我在其他代码中测试了它的闪烁 但要将x++放入ISR并在main()函数中读取x,它从不闪烁 我不熟悉asm,我认为这是编译器优化,所以我把变量放在volatile中,但它不起作用C 在ISR结束时使用reti(),c,microcontroller,avr,atmelstudio,isr,C,Microcontroller,Avr,Atmelstudio,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
#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;
}
}
}
#定义F#U CPU 1600000UL
#包括
#包括
#包括
挥发性静态uint8_t x=1;
ISR(计时器0 OVF vect)
{
x++;
reti();
}
内部主(空)
{
/*替换为您的应用程序代码*/
DDRB=DDRB | 0B00100000;//pinMode(13,输出);
TCCR0A=0;
TCCR0B=(1对于普通ISR,编译器会生成一些“样板”代码,例如,包括保存和恢复CPU寄存器,并围绕您在ISR正文中编写的代码。当您声明ISR为“裸”时,不会发生这种情况
正如在您的代码中一样,ISR不是赤裸裸的,这个样板代码是存在的,但是您仍然使用reti()
,这会立即离开ISR。因此,您的ISR将执行“序言”部分,而不会执行“尾声”部分,这可能会导致各种问题,例如混淆寄存器内容
顺便说一句,尾声样板中的最后一条指令无论如何都是reti
。只有在编写裸ISR时才使用reti()包括保存和恢复CPU寄存器的代码,以及围绕您自己在ISR正文中编写的代码。当您声明您的ISR为“裸体”时,不会发生这种情况
正如在您的代码中一样,ISR不是赤裸裸的,这个样板代码是存在的,但是您仍然使用reti()
,这会立即离开ISR。因此,您的ISR将执行“序言”部分,而不会执行“尾声”部分,这可能会导致各种问题,例如混淆寄存器内容
顺便说一句,尾声样板中的最后一条指令无论如何都是reti
。只有在编写裸ISR时才使用reti()
。您不应该在ISR中调用reti()
,这只适用于“裸ISR”ISRs。这解决了问题,但我能知道原因吗?非标准关键字ISR
用于在机器代码中生成此指令。您不应该在ISR中调用reti()
,这仅用于“裸”指令ISRs。这解决了问题,但我能知道原因吗?非标准关键字ISR
用于在机器代码中生成此指令。