新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)軟模PWM誤差率之研究

51單片機(jī)軟模PWM誤差率之研究

作者: 時(shí)間:2016-11-18 來(lái)源:網(wǎng)絡(luò) 收藏
普通型51單片機(jī)一般不集成PWM硬件發(fā)生器,要想實(shí)現(xiàn)PWM輸出必須采用軟件模擬的方式。根據(jù)具體應(yīng)用的不同,PWM波形頻率也高低不一;就直流電機(jī)控制而言,PWM波的頻率一般建議在10kHz~40kHz,20kHz為典型值,輸出頻率過(guò)低,則輸出電流不夠平緩,電機(jī)運(yùn)行不平穩(wěn)。

軟模PWM輸出一般有兩種方式:利用定時(shí)器0控制PWM頻率輸出,結(jié)合定時(shí)器1控制占空比,這是其一;第二種方式,僅使用一個(gè)定時(shí)器,工作于16bit手工裝載模式,同時(shí)控制輸出頻率和占空比,這種方式不占用太多資源,而且實(shí)現(xiàn)起來(lái)也不失其靈活性,俺本人就建議采用這樣方式,建議剔除第一種方式。本文的研究也是基于方式二展開(kāi)的。

本文引用地址:http://m.butianyuan.cn/article/201611/315617.htm

網(wǎng)絡(luò)上常見(jiàn)MCS-51軟模輸出PWM波的文章,而至于對(duì)這種方式實(shí)現(xiàn)的可行性或者說(shuō)局限性,卻無(wú)一例外的被小覷了。本文就51單片機(jī)模擬PWM波輸出的劣根性進(jìn)行了探討,不正之處,歡迎大家提點(diǎn)。

1、產(chǎn)生PWM波的子模塊例程(PWM.C):

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

/*******************************************************************************
*** 函 數(shù) 名: extern void PWM_Init(void)
*** 功能描述: PWM參數(shù)初始化;
*** 全局變量: NO !
*** 輸 入: NO !
*** 輸 出: NO !
*** 創(chuàng) 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函數(shù)說(shuō)明: 外部函數(shù);
/******************************************************************************/
extern void PWM_Init(void)
{
TMOD &= 0x0f; TMOD |= 0x10; //定時(shí)器1方式1,16位手動(dòng)裝載模式;

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

PWM_PIN = 1; //初始化先輸出高電平;
ET1 = 1; //開(kāi)定時(shí)器1中斷;
EA = 1; TR1 = 1; //啟動(dòng)定時(shí)器1;
}
/*******************************************************************************
*** 函 數(shù) 名: extern void Timer1_ISR(void) interrupt 3
*** 功能描述: 定時(shí)器1中斷服務(wù)例程;
*** 全局變量: NO !
*** 輸 入: NO !
*** 輸 出: NO !
*** 創(chuàng) 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函數(shù)說(shuō)明: 中斷服務(wù)函數(shù);
PWM_LOW: 低電平持續(xù)時(shí)間us;
PWM_HIGH: 高電平持續(xù)時(shí)間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
*******************************************************************************/
其中斷服務(wù)例程在Keil C中編譯后的匯編代碼如下(默認(rèn)8級(jí)代碼優(yōu)化):

; 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函數(shù)中,首先清零PWM_PIN引腳,接著調(diào)用PWM_Init()例程,然后就是一個(gè)簡(jiǎn)單的空循環(huán),其經(jīng)由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、另外還有兩個(gè)重要的參數(shù)宏,定義在在PWM模塊的頭文件PWM.H中:

#define PWM_CYCLE 100 //100us,則PWM波的頻率為10kHz;
#define PWM_HIGH 25 //高電平持續(xù)時(shí)間,占空比1/4;
#define PWM_LOW 75 //低電平持續(xù)時(shí)間;

