51单片机软模PWM误差率之研究

发布者:hxcp18最新更新时间:2016-09-22 来源: eefocus关键字:51单片机  软模PWM  误差率 手机看文章 扫描二维码
随时随地手机看文章
     普通型51单片机一般不集成PWM硬件发生器,要想实现PWM输出必须采用软件模拟的方式。根据具体应用的不同,PWM波形频率也高低不一;就直流电机控制而言,PWM波的频率一般建议在10kHz~40kHz,20kHz为典型值,输出频率过低,则输出电流不够平缓,电机运行不平稳。

    软模PWM输出一般有两种方式:利用定时器0控制PWM频率输出,结合定时器1控制占空比,这是其一;第二种方式,仅使用一个定时器,工作于16bit手工装载模式,同时控制输出频率和占空比,这种方式不占用太多资源,而且实现起来也不失其灵活性,俺本人就建议采用这样方式,建议剔除第一种方式。本文的研究也是基于方式二展开的。

    网络上常见MCS-51软模输出PWM波的文章,而至于对这种方式实现的可行性或者说局限性,却无一例外的被小觑了。本文就51单片机模拟PWM波输出的劣根性进行了探讨,不正之处,欢迎大家提点。

    1、产生PWM波的子模块例程(PWM.C):

#include "Includes.h"    //文件包含

/*******************************************************************************
*** 函 数 名:   extern void PWM_Init(void)
*** 功能描述:   PWM参数初始化;
*** 全局变量:   NO !
*** 输        入:   NO !
*** 输        出:   NO !
*** 创 建 人:huangtiexiong     日期:2006-11-28
*** 修 改 人:                             日期:2006-11-28
*** 函数说明: 外部函数;
/******************************************************************************/
extern void PWM_Init(void)
{
TMOD &= 0x0f; TMOD |= 0x10;    //定时器1方式1,16位手动装载模式;

TH1 = (65536 - PWM_HIGH) / 256 ;
TL1 = (65536 - PWM_HIGH) % 256 ;

PWM_PIN = 1;    //初始化先输出高电平;
ET1    = 1;    //开定时器1中断;
EA     = 1; TR1    = 1;    //启动定时器1;
}
/*******************************************************************************
*** 函 数 名:   extern void Timer1_ISR(void) interrupt 3
*** 功能描述:   定时器1中断服务例程;
*** 全局变量:   NO !
*** 输        入:   NO !
*** 输        出:   NO !
*** 创 建 人:huangtiexiong     日期:2006-11-28
*** 修 改 人:                              日期:2006-11-28
*** 函数说明: 中断服务函数;
        PWM_LOW:    低电平持续时间us;
        PWM_HIGH: 高电平持续时间us;
        PWM_PIN:      PWM波输出引脚,接P1.7;
/******************************************************************************/
extern void Timer1_ISR(void) interrupt 3
{
if(PWM_PIN)   {PWM_PIN = 0;
    TH1 = (65536 - PWM_LOW) / 256 ;
    TL1 = (65536 - PWM_LOW) % 256 ; }
else    {PWM_PIN = 1;
    TH1 = (65536 - PWM_HIGH) / 256 ;
    TL1 = (65536 - PWM_HIGH) % 256 ; }  
}
/*******************************************************************************
****                              End Of File
*******************************************************************************/
    其中断服务例程在Keil C中编译后的汇编代码如下(默认8级代码优化):

             ; FUNCTION Timer1_ISR (BEGIN)
                                           ; SOURCE LINE # 43
                                           ; SOURCE LINE # 45
0000 309709            JNB     PWM_PIN,?C0002
                                           ; SOURCE LINE # 46
                                           ; SOURCE LINE # 47
0003 C297              CLR     PWM_PIN
                                           ; SOURCE LINE # 48
0005 758DFF            MOV     TH1,#0FFH
                                           ; SOURCE LINE # 49
0008 758BB5            MOV     TL1,#0B5H
                                           ; SOURCE LINE # 50
