51单片机产生PWM方法
89C51芯片没有自带PWM发生器,如果要用51来产生PWM波就必须要用软件编程的方法来模拟。方法大概可以分为软件延时和定时器产生两种方法。下面将逐一介绍。
1 软件延时法
利用软件延时函数,控制电平持续的时间,达到模拟pwm的效果。
程序如下:
#include<reg52.h>sbit pwm=P1^0;main(){while(1){ pwm=1;delayus(60);//置高电平后延时60us,占空比60%pwm=0;delayus(40);}}void delayus(uint x){while(x--);}
proteus软件仿真结果如下:
可见,用这种延时函数的方法就能简单地模拟出pwm输出。但是这种方法的缺点也相当明显。当程序除了要输出pwm波还要执行其他操作比如键盘扫描、显示等操作时,需要占用CPU一定的机器周期,这样就会影响pwm的准确度。现在很少会用到这种方法,接下来要介绍的是比较常用的方法。
2 定时器产生pwm
这种方法利用了定时器溢出中断,在中断服务程序改变电平的高低,在程序较复杂、多操作时仍能输出较准确的pwm波形。
2.1 注意事项
2.2.1中断服务程序的内容。
一般来说中断服务程序只完成改变标志位、转换高低电平的功能,如果中断服务程序中有太多的操作会影响pwm波的输出,尤其是除法、取余、浮点数运算会占用大量的机器周期,应在中断外完成运算。2.2.2定时器装入初值的问题。
装入初值不能太接近于定时器的溢出值。如我们使用定时器方式1,最多能计65536个数,假设我们转入的初值为65534,那么定时器计两个数就会进入中断,这样会使程序紊乱而其他功能无法正常地执行,所以一般要留50-100个数的裕量。
2.2 定时器工作方式
在定时器工作方式的选择上,可以选择定时器的工作方式0、1、2都可以,本文采用的是工作方式1,即16位定时器,这样可以获得较宽的调频范围。
2.3 定时器初值的计算
设占空比为α,频率为f
产生高电平时装入定时器高8位的值应为
产生高电平时装入定时器低8位的值应为
显然,产生低电平时的公式只要把α换成(1-α)就行了。
然而在51单片机中,浮点数运算需要消耗cpu很长的时间,为了提高程序效率,通常用100倍的占空比来计算。同时,要注意数据类型,避免超出范围,影响计算结果。关于C51的乘除法问题,可以看以下这篇文章:http://blog.163.com/ssou_1985/blog/static/295320362010311102232210/
修改后的公式如下:a为100倍占空比,fr为0.01倍频率TH0 = (65535-a*100/fr)/256; //高位初值TL0 = (65535-a*100/fr)%256;同样,低电平的公式只需把a换成(100-a)即可。
2.4 例程
本例程采用定时器T0在工作方式1下产生一路PWM,用独立键盘控制频率、占空比的加减,频率可调范围100Hz-10kHz,占空比0-100%(均为理论值,实际值略低)部分代码如下:
注:T0_H , T0_L , T1_H , T1_L 均用于暂时存储初值,进入中断服务程序后直接给寄存器TH0、TL0赋值,避免了在中断中计算。
注:flag为pwm输出标志,flag=1输出高电平,flag=0输出低电平
2.5 软件仿真结果
2.5.1 频率为100Hz
a.占空比约15%
b.占空比95%
2.5.2 频率为10KHz
a.占空比15%
b.占空比90%
51单片机PWM控制LED的亮度仿真程序图谱 (附仿真文件+源代码)
51单片机PWM控制LED的亮度仿真程序图谱
因为项目比较简单,我就没有做实物,只是用了仿真来实现,大家最重要的是要弄懂原理。
原理:单片机输出PWM斩波,控制LED的亮度并在图谱上面显示出来
仿真开启
参考代码:
#include "reg51.h"
unsigned int cd,dd;
unsigned char cc,ee;
sbit LED=P2^0;
void led_int() interrupt 1 using 0
{
TH0=0xf1;
TL0=0xf1;
TR0=1;
dd++;
if(dd==11)
{
if((cc==0x50)&&(ee==0)){cd=0;}
if((cc==0)&&(ee==0x50)){cd=1;}
if(cd){cc++;ee--;}
else {cc--;ee++;}
dd=0;
}
}
void delay(unsigned int i)
{
unsigned int j;
while(i--)
{
for(j=0;j<0x20;j++);
}
}
void main()
{
cc=0;
ee=0x50;
TMOD=0x01;
TH0=0xf0;
TL0=0xf0 ;
EA=1;
ET0=1;
TR0=1;
while(1)
{
LED=0;
delay(ee);
LED=1;
delay(cc);
}
}
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 程序完整源代码和 设计文件,请在下方留言或者私信我,看到后会第一时间回复。
谢谢!
感谢你的阅读,希望您有所收获,喜欢请点赞评论加关注!
相关问答
单片机 有多少 PWM 输出的引脚 - 懂得不是哪,PWM简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。能够有PWM输出只是单片机的个别引脚,这些引脚能够配...
单片机PWM 调光原理?单片机PWM调光的原理:就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的...
单片机 如何产生 PWM 信号?单片机通过控制IO口的高低电平来产生PWM信号。首先,设置IO口为输出模式,并根据PWM波形要求设定IO口输出高电平和低电平的时间比,通常使用定时器产生周期性中断...
求 单片机 控制 PWM 输出0~10V连续可调电压不进0.05程序电路?加低通滤波就可以了搞定如果负载那边输入阻抗很高,所谓低通滤波就可以用最简单的RC电路实现,RC时间常数比PWM周期大几倍就可以了。补充:单片机输出的话,先...
请教一颗IC.电压100mV左右输入,输出为 PWM 。电源电压5V- 15 V。 PWM 频率1K-10K左右?LM331,电压-频率(V/F)变换芯片。那你就用带ADC和PWM的单片机吧!LM331,电压-频率(V/F)变换芯片。那你就用带ADC和PWM的单片机吧!
单片机PWM 的概念是什么?分两点讨论:1.PWM脉冲宽度调制(PWM),是英文“PulseWidthModulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效...
如何将 单片机 输出的 PWM 控制信号,变成可以带负载的变化的电压?单片机输出的PWM为控制信号,需要加入控制器件才可以驱动负载单片机输出的PWM驱动能比较弱,不能直接驱动负载,需要三极管、MOS管参与才可以控制负载的功率,比...
单片机pwm 口怎么定义?分两点讨论:1.PWM脉冲宽度调制(PWM),是英文“PulseWidthModulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有...
单片机 产生 pwm 信号的方法是什么?_其他问答_系统粉在电机调速等方面,PWM应用是最广泛的,而用标准的51单片机内部没有PMW模块,只得用软件来产生PWM信号,这样就得用51单片机的定时器来完成,而在中档PIC...
8位 单片机 PID控制 PWM 的算法如何实现,C语言计算? - 沈默U 的...能帮我设计一个用单片机控制PWM占空比再控制可控硅的开端的硬件及程序。如果有发至liu983580@163.com直接配置单片机PWM输出的占空比就行了啊