|
PWM调速C程序编写 |
|
|
PWM调速C程序编写
使用定时计数器编写
/
用1个定时器的话就要用一个变量count1来控制周期和占空比了,
比如设置1周期为10ms,占空比为20%的PWM,
可以设置定时器为每10us产生一次中断,每中断一次使count加1,
一开始设置PA0为高电平,当count1加到200的时候拉低PA0,
等count1到1000了在拉高PA0,同时复位count1=0,
不过这样做的缺点是精度不高,要是PWM所需周期段,精度高的话还是用两个定时器来实
现;
/
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharPWM_PA0=PA0;
uintcount=0;
voidport_init(void)
{
PORTA|=(1< DDRA|=(1< }
voidtimer0_init(void)
{
SREG=0x80;
TIMSK|=(1< TCCR0|=(0<
TCNT0=0x91;
}
voidmain(void)
{
port_init();
timer0_init();
while(1);
}
#pragmavector=TIMER0_OVF_vect
__interruptvoidTIMER0_OVF(void)
{
TCNT0=0x91;
if(count++>=200)
{
PWM_PA0=0;
}
if(count++<=1000)
{
PWM_PA0=1;
count=0;
}
}
/
通过定时器模拟!可以通过两个定时器,T0控制周期,T1控制占空比。
例如:实现周期为1000us,占空比为20%的PWM,用PA0实现
首先设置T0为83(11.0592M晶振)
T1为65501
首先初始化PA0=1,两个定时器同时打开,在定时器T1中断时拉低PA0,
在定时器T0中断时在拉高PA0,同时将两定时器初始值初始化T0为83,T1为65501
定时器初值=2d的N次方-(时钟频率/分频系数)T
/
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharPWM_PA0=PA0;
voidport_init(void)
{
PORTA|=(1< DDRA|=(1< }
voidtimer_init(void)
{
TCCR0|=(0<
TCCR1A|=0x00;
TCCR1B|=(0< TIMSK|=(1<
TCNT0=0x53;
TCNT1H=0xff;
TCNT1L=0xdd;
}
/
voidtimer1_init(void)
{
}/
voidmain(void)
{
port_init();
timer_init();
//timer1_init();
SREG=0x80;
while(1);
}
#pragmavector=TIMER0_OVF_vect
__interruptvoidTIMER0_OVF(void)
{
PWM_PA0=1;
TCNT0=0x53;
}
#pragmavector=TIMER1_OVF_vect
__interruptvoidTIMER1_OVF(void)
{
PWM_PA0=0;
TCNT1H=0xff;
TCNT1L=0xdd;
}
/
使用I/O口输出PWM波形你必须首先明白PWM他的实质是:
调制占空比,占空比就是波形中高电平的长度与整个波长的比值。
我们写C语言的目的是写PWM波形的一个周期。在这个周期内高低电平的比值是可以改变
的。
这也就符合了PWM的原意脉宽调制。即高电平的宽度的调制。
/
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharPWM_PA0=PA0;
voidport_init(void)
{
PORTA|=(1< DDRA|=(1< }
voidpwm(ucharx,uinty)//X为占空比Y为函数使用时间
{
uinti,j,a,b;
for(i=y;i>0;i--)//定时外函数
{
for(j=9;j>0;j--)//定时内函数
{
for(a=y;a>0;a--)//PWM波高电平宽度
{
PWM_PA0|=(1< }
for(b=100-y;b>0;b--)//PWM低电平宽度
{
PWM_PA0|=(0< }
}
}
}
voidmain(void)
{
port_init();
while(1)
{
pwm(20,128);
}
}
|
|
|
|
|
|
|
|
|
|
|