|
我设置ATmega16的定时器0,2都工作在CTC模式,单独用定时器0或者单独用定时器2都没有问题,但是一起工作时只有一个能正常工作,详细说明如下:
硬件连线:PINC2 -- +LED1- --PINC3
PINC2 -- +LED2- --PINC7
PINC2连LED1,LED2的正极,LED1的负极连PINC3,LED2的负极连PINC7
预期程序功能:Timer0匹配中断后控制PINC7取反,LED2闪烁
Timer2匹配中断后控制PINC3取反,LED1闪烁
实际效果:在主程序中初始化Timer0,不初始化Timer2,LED2闪烁
在主程序中初始化Timer2,不初始化Timer0,LED1闪烁
在主程序中先初始化Timer0,再初始化Timer2,LED1闪烁,LED2灭
在主程序中先初始化Timer2,再初始化Timer0,LED2闪烁,LED1灭
程序:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//M16 at 12MHz
#define SET_BIT(io ,bit) ( io |= (1<<bit) )
#define CLR_BIT(io ,bit) ( io &= ~(1<<bit) )
#define GET_BIT(pin,bit) ( pin & (1<<bit) )
#define SET_IN( dir,bit) ( dir &= ~(1<<bit) )
#define SET_OUT(dir,bit) ( dir |= (1<<bit) )
unsigned char flag0 = 0;
unsigned char flag2 = 0;
void Timer0Init (void)
{
TCCR0 = _BV(CS02)|_BV(CS00)|_BV(WGM00)|_BV(WGM01);
OCR0 = 200;
TIMSK = _BV(OCIE0);
}
void Timer2Init (void)
{
TCCR2 = _BV(WGM21)|_BV(CS22)|_BV(CS21)|_BV(CS20);
OCR2 = 200;
TIMSK = _BV(OCIE2);
}
SIGNAL(SIG_OUTPUT_COMPARE2)
{
if (flag2 == 0)
{SET_BIT(PORTC,3);flag2=1;}
else
{CLR_BIT(PORTC,3);flag2=0;}
}
SIGNAL(SIG_OUTPUT_COMPARE0)
{
sei();
//这里“sei();”加与不加是一样的
if (flag0 == 0)
{SET_BIT(PORTC,7);flag0=1;}
else
{CLR_BIT(PORTC,7);flag0=0;}
}
int main(void)
{
SET_OUT(DDRC,2);//设置输出
SET_OUT(DDRC,3);
SET_OUT(DDRC,7);
SET_BIT(PORTC,2);//初始LED1,2灭
SET_BIT(PORTC,3);
SET_BIT(PORTC,7);
Timer0Init ();//这两句前后顺序有影响
Timer2Init ();//
sei();
while(1);
}
我用的编译器是站内下载的WinAVR-20060421
思考:如果Timer0在中断程序中,Timer2中断发生,AVR的中断有优先级,Timer2匹配中断比Timer0匹配中断优先级高,在Timer0中断程序中加入“sei()”,但是看上去效果还是一样的;如果程序在一个中断A(指这里的Timer0或Timer2中断)处理过程中,另一个中断B(指这里的Timer0或Timer2中断)发生了,那也会在A中断处理完之后处理B中断了啊。。。
找了很久没有找到原因,也没搜到相关的讨论,只好发帖求救了。。。 |
|