PWM 是“脈沖寬度調(diào)制”的意思。
PWM 實際上是在單片機的某個引腳輸出一系列的矩形波,其周期一般是固定的;而其高電平、低電平所占用的時間,是可以受控調(diào)整的。
高電平、低電平所占用的時間之比,稱為占空比,其值為0~1之間。
PWM 的應用很廣,簡單的說,它可以控制燈光的亮度、可以控制直流電機的轉速,甚至還可以輸出語音信號。
新型的單片機,往往都含有硬件的 PWM 模塊,編寫程序就很簡單;而老式的MCS-51系列,就不具備這個條件。
其實,在沒有 PWM 硬件的單片機上實現(xiàn) PWM,也并不難,只需一個定時器,令其工作在中斷方式即可。
下面以網(wǎng)上的一個題目為例,說明實現(xiàn) PWM 方法。
要求:
1。單片機的晶振是12MHz,輸出周期為1s。
2。用兩個開關控制占空比的增加和減少,分20等級。
針對這個題目,做而論道設計了一個簡單的實驗電路:
在 P2 口的 8 條線輸出 PWM 波形;
在 /INT1、/INT0 外接了兩個按鍵,用來調(diào)整占空比;
在 P0 口外接了兩個 BCD 數(shù)碼顯示器,用來顯示當前的占空比的等級。
實驗的時候,可以使用示波器來觀察 P2 口輸出的波形。
如果把 PWM 波形的頻率提高,也可以用 LED 觀察到漸亮漸暗的效果,目前看,只是閃爍的時間發(fā)生變化。
//程序如下:
//==========================================
#include
unsigned int a, b;
//------------------------------------------
void main()
{
TMOD = 0x01;//T0定時方式1
TH0 = (65536-50000) / 256;//50ms@12MHz
TL0 = (65536-50000) % 256;
TR0 = 1;
ET0 = 1;
EX0 = 1; EX1 = 1;
IT0 = 1; IT1 = 1;
EA = 1;
a = 0;
b = 10;
while(1);
}
//------------------------------------------
void time0() interrupt 1
{
TL0 = (65536-50000) % 256;
TH0 = (65536-50000) / 256;//50ms@12MHz
a++;
if(a == 20) a = 0;//在這里調(diào)整周期。
if(a 《 b) P2 = 0xff;//在這里調(diào)整占空比。
elseP2 = 0x00;
P0 = ((b / 10) 《《 4) + b % 10; //顯示占空比等級
}
//------------------------------------------
void X0_INT() interrupt 0
{
b++;
if(b 》 19) b = 19;//占空比等級最大為19
}
//------------------------------------------
void X1_INT() interrupt 2
{
b--;
if(b 《 1) b = 1;//占空比等級最小為1.
}
//==========================================
//電路以及仿真效果如下圖:
這個程序時我在剛學單片機是轉來的,今天我想就這個程序說兩句。按功能要求來說這個程序是沒有問題的,我想說的是——用pwm控制直流電機在你用硬件調(diào)試調(diào)試這個程序時,你會發(fā)現(xiàn)個問題:當你按下按鈕減小占空比時直流電機是轉一下停一下的用眼睛或者耳朵都是能分辨的。當然用pwm控制直流電機本來就是轉下停下的,因為pwm就是有連續(xù)的一高一低電平。當他為高電平時電機轉低電平時就停。我們現(xiàn)在要做的就是讓電機的轉動給我們的感覺是連續(xù)的,當然這肯定還是要從pwm下手。
要做到電機流暢的轉動其實很簡單,只要將pwm電平的周期縮短(頻率升高)就行了也就是減小產(chǎn)生中斷的時間(初值設大點)。
這個程序還是有很大的缺陷的,在protues上仿真有些問題是發(fā)現(xiàn)不了的。而這里出現(xiàn)的問題也是典型的——按鍵消抖。這個程序里是沒有消抖的(如果進行了硬件消抖,這是沒有問題的)。用按鍵來產(chǎn)生一個中斷肯定是要消抖的,不管是硬件的還是軟件的。在protues上兩樣都不用的話,仿真也是能通過的,所已說仿真通過不一定能在硬件上實現(xiàn)你想要的功能。
以上為轉載
如果只是簡單的想產(chǎn)生一定占空比的矩形信號可以對定時器這樣使用,道理同上
比如要P3^6產(chǎn)生占空比為30%的1KHZ的矩形波。
void timer() interrupt 1 //產(chǎn)生1khz的占空比為
{
TH0=(65536-100)/256; //定時產(chǎn)生0.1KHZ的波形
TL0=(65536-100)%6;
a++;
if(a==3) //定時器運行3次指向下一句
P3^6=1;
else if (a==10) //記到10次時執(zhí)行下一句
P3^6=0;
a=0;
}
也可以將紅字設置為變量,用按鍵控制產(chǎn)生不同占空比、不同頻率的矩形波。
評論
查看更多