//EX6AVR ATmega8A 16位定时器TC1CTC-模式4//author:QI小米粥//data:2018.3.15#include#includechar a=0;
void init(void)
{
DDRB |=0X16;//oca,ocb设置位输出
PORTB &=~0X16;//初始是低电平
TCCR1A |=0X50;//输出模式位反转
TCCR1A &=~0XA0;
TCCR1A &=~0X03;//选择工作模式4
TCCR1B |=BIT(3);
TCCR1B &=~BIT(4);
TCCR1B &=~BIT(2);//tc1频率8M/256=31250Hz
TCCR1B |=0x03;
OCR1A=0XF000;//设置top值
OCR1B=0X8000;//设置OCR1B的匹配中断值
TCNT1=0X0000;//设置初始的计数器值
SREG |=BIT(7);//全局中断打开
TIMSK |=BIT(4);//0ca中断打开
TIMSK |=BIT(3);//OCB中断打开
}
#pragma interrupt_handler oca:7
void oca(void)
{
unsigned int b,c;
b=0;
c=0;
switch (a)
{
case 0:
OCR1B=0XC000;a=1;break;
case 1:
OCR1B=0X0000;a=2;break;
case 2:
OCR1B=0x4000;a=3;break;
case 3:
OCR1B=0x8000;a=0;break;
default :a=0;break;
}
//OCR1B +=0X4000;
//这条语句可以代替整个的SWITCH语句,
//实现了匹配中断B的不断的减小,由于是以A为周期的所以计算
//所以时刻应该在每一个oca中断匹配的时刻作为ocb计时的时刻
//另外需要注意的是0xc000-0x000的顺序和波形也有很大的关系。
//这也是为什么switch语句里面的的顺序很乱的原因
if(PORTB&BIT(4))
{PORTB &= ~BIT(4);}
else
{PORTB |=BIT(4);}
}
#pragma interrupt_handler ocb:8
void ocb(void)
{
}
void main(void)
{
init();
}
网友评论