基于avr atmega16单片机定时器的 pwm调宽调占空比以及调频率
- 前言
最近写avr时候发现网上教程太少,本着为各位的学习提供帮助的心理,把自己写的程序发出来,一起探讨学习,希望我们共同努力,为梦想奋斗。本程序主要用于实现以下功能,这个程序最大的难点就在于pwm调宽,只要pwm调宽成功,基本这个程序就没有什么问题了。
2.问题
遇到的问题:
1,最开始的时候我找认为2个pwm波用一个定时器1就可以实现,后面仔细阅读数据手册,我认为要两个定时器才能完成,并且其中一个必须是定时器1,因为定时器一可以产生多样化频率,而定时器0,2只能固定几种频率.
2,要让定时器输出pwm波,一定要初始化端口为输出.
3,注意使用定时器1进行频率调节时,对ICR1的初始化不能太靠后,因为ICR1不是双缓冲寄存器.
3.程序
/*
- 试题1.c
- k1-k8 pc0-pc7
- a-dp pb0-pb7
- pd5输出1k及4HZ pd7输出124HZ
- Created: 2020/3/23 9:04:03
- Author : zjlc
*/
#include <avr/io.h>
#include <util/delay.h>
char number[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
char bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
float percent[]={0,0.85,0.75,0.5,0.4,0.15,0.7,0.5,0.25};
int i;
void begin()
{
PORTB=number[0];
DDRB=0xff;
PORTD=0xff;
DDRD=0xff;
PORTC=0xff;
DDRC=0x00;
}
void frequency(int temporary)
{
TCCR2=0x1e;//124HZ
TCNT2=0;
OCR2=12;
if(temporary==0)//1K
{
TCCR1A=0xf2;
TCCR1B=0x19;
ICR1=11059;
TCNT1=0;
}
else if (temporary==1)//4hz
{
TCCR1A=0xf2;
TCCR1B=0x1C;
ICR1=10800;
TCNT1=0;
}
}
void show()
{
for (i=0;i<8;i++)
{
if (PINC&bit[i]);
else
{
_delay_ms(10);
if (PINC&bit[i])
{
continue;
}
else
{
PORTB=number[i+1];
while(PINC&bit[i]);
if(i>4)
{
frequency(1);
OCR1A=10800*percent[i+1];
}
else
{
frequency(0);
OCR1A=11059*percent[i+1];
}
break;
}
}
}
}
int main(void)
{
begin();
while(1)
show();
}