一、PWM脈寬調變
PWM是脈衝寬度調變的簡稱。實際上,PWM波也是一個連續的方波,但在一個週期中,其高電平和低電平的duty
cycle是不同的。一個典型PWM的波形如圖所示。
在圖中,T是PWM波的週期,T1是高電平的寬度,Vcc是高電平值。當該PWM波通過一個積分器後(低通濾波器)後,我們可以得到其輸出的平均電壓為:
式中,T1/T稱為PWM波的duty cycle。控制調節和改變T1的寬度,即改變PWM的duty cycle,就可以的到不同的平均電壓輸出。因此在實際應用中,常利用PWM波的輸出,實現D/A轉換,調節電壓或電流控制改變馬達的轉速,實現變頻控制等功能。
一個PWM方波的參數有頻率、duty
cycle和相位(在一個PWN週期中,高低電平轉換的起始時間),其中頻率和duty
cycle為主要的參數。圖為3個duty
cycle都為2/3的PWM波形,儘管他們輸出的平均電壓是一樣的,但其中(b)的頻率比(a)高一倍,相位相同;而(c)與(a)的頻率相同,但相位不同。
在實際應用中,除了要考慮如何正確的控制和調整PWM波的duty
cycle,獲得達到要求的平均電壓的輸出外,還需要綜合的考慮PWM的週期、PWM波duty
cycle調節的精度(通常用BIT位表示)、積分器的設計等。而且這些因素相互之間也是互相牽連的。
根據PWM的特點,在使用ATmega128的定時/計數器設計輸出PWM時應注意以下幾點:
1.首先應根據實際的情況,確定需要輸出的PWM頻率範圍,這個頻率與控制的物件有關。如輸出PWM 波用於控制燈的亮度,由於人眼不能分辨42Hz以上的頻率,所以PWM的頻率應高於42Hz,否則人眼會察覺到燈的閃爍。
2. ATmega128的Timer/Count0和Timer/Coount2都具備產生PWM波的功能,由於它們計數器的長度為8位,所以是固定8位元精度的PWM波發生器。即PWM的調節精度為8位,因此PWM波的週期只能取決於系統時鐘和除頻係數(即作為計數器計數脈衝的頻率)。T/C0、T/C2的工作模式中有快速PWM模式(WGMn[1:0]=3)和相位可調PWM模式(WGMn[1:0]=1)兩種。
PWM模式可以分成快速PWM和相位調整PWM兩大類。
3.快速PWM模式可以的到比較高頻率、相位固定的PWM輸出,適合一些要求輸出PWM頻率較高,頻率相位固定的應用。快速PWM模式中,計數器僅工作在單程正向計數方式,計數器的上限值決定PWM的頻率,而比較匹配寄存器OCRn的值決定了duty
cycle的大小。快速PWM頻率的計算公式為:
(快速PWM模式)
PWM頻率 =
系統時鐘頻率/(除頻係數 *
256)
4. 快速PWM模式適合要求輸出PWM頻率較高,但頻率固定,duty
cycle調節精度要求不高的應用。
5.相位調整PWM模式的duty
cycle調節精度高,但輸出頻率比較低,因為此時計數器僅工作在雙向計數方式。同樣計數器的上限值決定了PWM的頻率,比較匹配寄存器的值決定了duty
cycle的大小。 PWM頻率的計算公式為:
(相位可調PWM模式) PWM頻率 =
系統時鐘頻率/(除頻係數 *
510)
6.相位調整PWM模式適合要求輸出PWM頻率較低,但頻率固定,duty
cycle調節精度要求高的應用。當調整duty
cycle時,PWM的相位也相應的跟著變化(Phase Correct)。
7.相位調整PWM模式適合要求輸出PWM頻率較低,輸出頻率需要變化,duty cycle調節精度要求高 的應用。此時應注意:不僅調整duty cycle時(改變OCR0的值),PWM的相位會相應的跟著變化(Phase Correct);而一但改變計數器上限值,即改變PWM的輸出頻率時,會使PWM的duty cycle和相位都相應的跟著變化。由於其產生的PWM波形是對稱的,更加適合在電機控制中使用。
T/CO、T/C
2兩種PWM模式都是固定8位元元的PWM,計數器TCNTn的上限值為固定的0xFF(8位T/C),而比較匹配寄存器OCRn的值與計數器上限值之比即為duty
cycle。
二、 PWM應用設計參考 下面給出一個設計示例,在示例中使用PWM方式來產生一個1KHz左右的正弦波,幅度為0-Vcc/2。
首先按照下面的公式建立一個正弦波樣本表,樣本表將一個正弦波週期分為128個點,每點按7位量化(127對應最高幅值Vcc/2):
f(x) = 64 + 63 * sin(2πx/128) x∈[0…127]
如果在一個正弦波週期中採用128個樣點,那麼對應1KHz的正弦波PWM的頻率為128KHz。實際上,按照採樣頻率至少為信號頻率的2倍的取樣定理來計算,PWM的頻率的理論值為2KHz即可。考慮儘量提高PWM的輸出精度,實際設計使用PWM的頻率為32KHz,即一個正弦波週期(1KHz)中輸出32個正弦波樣本值。這意味著在128點的正弦波樣本表中,每隔4點取出一點作為PWM的輸出。
程式中使用ATmega128的8位元Timer/Count0,工作模式為相位調整PWM模式輸出,系統時鐘為16MHz,分頻係數為1,其可以產生最高PWM頻率為: 16000000Hz / 510 = 31372Hz。每32次輸出構成一個週期正弦波,正弦波的頻率為980.4Hz。PWM由OC0(PB4)引腳輸出。
輸出波形
// Target :ATmega128
// Crystal: 16.0000Mhz
// IAR AVR compiler
#include "iom128.h"
#include "ina90.h"
#define ENABLE_BIT_DEFINITIONS //Enable bit definitions in I/O-Include files 啟用編譯開關
#define PRAGMA(x) _Pragma( #x )
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
#define SEI() __enable_interrupt() // enable interrupy
// Crystal: 16.0000Mhz
// IAR AVR compiler
#include "iom128.h"
#include "ina90.h"
#define ENABLE_BIT_DEFINITIONS //Enable bit definitions in I/O-Include files 啟用編譯開關
#define PRAGMA(x) _Pragma( #x )
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
#define SEI() __enable_interrupt() // enable interrupy
// 128點正弦波樣本表
__hugeflash const unsigned char auc_SinParam[128] = {
__hugeflash const unsigned char auc_SinParam[128] = {
64,67,70,73,76,79,82,85,88,91,94,96,99,102,104,106,109,111,113,115,117,118,120,121,
123,124,125,126,126,127,127,127,127,127,127,127,126,126,125,124,123,121,120,118,
117,115,113,111,109,106,104,102,99,96,94,91,88,85,82,79,76,73,70,67,64,60,57,54,51,48,
45,42,39,36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,1,0,0,0,0,0,0,0,1,1,2,3,4,6,
7,9,10,12,14,16,18,21,23,25,28,31,33,36,39,42,45,48,51,54,57,60};
unsigned char x_SW = 4, X_LUT = 0; //interrupt 必須使用golbal var
123,124,125,126,126,127,127,127,127,127,127,127,126,126,125,124,123,121,120,118,
117,115,113,111,109,106,104,102,99,96,94,91,88,85,82,79,76,73,70,67,64,60,57,54,51,48,
45,42,39,36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,1,0,0,0,0,0,0,0,1,1,2,3,4,6,
7,9,10,12,14,16,18,21,23,25,28,31,33,36,39,42,45,48,51,54,57,60};
unsigned char x_SW = 4, X_LUT = 0; //interrupt 必須使用golbal var
//ISR of TIMER0_OVF
#pragma vector=TIMER0_OVF_vect
__interrupt void handler_TIMER0_OVF_vect(void){
X_LUT += x_SW; // 新樣點指針
if (X_LUT > 127) X_LUT -= 128; // 樣點指針調整
OCR0 = auc_SinParam[X_LUT]; // 取樣點指針到比較匹配寄存器
}
void main(void)
{
DDRB |= 0x10; // PB4(OC0)輸出
TCCR0 = 0x61; //相位調整PWM模式,分頻係數=1,正向控制OC0
TIMSK = 0x01; // T/C0溢出中斷允許
SEI(); // enable全局中斷
while(1)
{……};
}
每次計數器溢出中斷的服務中取出一個正弦波的樣點值到比較匹配寄存器中,用於調整下一個PWM的脈衝寬度,這樣在PB4引腳上輸出了按正弦波調製的PWM方波。當PB4的輸出通過一個低通濾波器後,便得到一個980.4Hz的正弦波了。如要得到更精確的1KHz的正弦波,可使用定時/計數器T/C1,選擇工作模式10,設置ICR1=250為計數器的上限值。
在ATMEL公司網站上,給出了使用一個定時/計數器實現雙音頻撥號的應用設計參考(AVR314.pdf),讀者可以從中學習到如何更好設計和使用PWM的功能。
note:// 另一種ISR寫法,可以與GCC相容ISR(TIMER0_OVF_vect) //0x40 TIMER0_OVF_vect
{
X_LUT += x_SW; // 新樣點指針
if (X_LUT > 127) X_LUT -= 128; // 樣點指針調整
OCR0 = auc_SinParam[X_LUT]; // 取樣點指針到比較匹配寄存器}others Link:
At this link you can see a short video clip of "The Bug". The clip is filmed by Nicki and shows the robot completing the compulsory task as demanded by the specifications.
EX: PWM drive DC motor
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。