PWM(Pulse Width Modulation),一般指脈沖寬度調(diào)節(jié),是利用微處理器的數(shù)字輸出來對(duì)模擬電路進(jìn)行控制的一種非常有效的技術(shù),廣泛應(yīng)用在從測(cè)量、通信到功率控制與變換的許多領(lǐng)域中,比如LED亮度調(diào)節(jié)、電機(jī)轉(zhuǎn)速控制等。
而在某些特殊應(yīng)用中,我們也需要通過測(cè)量輸入PWM的占空比,來實(shí)現(xiàn)不同的輸出控制,這就需要使用到PWM占空比的測(cè)量方法。這里介紹三種不同的測(cè)量方法:阻塞方式、中斷方式以及定時(shí)器捕獲功能。
1. 阻塞方式
MCU阻塞方式測(cè)量PWM占空比的原理比較簡(jiǎn)單,也只需要使用到一個(gè)普通的IO端口(設(shè)置為輸入模式,對(duì)于51而言那就是一個(gè)普通的雙向口具體實(shí)現(xiàn)流程為:
等待上升沿到來,然后開啟定時(shí)器,開始計(jì)時(shí);
等待下降沿到來,記錄下定時(shí)器的計(jì)數(shù)值,即得到PWM的高電平時(shí)間H;
同時(shí),清零定時(shí)器,重新開始計(jì)數(shù);
等待上升沿到來,記錄下定時(shí)器的計(jì)數(shù)值,即得到PWM的低電平時(shí)間L;
計(jì)算得出占空比:duty = H / (H + L);
阻塞方式原理簡(jiǎn)單,而且只需要MCU有一個(gè)定時(shí)器的資源即可實(shí)現(xiàn);但采集時(shí)阻塞CPU運(yùn)行,阻塞的時(shí)間和輸入PWM的周期相關(guān),只適用于實(shí)時(shí)性較低的系統(tǒng)。
另外,上述流程中存在著一個(gè)嚴(yán)重的BUG,即當(dāng)輸入的PWM占空比為0%或者100%時(shí),程序會(huì)被一直阻塞,等待上升沿/下降沿的到來。所以解決方法是,在等待上升沿/下降沿的過程中,實(shí)時(shí)提取定時(shí)器的值,一旦定時(shí)時(shí)間超過1個(gè)周期的限定(一般可定義為2-3個(gè)周期時(shí)間),即退出等待,并根據(jù)端口電平判斷此時(shí)占空比為0%(低電平)或100%(高電平)。
示例代碼,僅供參考:
//獲取PWM輸入腳的電平
#define PWM_IN() xxxxxx
//定義超時(shí)時(shí)間(如2-3倍PWM周期)
#define T1_TIMEOUT xxxxxx
uint8_t PWM_Analyse(void)
{
uint8_t duty = 0xFF;
uint16_t pwm_H = 0;
uint16_t pwm_L = 0;
if (PWM_IN()) //初始為高電平,則開始等待低電平
{
TH1 = 0;
while (PWM_IN()) //等待下降沿
{
if (TH1 》= T1_TIMEOUT) //下降沿沒有到來,判定為100%占空比
{
duty = 100;
return duty;
}
}
TH1 = 0;
TL1 = 0;
while (!PWM_IN()) //等待上升沿
{
if (TH1 》= T1_TIMEOUT) //上升沿沒有到來,判定為0%占空比
{
duty = 0;
return duty;
}
}
pwm_L = (TH1 《《 8) | TL1;
TH1 = 0;
TL1 = 0;
while (PWM_IN()) //等待下降沿
{
if (TH1 》= T1_TIMEOUT) //下降沿沒有到來,判定為100%占空比
{
duty = 100;
return duty;
}
}
pwm_H = (TH1 《《 8) | TL1;
duty = pwm_H * 100 / (pwm_H + pwm_L);
return duty;
}
else //當(dāng)前為低電平,則開始等待高電平
{
TH1 = 0;
while (!PWM_IN()) //等待上升沿
{
if (TH1 》= T1_TIMEOUT) //上升沿沒有到來,判定為0%占空比
{
duty = 0;
return duty;
}
}
TH1 = 0;
TL1 = 0;
while (PWM_IN()) //等待下降沿
{
if (TH1 》= T1_TIMEOUT) //下降沿沒有到來,判定為100%占空比
{
duty = 100;
return duty;
}
}
pwm_H = (TH1 《《 8) | TL1;
TH1 = 0;
TL1 = 0;
while (!PWM_IN()) //等待上升沿
{
if (TH1 》= T1_TIMEOUT) //上升沿沒有到來,判定為0%占空比
{
duty = 0;
return duty;
}
}
pwm_L = (TH1 《《 8) | TL1;
duty = pwm_H * 100 / (pwm_H + pwm_L);
return duty;
}
return 0xFF;
}
2. 中斷方式
中斷方式的PWM采集原理與阻塞方式相同,只是將判定移動(dòng)至外部中斷中。開啟MCU端口的外部中斷(上升沿和下降沿中斷);如果MCU外部中斷觸發(fā)不支持上升和下降沿中斷,則先開啟上升沿中斷,在中斷處理中切換中斷觸發(fā)條件。
處理方法:在中斷處理函數(shù)中,根據(jù)當(dāng)前電平狀態(tài),記錄下定時(shí)器的值,并清零定時(shí)器的值,重新開始下一輪計(jì)時(shí)。
0%和100%的處理:設(shè)定一個(gè)定時(shí)遞增的變量,同時(shí)在外部中斷中執(zhí)行清零操作。若該變量超過一定值(說明外部中斷有較長(zhǎng)時(shí)間沒有觸發(fā)),則判定為0%或100%。
uint16_t pwm_H = 0;
uint16_t pwm_L = 0;
uint16_t pwm_time_out = 0;
void EXT1_ISR(void) interrupt EXTI1_VECTOR
{
if (PWM_IN())
{
pwm_L = (TH1 《《 8) | TL1; //記錄低電平時(shí)間
TH1 = 0;
TL1 = 0;
}
else
{
pwm_H = (TH1 《《 8) | TL1; //記錄高電平時(shí)間
TH1 = 0;
TL1 = 0;
}
//該變量定時(shí)遞增(如1ms遞增1),在外部中斷中清零
//在主程序中判斷,超過一定值時(shí)認(rèn)為PWM占空比為0%或100%
pwm_time_out = 0;
return;
}
注:使用中斷方式,則占空比計(jì)算不建議放在中斷中處理;同時(shí),為了保證占空比的準(zhǔn)確性,可以連續(xù)2-3次計(jì)算結(jié)果一致時(shí),再確定當(dāng)前占空比的結(jié)果。
3. MCU捕獲方式
采用捕獲方式的前提是MCU支持捕獲功能。當(dāng)前部分廠家推出的51內(nèi)核單片機(jī),會(huì)包含一個(gè)定時(shí)器2,其擁有捕獲功能;或者采用32位單片機(jī),一般都帶有捕獲功能。捕獲的原理很簡(jiǎn)單,當(dāng)上升沿或下降沿來臨時(shí),MCU硬件將定時(shí)器/計(jì)數(shù)器的值保存在一個(gè)影子寄存器中,并產(chǎn)生捕獲中斷。
通過固定每次上升/下降沿的計(jì)數(shù)器值,相減即可分別得出高電平值和低電平值,從而計(jì)算出占空比。
下面以某顆51內(nèi)核的MCU為例,提供示例代碼:
unsigned int pwm_fall = 0, pwm_rise = 0;
volatile unsigned int pwm_H;
volatile unsigned int pwm_L;
volatile unsigned char pwm_time_out;
//------------------------------------------------------------
void T2_interrupt(void) interrupt 5 //定時(shí)器2中斷;
{
if (CCCON & 0x02) //CC1中斷標(biāo)志位
{
CCCON &= 0xFD; //清除中斷標(biāo)志
if (PWM_IN()) //上升沿觸發(fā)
{
pwm_rise = CC1; //獲取捕獲寄存器中的值
pwm_L = pwm_rise - pwm_fall;
}
else
{
pwm_fall = CC1; //獲取捕獲寄存器中的值
pwm_H = pwm_fall - pwm_rise;
}
//該變量定時(shí)遞增(如1ms遞增1),在外部中斷中清零
//在主程序中判斷,超過一定值時(shí)認(rèn)為PWM占空比為0%或100%
pwm_time_out = 0;
}
}
注: pwm_rise/pwm_fall/pwm_L/pwm_H都必須使用無符號(hào)數(shù),否則相減時(shí)可能得到錯(cuò)誤的值。
總結(jié)
方式一:任何單片機(jī)都可以實(shí)現(xiàn),但是阻塞方式會(huì)使系統(tǒng)的實(shí)時(shí)性變差;
方式二:在使用時(shí),需要保證外部中斷的最高優(yōu)先級(jí),不可以被其他中斷打斷,以保證其準(zhǔn)確性;
方式三:的穩(wěn)定性和準(zhǔn)確性都較高,但是需要MCU硬件支持。
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/crazy_kismet/article/details/102756206
審核編輯:何安
-
單片機(jī)
+關(guān)注
關(guān)注
6040文章
44594瀏覽量
636941 -
PWM
+關(guān)注
關(guān)注
114文章
5196瀏覽量
214373 -
占空比
+關(guān)注
關(guān)注
0文章
109瀏覽量
29126
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論