000B 32                RETI    
000C         ?C0002:
                                           ; SOURCE LINE # 52
                                           ; SOURCE LINE # 53
000C D297              SETB    PWM_PIN
                                           ; SOURCE LINE # 54
000E 758DFF            MOV     TH1,#0FFH
                                           ; SOURCE LINE # 55
0011 758BE7            MOV     TL1,#0E7H
                                           ; SOURCE LINE # 56
                                           ; SOURCE LINE # 57
0014         ?C0004:
0014 32                RETI    
             ; FUNCTION Timer1_ISR (END)

    2、主入口模块(BootLoader.c):在主模块main函数中,首先清零PWM_PIN引脚,接着调用PWM_Init()例程,然后就是一个简单的空循环,其经由Keil C编译后的汇编代码为:

             ; FUNCTION main (BEGIN)

0000 C297              CLR     PWM_PIN
                                           ; SOURCE LINE # 31
0002 120000      E     LCALL   PWM_Init
0005         ?C0001:
                                           ; SOURCE LINE # 32
0005 80FE              SJMP    ?C0001
             ; FUNCTION main (END)

    3、另外还有两个重要的参数宏,定义在在PWM模块的头文件PWM.H中:

#define PWM_CYCLE 100     //100us,则PWM波的频率为10kHz;
#define PWM_HIGH     25      //高电平持续时间,占空比1/4;
#define PWM_LOW      75      //低电平持续时间;

    4、首先取PWM_CYCLE, PWM_HIGH, PWM_LOW分别为100、25、75,则设定的PWM波频率为10kHz,占空比0.25。编译连接正确后在Proteus中仿真(单片机晶振频率设置为12.0mHz),抓出一个周期的波形图如下:

可计算:高电平持续时间为810us-773us=37us,低电平持续时间897us-810us=87us,实际输出PWM波的占空比为:37/(37+87)=0.298387,占空比误差率为(0.298387-0.25)/0.25=19.35%;一般工程实践要求的误差率不超过5%,显然这19.35%的误差率是不符合要求的。(注-Proteus的图形仿真精度:对模拟量的采样最小间隔为1e-18s,典型值为1e-09,参见Proteus使用手册。)

     5、接着取PWM_CYCLE, PWM_HIGH, PWM_LOW分别为10、2、8,则设定的PWM波频率为100kHz,占空比0.2。编译连接正确后在Proteus中仿真(12.0mHz晶振)后抓出的单个周期波形图如下:

由图可计算得:实际输出的PWM_HIGH, PWM_LOW分别为15、19,占空比0.4412,占空比误差率120.59%,也就是说,实际输出的PWM波占空比翻番了。

   6、继续取PWM_CYCLE, PWM_HIGH, PWM_LOW分别为1000、250、750,则设定的PWM波频率为1kHz,占空比0.25。编译连接正确后在Proteus中仿真(12.0mHz晶振)后抓出的单个周期波形图如下:

由图可计算:实际输出的PWM_HIGH, PWM_LOW分别为262、762,占空比0.2558,占空比误差率2.34%(<5%)。

    7、综上,本文得出的结论为:在51单片机上采用软件模拟的方式输出PWM波,其频率越大,占空比误差越不可收拾;在PWM波形频率不是很高的情况下(比如小于1kHz),采用软模方式输出PWM是完全可行的。

    8、为什么会出现这种情况呢 ?首先将每次仿真调试,程序中设定的PWM_HIGH, PWM_LOW值及实际输出值列表如下:

比较发现实际输出的PWM波形时间参数总比我们当然中预期的多约12个us,也就是本仿真单片机的12个机器周期。再次查看中断服务函数的汇编代码:

             ; FUNCTION Timer1_ISR (BEGIN)
                                           ; SOURCE LINE # 43
                                           ; SOURCE LINE # 45
0000 309709            JNB     PWM_PIN,?C0002        ;;;2us
                                           ; SOURCE LINE # 46
                                           ; SOURCE LINE # 47