4、首先取PWM_CYCLE, PWM_HIGH, PWM_LOW分別為100、25、75,則設(shè)定的PWM波頻率為10kHz,占空比0.25。編譯連接正確后在Proteus中仿真(單片機(jī)晶振頻率設(shè)置為12.0mHz),抓出一個(gè)周期的波形圖如下:

可計(jì)算:高電平持續(xù)時(shí)間為810us-773us=37us,低電平持續(xù)時(shí)間897us-810us=87us,實(shí)際輸出PWM波的占空比為:37/(37+87)=0.298387,占空比誤差率為(0.298387-0.25)/0.25=19.35%;一般工程實(shí)踐要求的誤差率不超過(guò)5%,顯然這19.35%的誤差率是不符合要求的。(注-Proteus的圖形仿真精度:對(duì)模擬量的采樣最小間隔為1e-18s,典型值為1e-09,參見(jiàn)Proteus使用手冊(cè)。)

5、接著取PWM_CYCLE, PWM_HIGH, PWM_LOW分別為10、2、8,則設(shè)定的PWM波頻率為100kHz,占空比0.2。編譯連接正確后在Proteus中仿真(12.0mHz晶振)后抓出的單個(gè)周期波形圖如下:

由圖可計(jì)算得:實(shí)際輸出的PWM_HIGH, PWM_LOW分別為15、19,占空比0.4412,占空比誤差率120.59%,也就是說(shuō),實(shí)際輸出的PWM波占空比翻番了。

6、繼續(xù)取PWM_CYCLE, PWM_HIGH, PWM_LOW分別為1000、250、750,則設(shè)定的PWM波頻率為1kHz,占空比0.25。編譯連接正確后在Proteus中仿真(12.0mHz晶振)后抓出的單個(gè)周期波形圖如下:

由圖可計(jì)算:實(shí)際輸出的PWM_HIGH, PWM_LOW分別為262、762,占空比0.2558,占空比誤差率2.34%(<5%)。

7、綜上,本文得出的結(jié)論為:在51單片機(jī)上采用軟件模擬的方式輸出PWM波,其頻率越大,占空比誤差越不可收拾;在PWM波形頻率不是很高的情況下(比如小于1kHz),采用軟模方式輸出PWM是完全可行的。

8、為什么會(huì)出現(xiàn)這種情況呢 ?首先將每次仿真調(diào)試,程序中設(shè)定的PWM_HIGH, PWM_LOW值及實(shí)際輸出值列表如下:

比較發(fā)現(xiàn)實(shí)際輸出的PWM波形時(shí)間參數(shù)總比我們當(dāng)然中預(yù)期的多約12個(gè)us,也就是本仿真單片機(jī)的12個(gè)機(jī)器周期。再次查看中斷服務(wù)函數(shù)的匯編代碼:

; 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)

這次把每條指令的執(zhí)行時(shí)間注釋了在后,考慮指令流進(jìn)入了定時(shí)器中斷,執(zhí)行CLR PWM_PIN指令完成,則經(jīng)4us的PWM_HIGH計(jì)時(shí)參數(shù)裝載,2us的中斷返回操作,運(yùn)行main流程中的SJMP ?C0001空轉(zhuǎn)指令至定時(shí)器再次溢出中斷(Xus,X為程序設(shè)定PWM_HIGH取值),CPU中斷響應(yīng)再次轉(zhuǎn)入中斷服務(wù)例程(可計(jì)算中斷響應(yīng)時(shí)間為3~4us),執(zhí)行JNB PWM_PIN,?C0002SETB PWM_PIN

9、到這里,單片機(jī)軟模PWM波在高頻輸出下占空比誤差率變得不可收拾的原因終于畢露原形。實(shí)際輸出占空比計(jì)算式為:(PWM_HIGH+12)/(PWM_HIGH+PWM_LOW+24)。



關(guān)鍵詞: 51單片機(jī)軟模PWM誤差

評(píng)論


技術(shù)專區(qū)

關(guān)閉