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%
End51单片机存储器小结
存储器分为程序存储器(ROM)和数据存储器(RAM),两种又都可以分为片内和片外,片外即需要自己在单片机外部扩展。
8051单片机的片内程序存储器有4K,片内数据存储器有256个字节,其中又分为高128字节位特殊功能寄存器区,真正用户能用的RAM只有低128字节。
8052单片机有8K片内程序存储器,而数据存储器除了低128字节外还有扩展的高128字节,地址上跟特殊功能寄存器一样,但物理上是独立的,寻址方式不一样,扩展的高128字节只能间接寻址。
Keil中变量的存储类型:
存储类型
说明
code
程序空间(无需改变的变量)
data
直接访问的内部数据存储器(速度最快)
idata
间接访问的内部数据存储器(可以访问全部256字节RAM)
bdata
可位寻址的内部数据存储器
xdata
外部数据寄存器(最大64K)
pdata
分页的外部数据寄存器(最大256字节,少用)
【如无使用关键字,系统则按默认处理(根据存储模式)】
Keil中的存储模式:
存储模式
说明
Small
变量默认为data型,最大128字节
Compare
变量默认为pdata型,最大256字节
Large
变量默认为xdata型,最大64K
Keil中设置如下图:
我们平常使用的STC单片机,有很多型号,具体存储器大小都要看型号:
【89/90系列的机器周期需要12个或6个时钟周期】
【12/15系列的机器周期只需要1个时钟周期】
51单片机上的FFT算法
最近用增强型51单片机做了一个简易的点阵音乐频谱显示器,最主要是自己刚学完信号处理课程,想自己写一个FFT算法。现将已经能够在51单片机上运行的FFT算法供需要的伙伴们参考。
在51单片机上运行FFT算法,需要注意一下几点:
由于51单片机的内存RAM很小,只有128字节,52有256字节,而16点的浮点数输入,就需要2*4*16=128字节的内存开销,所以只有256字节的做多只能做16点的FFT运算。而且必须要用idata定义才能将其定义在高128字节。所以要做16点以上的FFT运算,必须选用有内部扩展RAM的51系列单片机,然后用xdata定义,并且要将存储模式设为LARGE模式。
相关问答
51单片机 中的基本数据类型?在标准C语言中,存在着如下六种基本数据类型:1、char:字符型;2、short=shortint:短整型3、int:整型4、long=longint:长整型5、float:单精...
8位 单片机 如何实现32位 浮点数 运算?求原理求思路?其实这个问题我之前也有疑惑,后来看了汇编就明白了,8位单片机在进行32位计算时,会分高16位和低16位,16位又可以被分为高八位和低八位,计算时超过八位会产生进...
合泰 单片机 HT66F0185支持 浮点数 类型的数据吗?多数单片机硬件上不支持浮点运算,但C语言库函数可以支持浮点运算,而不用你去了解它是怎么实现的。添加math.h头文件,连三角函数也可以计算多数单片机硬件上...
单片机 如何把 浮点 型转换为char型?floata;intc;charb;c=(a*(float)(2^16));b=c>>16;先用浮点乘上一个2的倍数(假设16倍),把结果转成整型,然后把这个整形结...
单片机 控制MOS开关管问题?是P沟的好,这样控制可以共地,处理起来方便;IRF5305可以,不过却有20A电流的话,建议两个并一起使用,那样安全多了。使用MOS管来控制恒流,MOS管上为了恒流,...
c 51 变量定义的四个要素?[存储种类]数据类型[存储类型]变量名其中:存储种类与标准C语言相同,包括:自动型(auto)、外部型(extern)、静态型(static)、寄存器型(register)。数据类...
计算机中MIPS表示什么 - 茶茶 的回答 - 懂得MillionInstructionsPerSecond的缩写,每秒2113处理的百万5261级的机器语言指令数。这是4102衡量CPU速度的一个指1653标。像是一个Intel80386电脑可...
一般 单片机 代码对变量有什么要求吗?C语言中,变量一般有两种属性,分别是:存储类别、数据类型。例如定义一个变量:staticunsignedcharvar=0;上述语句中,static(静态的)为变量的存储类别,...
ju指令的用法及功能?ju指令是一个用于计算机编程的命令,它的功能是将一个数值转换为整数。它可以用于不同的编程语言和环境中,例如Python、Java和C++等。使用ju指令,可以将浮点数...
DSP与 单片机 的区别?存储器结构不同单片机使用冯。诺依曼存储器结构。这种结构中,只有一个存储器空间通过一组总线(一个地址总线和一个数据总线)连接到处理器核。大多数DSP采用...