0003 C297              CLR     PWM_PIN                        ;;;1us
                                           ; SOURCE LINE # 48
0005 758DFF            MOV     TH1,#0FFH                 ;;;2us
                                           ; SOURCE LINE # 49
0008 758BB5            MOV     TL1,#0B5H                  ;;;2us
                                           ; SOURCE LINE # 50
000B 32                RETI                                                  ;;;2us
000C         ?C0002:
                                           ; SOURCE LINE # 52
                                           ; SOURCE LINE # 53
000C D297              SETB    PWM_PIN                      ;;1us
                                           ; SOURCE LINE # 54
000E 758DFF            MOV     TH1,#0FFH                 ;;2us
                                           ; SOURCE LINE # 55
0011 758BE7            MOV     TL1,#0E7H                   ;;2us
                                           ; SOURCE LINE # 56
                                           ; SOURCE LINE # 57
0014         ?C0004:
0014 32                RETI                                                   ;;2us
             ; FUNCTION Timer1_ISR (END)

这次把每条指令的执行时间注释了在后,考虑指令流进入了定时器中断,执行CLR     PWM_PIN指令完成,则经4us的PWM_HIGH计时参数装载,2us的中断返回操作,运行main流程中的SJMP    ?C0001空转指令至定时器再次溢出中断(Xus,X为程序设定PWM_HIGH取值),CPU中断响应再次转入中断服务例程(可计算中断响应时间为3~4us),执行JNB     PWM_PIN,?C0002SETB    PWM_PIN

    9、到这里,单片机软模PWM波在高频输出下占空比误差率变得不可收拾的原因终于毕露原形。实际输出占空比计算式为:(PWM_HIGH+12)/(PWM_HIGH+PWM_LOW+24)。

关键字:51单片机  软模PWM  误差率 引用地址:51单片机软模PWM误差率之研究

上一篇:51单片机C和汇编指令对比
下一篇:单片机电子钟汇编程序

推荐阅读最新更新时间:2024-03-16 15:11

