//EX10AVR ATmega8A 16位定时器TC1 pwm phase correct modle-模式1、2、3//author:QI小米粥//data:2018.3.16#include#includechar a=0;
char b=0;
void init(void)
{
DDRB |=0X06;//oca,ocb设置位输出
PORTB &=~0X06;//初始是低电平
TCCR1A |=0XF0;//匹配的时候反转,也就是 non-inverting mode
TCCR1A |=BIT(0);//选择工作模式1//top值固定为0XFF
TCCR1A &=~BIT(1);
TCCR1B &=~BIT(3);
TCCR1B &=~BIT(4);
/*
TCCR1A &=~BIT(0);//选择工作模式2//top值固定为0X1FF
TCCR1A |=BIT(1);
TCCR1B &=~BIT(3);
TCCR1B &=~BIT(4);
*/
/*
TCCR1A |=BIT(0);//选择工作模式3//top值固定为0X3FF
TCCR1A |=BIT(1);
TCCR1B &=~BIT(3);
TCCR1B &=~BIT(4);
*/
TCCR1B &=~BIT(1);//tc1频率1M/1024=1024Hz
TCCR1B |=0x05;
OCR1A=0X001F;
OCR1B=0X001F;
//ICR1=0X1FF;
//TCNT1=0X0000;//在这个模式下是自动循环的不需要对计数器进行写操作,因此不要写否则会出错。
SREG |=BIT(7);//全局中断打开
TIMSK |=BIT(4);//0ca中断打开
TIMSK |=BIT(3);//OCB中断打开
TIMSK |=BIT(2);//溢出中断打开
}
//把程序放在溢出中断,一个周期内有一次中断的机会,所以一次匹配一次更新
//把程序放在匹配中断,一个周期有两次中断,但是只有在top的时候更新,两次匹配一次更新
#pragma interrupt_handler oca:7
void oca(void)
{
/*if(a==0)
{
if(OCR1A==0X00DF)
{
a=1;
}
else
{
OCR1A +=0X0020;
}
}
if(a==1)
{
if(OCR1A==0X001F)
{
a=0;
}
else
{
OCR1A -=0X0020;
}
}
*/
}
#pragma interrupt_handler ocb:8
void ocb(void)
{
/*if(b==0)
{
if(OCR1B==0X00DF)
{
b=1;
}
else
{
OCR1B +=0X0020;
}
}
if(b==1)
{
if(OCR1B==0X001F)
{
b=0;
}
else
{
OCR1B -=0X0020;
}
}*/
}
#pragma interrupt_handler over:9
void over(void) //把程序放在这里,一个周期内有一次中断的机会
{
if(a==0)
{
if(OCR1A==0X00DF)
{
a=1;
}
else
{
OCR1A +=0X0020;
}
}
if(a==1)
{
if(OCR1A==0X001F)
{
a=0;
}
else
{
OCR1A -=0X0020;
}
}
if(b==0)
{
if(OCR1B==0X00DF)
{
b=1;
}
else
{
OCR1B +=0X0020;
}
}
if(b==1)
{
if(OCR1B==0X001F)
{
b=0;
}
else
{
OCR1B -=0X0020;
}
}
}
void main(void)
{
init();
}
网友评论