本人在EWAVR中写了段测试程序,但关于延时过程中的中断问题有些不解:
如果没有延时程序,测试板,灯近似一直亮。
加入延时程序,可以看见灯运行的过程。
问题是延时过程中会不会产生中断,为什么会出现上述情况.
中断调用子函数都完成了,标志位应该清除了,为何还会出现这个情况
?#include
unsigned int flag;
/*在T0的CTC模式中比较和溢出都会产生中断
为了便于观察,这里加入定时延时函数 */
void delay(void)
{
unsigned char x,y;
x=255;
y=255;
while(x--)
{
while(y--);
}
}
void timer0_init(void)
{
//CTC mode ,TOS/32,compare equ reverse
TCCR0=(1<
//SET TOP=1000,000/(2*32*100)=156.25
OCR0=0x9c;
}
#pragma vector = TIMER0_COMP_vect
__interrupt void time0_isr1(void){
flag++;
// asm("CLI");
}
/*#pragma vector = TIMER0_OVF_vect
__interrupt void time0_isr2(void){
flag++;
asm("CLI");
}*/
unsigned char k;
void main(void)
{
DDRD=0xff;
PORTD=0x0f;
asm("nop");//同步,一个时钟
PORTD=0xf0;
asm("sei");
TIMSK=(1<
k=1;
while(1)
{
if(((flag%3)==0))
{
k<<=1;
PORTD =k;
if(k==0) k=1;
}
delay();
// asm("sei");
}
}
延时过程(函数)肯定会产生中断,前提是你开启了中断。灯近似一直亮是因为灯变化太快而人眼反映不够快,加入延时后等于把灯的变化放缓,人眼自然能看清。
1.如果没有延时程序,测试板,灯近似一直亮。因为你的定时器很块,很快就使flag增加3。而且while(1)程序一直检测flag值,并更改你的LED状态。
2.加入延时程序,可以看见灯运行的过程。在while(1)下,每次改变LED状态,进入delay()后,并不是屏蔽了中断,定时器中断照常发送,也就是flag的值正常递增,但是递增了flag之后,并不是去重新检测flag值,更不用谈更改LED的状态了,而是返回delay(),继续完成未完成的delay。
3.问题是延时过程中会不会产生中断,为什么会出现上述情况. 延时过程中,你没屏蔽中断,肯定会产生中断。出现这种情况的原因,因为,见2解释。
假如楼主你的flag值的判断也放在定时器中断中,而且同时更新LED状态,那么这个delay对你的效果来说,就肯定不起作用了。
帮你顶,
不用中断的时候关掉,
用的时候再开启中断就可以了,
在写大的工程的时候,
一定要小心中断,
不用的时候一定要关闭,
用的时候再开启,
中断的优先级不同,会造成程序bug,初学者应该养成好习惯,用的时候开,不用的时候关
我一般都做成这样:
定时中断时置timer_f,狗在此置为保证定时中断一直有且中断时间短
void led(void)
{
if(timer_f)
{
ijk++;
timer_f=0;
if (ijk>500)
{
if(PORTB&0x4)PORTB&=~0x4;
else PORTB|=0x4;
ijk=0;
#asm("WDR");
}
}
}