51单片机同时外扩RAM,ROM的具体实现及Keil的具体设置
51MCU内部有RAM,ROM,不同于8031。尽管如今的增强行51MCU的内部RAM,ROM可能已经很大的空间。但就技术而言,扩展RAM,ROM还是需要学会的。 对于不同的设计方案需求,扩展可能基于以下任何一种设计: A,只扩展RAM B,只扩展ROM C,扩展ROM,RAM 总线扩展时,P2口是否可用做普通IO口 这种扩展是基于总线扩展的,所以,P0P2口就已经不可以再做它用了(有网友提供信息,总线扩展P2还可以做普通IO口用,有两种可能:1,P2口复用,如同P1利用373锁存器。2,在总线扩展时,只用到了低地址总线,P2口未用到。就作为普通IO口应用。由于技术还不到位,不做评论。) *扩展R
[单片机]
51单片机多机通信原理
一、多机通信原理 在多机通信中,主机必须要能对各个从机进行识别,在51系列单片机中可以通过SCON寄存器的SM2位来实现。当串口以方式2或方式3发送数据时,每一帧信息都是11位,第9位是数据可编程位,通过给TB8置1或置0来区别地址帧和数据帧,当该位为1时,发送地址帧;该位为0时,发送数据帧。 在多机通信过程中,主机先发送某一从机的地址,等待从机的应答,所有的从机接收到地址帧后与本机地址进行比较,若相同,则将SM2置0准备接收数据;若不同,则丢弃当前数据,SM2位不变。 二、多机通信电路图 此处,U1作为主机,U2为从机1,U3为从机2。 三、C语言程序 (1)主机程序 #include#include #define
[单片机]
<font color='red'>51单片机</font>多机通信原理
利用51单片机的LED点阵输出生日快乐
Led点阵原理图 D0-D7口接在74HC595芯片上,芯片的输入端口为P34、P35、P36端口; 控制每一列的为P00-P07端口 LED点阵工作原理 根据点阵原理图,P00-P07接低电平,D0-D7接高电平时led点亮,由于单片机控制端口有限,于是只能每次点亮一列,逐列扫描,利用人眼的视觉暂留形成同时点亮的现象。将要点亮的LED灯标记为1,每一列根据D0-D7的高低电平,转换成2进制数,再转换成16进制数,于是得到每一个汉字所对应的数组,通过74HC595移位输出(这里可以通过IC资料查看74HC595工作原理编程)。 程序代码
[单片机]
利用<font color='red'>51单片机</font>的LED点阵输出生日快乐
51单片机:定时器
定时器:单条指令时间(us) = 1/单片机频率*单条指令时钟周期 TH0和TL0共16位,最多只能表示65535,所以要设定一个Base值,再利用循环多计数几次 比如0.002s:0.02 = (1/11.0592M * 12)*指令个数,指令个数 = 0.02(1/11.0592M * 12) = 0.018432 因为频率用的是M,所以结果0.018432*1000000 = 18432 使用16位寄存器的情况下,TH0和TL初始值:65536 - 18432 = 47104 = 0xB8 00 编写定时器延时函数: #include sbit LED = P0^0; void Delay(un
[单片机]
两种方法教你如何有效地利用51单片机产生PWM
89C51芯片没有自带PWM发生器,如果要用51来产生PWM波就必须要用软件编程的方法来模拟。方法大概可以分为软件延时和定时器产生两种方法。下面将逐一介绍。 1 软件延时法 利用软件延时函数,控制电平持续的时间,达到模拟pwm的效果。 程序如下: #include 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输出。
[单片机]
两种方法教你如何有效地利用<font color='red'>51单片机</font>产生<font color='red'>PWM</font>波
51单片机快速入门指南】5.1:SPI与DS1302时钟芯片
普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《普中 51 单片机开发攻略》、《DS1302中文手册》。 DS1302 简介 DS1302 是 DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和 31 字节静态 RAM,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM 指示决定采用 24 或 12 小时格式。DS1302 与 单片机之间能简单地采用同步串行
[单片机]
【<font color='red'>51单片机</font>快速入门指南】5.1:SPI与DS1302时钟芯片
51单片机和PC串口异步通信
单片机和PC机间的通信有很多方式,下面的程序主要用到的是51单片机的异步串行通信。 一.51单片机的串行通信管脚 P3.1为单片机的TXD管脚(Transfer Data),P3.2为单片机的RXD管脚(Receive Data)。 通过TXD管脚可以将CPU要发送的数据输出,RXD管脚可以将串行数据线传来的数据读入。 二.51单片机的串行通信控制寄存器SCON,电源控制寄存器PCON SCON: 其中,SM0,SM1控制着串行通信的工作方式。 SM0 SM1 工作方式 说明 波特率 0 0 0 移位寄存器 fosc/12 0 1
[单片机]
<font color='red'>51单片机</font>和PC串口异步通信
基于GSM模块Q2403A和8051单片机实现短消息收发系统的应用方案
基于GSM短消息的业务不需要建立拨号连接,只需把待发的消息加上目的地址发送至短消息中心,再由短消息中心转发到最终目标。GSM 短消息业务以其连接简单、费用低廉、覆盖范围广、实现方便等优点得到了广泛的应用。运用 GSM 短消息实现远程测控的可靠性较高、信号传播距离远、覆盖面积广,并且可以节省建网初期的巨额投资。 本文对基于GSM短消息收发系统的设计与实现作了具体描述,给出了系统的软硬件设计方案,对主要硬件,即GSM模块Q2403A 和8051单片机作了重点介绍。给出了系统的软件设计,包括PC与单片机通信部分和短消息收发部分。最后实现系统监控功能。 系统硬件实现 总体系统结构 该系统硬件主要由8051单片机扩展电路、Q2403
[单片机]
基于GSM模块Q2403A和80<font color='red'>51单片机</font>实现短消息收发系统的应用方案
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved