PWM(脈沖寬度調制)和占空比究竟是啥?

對于很多剛剛接觸Arduino的人來說,占空比和PWM 這兩個詞可能不太容易理解,下面就讓我們深度剖析一下這兩個概念。
你也可以通過與視頻結合的方式學習,PWM的概念與應用,這是個不錯的視頻;更詳細的介紹參看 用Arduino剖析PWM脈寬調制

PWM(Pulse Width Modulation)

簡介

PWM,也就是脈沖寬度調制,用于將一段信號編碼為脈沖信號(一般是方波信號)。是在數字電路中 達到 模擬輸出效果的一種手段。即:使用數字控制產生占空比不同的方波(一個不停在開與關之間切換的信號)來控制模擬輸出。我們要在數字電路中輸出模擬信號,就可以使用PWM技術實現。在嵌入式開發中,我們常用PWM來驅動LED的暗亮程度,電機的轉速等。

PWM的頻率

pwm的頻率決定了輸出的數字信號on ,1 和 off,0 的切換速度。頻率越高,切換就越快。頻率的大小就是前面提到的調制周期T的倒數 : f = 1/T。

1秒內,0.5秒開,0.5秒滅,占空比是50%。那么,1毫秒內,0.5毫秒開,0.5毫秒滅,占空比也是50%,對于前者,頻率就是1HZ,而后者,是1毫秒,頻率就是1KHZ。

一般pwm頻率都是因硬件設計而固定的,是由pwm發生器決定的。PWM頻率越高,調制出來的輸出曲線就更加的smooth,效果越好,完成一個調制周期的時間越短。這個和手機的ppi越高,顯示越清晰是一個道理。當然PWM的頻率越高,對硬件的要求就也越高。

如何產生PWM?

Arduino有三種方式可以產生PWM。第一種:

用analogWrite(pin, val)命令
其中pin是引腳的編號,只能用3,5,6,9,10,11這幾條;val是0~255的整數值,對應電壓從0到+5V。
具體的使用可以看下面的示例代碼:

int pin = 8; //0~13
void setup()
{
    pinMode(pin, OUTPUT);
}   
void loop()
{
    analogWrite(pin, 128);
    delay(500);
}

這種方式產生的方波周期大概是2ms左右(490Hz),不需要占用額外的cpu命令時間。據說99%的同學看到這里就可以下課了,技術宅請繼續看第二種方式:

手動用代碼實現PWM

int pin = 38;  //這個可以隨意點
void setup()
{
    pinMode(pin, OUTPUT);
} 
void loop()
{
  digitalWrite(pin, HIGH);
  delayMicroseconds(100);
  digitalWrite(pin, LOW);
  delayMicroseconds(1000 - 100);
}

上面這段代碼會產生一個PWM=0.1的,周期為1ms的方波(1000Hz),這種方式的優缺點很明顯:

1.PWM的比例可以更精確;
2.周期和頻率可控制;
3.所有的pin腳都可以輸出,不局限于那幾個腳;
缺點:CPU干不了其他事情了;
好吧,缺點只有一個,卻非常致命,以至于上面這些基本都是廢話。但是對于周期比較大的PWM,可以用算法模擬CPU的多任務系統,從而在輸出PWM的同時做點兼職。
那么能不能既調節PWM的頻率和周期,又不要占用額外的CPU時間呢?請看第三種方式:

使用PWM寄存器(不作要求)

ATmega168有三個時鐘,名字分別叫Timer0, Timer1和Timer2。每個時鐘都使用了兩個寄存器,其中一個是設定值例如128,另一個則從0開始不斷遞增,到1024之后溢出回到0。那么當兩個值相同的時候,Timer就會把某個管腳反相。不同的Timer之間頻率是相同的,占空比則根據設置值不同。
占空比有了,那么周期怎么控制呢?有一種叫做時鐘控制器的東東,這個控制器可以設置周期為CPU周期的某個倍數,例如1,8,64,256,1024等等,Timer0和Timer1共用一個控制器,Timer2和它們是獨立的。

Atmega 168/328的時鐘們
ATmega328P有三個時鐘,Timer0,Timer1和Timer2。每個時鐘都有兩個比較寄存器,可以同時支持兩路輸出。其中比較寄存器用于控制PWM的占空比,具體的原理等會兒會介紹。大多數情況下,每個時鐘的兩路輸出會有相同的頻率,但是可以有不同的占空比(取決于那兩個比較寄存器的設置)

每個時鐘都有一個“預定標器”,它的作用是設置timer的時鐘周期,這個周期一般是有Arduino的系統時鐘除以一個預設的因子來實現的。這個因子一般是1,8,64,256或1024這樣的數值。Arduino的系統時鐘周期是16MHz,所以這些Timer的頻率就是系統時鐘除以這個預設值的標定值。需要注意的是,Timer2的時鐘標定值是獨立的,而Timer0和Timer1使用的是相同的。

這些時鐘都可以有多種不同的運行模式。常見的模式包括“快速PWM”和“相位修正PWM”,這兩種PWM的定義也會在后面解釋。這些時鐘可以從0計數到255,也可以計數到某個指定的值。例如16位的Timer1就可以支持計數到16位(2個字節)。

除了比較寄存器外,還有一些其他的寄存器用來控制時鐘。例如TCCRnA和TCCRnB就是用來設置時鐘的計數位數。這些寄存器包含了很多位(bit),它們分別的作用如下:
脈沖生成模式控制位(WGM):用來設置時鐘的模式
時鐘選擇位(CS):設置時鐘的預定標器
輸出模式控制位(COMnA和COMnB):使能/禁用/反相 輸出A和輸出B
輸出比較器(OCRnA和OCRnB):當計數器等于這兩個值時,輸出值根據不同的模式進行變化

不同時鐘的這些設置位稍有不同,所以使用的時候需要查一下資料。其中Timer1是一個16位的時鐘,Timer2可以使用不同的預定標器。

占空比(duty cycle)

有了前面的知識,相信你已經對占空比理解了,其實很好理解 ,所謂占空比就是調整led通過電流和不通過電流的時間比來控制的,由于人眼有視覺暫留特性,所以只要頻率比較高是看不出來閃爍的。有關這部分介紹在PWM的概念與應用這個視頻里有直觀的說明。

當然通過電流比不通過電流的時間比例越大,led做的功就越多,這樣也就越亮,需要注意的是led芯片的溫升和最大電流值不要超標,不然會影響其壽命。

下面給出占空比的公式

占空比計算公式

D: 占空比
PW: 脈沖寬度(調制周期中脈沖持續時間)
T: 一個調制周期

所以我們可以很自然的得出結論:

  • 低占空比意味著輸出的能量低,因為在一個周期內大部分時間信號處于關閉狀態,如果pwm控制的負載為led,則具體表現例如led燈很暗。
  • 高占空比意味著輸出的能量高,在一個周期內,大部分時間信號處于on狀態,具體表現為LED比較亮。
  • 當占空比為100%時,表示 fully on,也就是在一個周期內,信號都處于on狀態,具體表現為led亮度到達100%。
  • 當占空比為0%時則表示 totally off,在一個周期內,一直處于off狀態,具體表現為led熄滅。

現在一切都明了了:脈沖寬度調制,這個寬,不是物體的寬度,而是高電平(有效電平)信號在一個調制周期中持續時間長短,它可以用占空比去衡量,占空比越大,脈沖寬度越寬。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容