欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于avr atmega16单片机定时器的 pwm调宽调占空比以及调频率

程序员文章站 2022-06-09 10:50:30
...
  1. 前言

最近写avr时候发现网上教程太少,本着为各位的学习提供帮助的心理,把自己写的程序发出来,一起探讨学习,希望我们共同努力,为梦想奋斗。本程序主要用于实现以下功能,这个程序最大的难点就在于pwm调宽,只要pwm调宽成功,基本这个程序就没有什么问题了。

基于avr atmega16单片机定时器的 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();
}

相关标签: 单片机 avr