10 2 PWM的原理與控制程式

2021-09-11 05:41:39 字數 3223 閱讀 9532

pwm 在微控制器中的應用是非常廣泛的,它的基本原理很簡單,但往往應用於不同場合上意義也不完全一樣,這裡我先把基本概念和基本原理給大家介紹一下,後邊遇到用的時候起碼知道是個什麼東西。

pwm 是 pulse width modulation 的縮寫,它的中文名字是脈衝寬度調製,一種說法是它利用微處理器的數字輸出來對模擬電路進行控制的一種有效的技術,其實就是使用數碼訊號達到乙個模擬訊號的效果。這是個什麼概念呢?我們一步步來介紹。

首先從它的名字來看,脈衝寬度調製,就是改變脈衝寬度來實現不同的效果。我們先來看三組不同的脈衝訊號,如圖 10-1 所示。

圖 10-1 pwm 波形

這是乙個週期是 10ms,即頻率是 100hz 的波形,但是每個週期內,高低電平脈衝寬度各不相同,這就是 pwm 的本質。在這裡大家要記住乙個概念,叫做「占空比」。占空比是指高電平的時間佔整個週期的比例。比如第一部分波形的占空比是 40%,第二部分波形占空比是 60%,第三部分波形占空比是 80%,這就是 pwm 的解釋。

那為何它能對模擬電路進行控制呢?大家想一想,我們數位電路裡,只有 0 和 1 兩種狀態,比如我們第 2 章學會的點亮 led 小燈那個程式,當我們寫乙個 led = 0;小燈就會長亮,當我們寫乙個 led = 1;小燈就會滅掉。當我們讓小燈亮和滅間隔執行的時候,小燈是閃爍。

如果我們把這個間隔不斷的減小,減小到我們的肉眼分辨不出來,也就是 100hz 以上的頻率,這個時候小燈表現出來的現象就是既保持亮的狀態,但亮度又沒有 led = 0;時的亮度高。那我們不斷改變時間引數,讓 led = 0;的時間大於或者小於 led = 1;的時間,會發現亮度都不一樣,這就是模擬電路的感覺了,不再是純粹的 0 和 1,還有亮度不斷變化。大家會發現,如果我們用 100hz 的訊號,如圖 10-1 所示,假如高電平熄滅小燈,低電平點亮小燈的話,第一部分波形熄滅 4ms,點亮 6ms,亮度最高,第二部分熄滅 6ms,點亮 4ms,亮度次之,第三部分熄滅 8ms,點亮 2ms,亮度最低。那麼用程式驗證一下我們的理論,我們用定時器t0 定時改變 p0.0 的輸出來實現 pwm,與純定時不同的是,這裡我們每週期內都要過載兩次定時器初值,即用兩個不同的初值來控制高低電平的不同持續時間。為了使亮度的變化更加明顯,程式中使用的占空比差距更大。

#include sbit pwmout = p0^0;

sbit addr0 = p1^0;

sbit addr1 = p1^1;

sbit addr2 = p1^2;

sbit addr3 = p1^3;

sbit enled = p1^4;

unsigned char highrh = 0; //高電平過載值的高位元組

unsigned char highrl = 0; //高電平過載值的低位元組

unsigned char lowrh = 0; //低電平過載值的高位元組

unsigned char lowrl = 0; //低電平過載值的低位元組

void configpwm(unsigned int fr, unsigned char dc);

void closepwm();

void main()

}/* 配置並啟動 pwm,fr-頻率,dc-占空比 */

void configpwm(unsigned int fr, unsigned char dc)

/* 關閉 pwm */

void closepwm()

/* t0 中斷服務函式,產生 pwm 輸出 */

void interrupttimer0() interrupt 1else

}

需要提醒大家的是,由於標準 51 微控制器中沒有專門的 pwm 模組,所以我們用定時器加中斷的方式來產生 pwm,而現在有很多的微控制器都會整合硬體的 pwm 模組,這種情況下需要我們做的就僅僅是計算一下週期計數值和占空比計數值然後配置到相關的 sfr 中即可,既使程式得到了簡化又確保了 pwm 的輸出品質(因為消除了中斷延時的影響)。

#include sbit pwmout = p0^0;

sbit addr0 = p1^0;

sbit addr1 = p1^1;

sbit addr2 = p1^2;

sbit addr3 = p1^3;

sbit enled = p1^4;

unsigned long periodcnt = 0; //pwm 週期計數值

unsigned char highrh = 0; //高電平過載值的高位元組

unsigned char highrl = 0; //高電平過載值的低位元組

unsigned char lowrh = 0; //低電平過載值的高位元組

unsigned char lowrl = 0; //低電平過載值的低位元組

unsigned char t1rh = 0; //t1 過載值的高位元組

unsigned char t1rl = 0; //t1 過載值的低位元組

void configtimer1(unsigned int ms);

void configpwm(unsigned int fr, unsigned char dc);

void main()

/* 配置並啟動 t1,ms-定時時間 */

void configtimer1(unsigned int ms)

/* 配置並啟動 pwm,fr-頻率,dc-占空比 */

void configpwm(unsigned int fr, unsigned char dc)

/* 占空比調整函式,頻率不變只調整占空比 */

void adjustdutycycle(unsigned char dc)

/* t0 中斷服務函式,產生 pwm 輸出 */

void interrupttimer0() interrupt 1else

}/* t1 中斷服務函式,定時動態調整占空比 */

void interrupttimer1() interrupt 3;

tl1 = t1rl;

adjustdutycycle(table[index]); //調整 pwm 的占空比

if (dir == 0)

}else

}}

呼吸燈效果做出來後,利用這個基本原理,其它各種效果的燈光閃爍都應該可以做出來,大家看到的 ktv 裡邊那絢麗的燈光閃爍,其實就是採用的 pwm 技術控制的。

Spring的註解驅動控制程式

在pojo類定義的時候我們給該類加上 controller註解後,在通過在spring mvc的配置檔案中加上,該pojo就可以成為乙個能處理http請求的控制器了。具體的對映方法 1 通過請求url進行對映請求。2 通過請求方法 post,get等 請求引數或者請求頭進行對映。請求處理方法簽名 1...

9 8 實用的電機控制程式

上面我們雖然完成了用中斷控制電機轉動的程式,但實際上這個程式還是沒多少實用價值的,我們不能每次想讓它轉動的時候都上下電啊,是吧。還有就是它不但能正轉還得能反轉啊,也就是說不但能轉過去,還得能轉回來呀。好吧,我們就來做乙個例項程式吧,結合第 8 章的按鍵程式,我們設計這樣乙個功能程式 按數字鍵 1 9...

程式控制電源的控制程式開發總結

自動化技術得到飛躍發展的今天,測試中各種儀表也都支援ieee 488協議,可以利用pc完成控制。在gpib匯流排程式設計中,將總結過去用到的基於gpib匯流排控制儀表的開發經驗。首先總結一下agent 663系列電源的控制。開發工具 vc 6.0,必備檔案 visa庫。說到visa庫,談談我對它的認...