標(biāo)題: 單片機(jī)脈寬調(diào)制應(yīng)用-漸明漸暗的燈 [打印本頁(yè)]

作者: xiashan    時(shí)間: 2015-4-5 16:21
標(biāo)題: 單片機(jī)脈寬調(diào)制應(yīng)用-漸明漸暗的燈
PWM(Pulse Width Modulation)是脈沖寬度調(diào)制的英文單詞的縮寫。下面這段話是通信百科中對(duì)其的定義:
脈沖寬度調(diào)制(PWM)是利用微處理器的數(shù)字輸出來(lái)對(duì)模擬電路進(jìn)行控制的一種非常有效的技術(shù),廣泛應(yīng)用在從測(cè)量、通信到功率控制與變換的許多領(lǐng)域中。脈寬調(diào)制是開關(guān)型穩(wěn)壓電源中的術(shù)語(yǔ)。這是按穩(wěn)壓的控制方式分類的,除了PWM型,還有PFM型和PWM、PFM混合型。脈寬調(diào)制式開關(guān)型穩(wěn)壓電路是在控制電路輸出頻率不變的情況下,通過電壓反饋調(diào)整其占空比,從而達(dá)到穩(wěn)定輸出電壓的目的。
讀起來(lái)有點(diǎn)晦澀難懂。其實(shí)簡(jiǎn)單的說來(lái),PWM技術(shù)就是通過調(diào)整一個(gè)周期固定的方波的占空比,來(lái)調(diào)節(jié)輸出電壓的平均當(dāng)電壓,電流或者功率等被控量。我們可以用一個(gè)水龍頭來(lái)類比,把1S時(shí)間分成50等份,即每一個(gè)等份20MS。在這20MS時(shí)間里如果我們把水龍頭水閥一直打開,那么在這20MS里流過的水肯定是最多的,如果我們把水閥打開15MS,剩下的5MS關(guān)閉水閥,那么流出的水相比剛才20MS全開肯定要小的多。同樣的道理,我們可以通過控制20MS時(shí)間里水閥開啟的時(shí)間的長(zhǎng)短來(lái)控制流過的水的多少。那么在1S內(nèi)平均流出的水流量也就可以被控制了。
當(dāng)我們調(diào)整PWM的占空比時(shí),就會(huì)引起電壓或者電流的改變,LED的明暗狀態(tài)就會(huì)隨之發(fā)生相應(yīng)的變化,聽起來(lái)好像可以通過這種方法來(lái)實(shí)現(xiàn)我們想要的漸明漸暗的效果。讓我們來(lái)試一下吧。
大家都知道人眼有一個(gè)臨界頻率,當(dāng)LED的閃爍頻率達(dá)到一定的時(shí)候,人眼就分辨不出LED是否在閃爍了。就像我們平常看電視一樣,看起來(lái)畫面是連續(xù)的,實(shí)質(zhì)不是這個(gè)樣子,所有連續(xù)動(dòng)作都是一幀幀靜止的畫面在1S的時(shí)間里快速播放出來(lái),譬如每秒24幀的速度播放,由于人眼的視覺暫留效應(yīng),看起來(lái)畫面就是連續(xù)的了。同樣的道理,為了讓我們的LED在變化的過程中,我們感覺不到其在閃爍,可以將其閃爍的頻率定在50Hz以上。同時(shí)為了看起來(lái)明暗過渡的效果更加明顯,我們?cè)谶@里定義其變化范圍為0~99(100等分).即最亮的時(shí)候其灰度等級(jí)為99,為0的時(shí)候最暗,也就是熄滅了。
于是乎我們定義PWM的占空比上限為99, 下限定義為0
#define  LED_PWM_LIMIT_MAX    99
#define  LED_PWM_LIMIT_MIN      0

假定我們LED的閃爍頻率為50HZ,而亮度變化的范圍為0~99共100等分。則每一等分所占用的時(shí)間為 1/(50*100)  =  200us 即我們?cè)诟淖僉ED的亮滅狀態(tài)時(shí),應(yīng)該是在200us整數(shù)倍時(shí)刻時(shí)。在這里我們用單片機(jī)的定時(shí)器產(chǎn)生200us的中斷,同時(shí)每20MS調(diào)整一次LED的占空比。這樣在20MS * 100 = 2S的時(shí)間內(nèi)LED可以從暗逐漸變亮,在下一個(gè)2S內(nèi)可以從亮逐漸變暗,然后不斷循環(huán)。
由于大部分的內(nèi)容都可以在中斷中完成,因此,我們的大部分代碼都在Timer.c這個(gè)文件中編寫,主函數(shù)中除了初始化之外,就是一個(gè)空的死循環(huán)。






Timer.c內(nèi)容如下。
#include <reg52.h>
#include "MacroAndConst.h"

#define LED P0            //定義LED接口
#define LED_ON()      LED = 0x00 ;  //所有LED亮
#define LED_OFF()    LED = 0xff ;  //所有LED熄滅

#define  LED_PWM_LIMIT_MAX    99
#define  LED_PWM_LIMIT_MIN      0

static uint8 s_u8TimeCounter = 0 ; //中斷計(jì)數(shù)
static uint8 s_u8LedDirection = 0 ; //LED方向控制 0 :漸亮 1 :漸滅
static int8  s_s8LedPWMCounter  = 0 ; //LED占空比
void Timer0Init(void)
{
    TMOD &= 0xf0 ;
    TMOD |= 0x01 ;     //定時(shí)器0工作方式1
    TH0  =     0xff ;     //定時(shí)器初始值(200us中斷一次)
    TL0  =  0x47 ;
    TR0  = 1 ;
    ET0  = 1 ;
}

void Time0Isr(void) interrupt 1
{     
    static int8 s_s8PWMCounter = 0  ;
    TH0  =     0xff ;           //定時(shí)器重新賦初值
    TL0  =  0x47 ;

    if(++s_u8TimeCounter >= 100) //每20MS調(diào)整一下LED的占空比
    {
        s_u8TimeCounter = 0 ;
        //如果是漸亮方向變化,則占空比遞增
         if((s_s8LedPWMCounter <= LED_PWM_LIMIT_MAX) &&(0 == s_u8LedDirection))
        {
            s_s8LedPWMCounter++  ;
            if(s_s8LedPWMCounter > LED_PWM_LIMIT_MAX)
            {
                s_u8LedDirection = 1 ;
                s_s8LedPWMCounter =  LED_PWM_LIMIT_MAX ;               
            }            
        }
        //如果是漸暗方向變化,則占空比遞漸
                if((s_s8LedPWMCounter >= LED_PWM_LIMIT_MIN) &&(1 == s_u8LedDirection))
                                                                                                
        {
            s_s8LedPWMCounter-- ;
            if(s_s8LedPWMCounter < LED_PWM_LIMIT_MIN)
            {
                s_u8LedDirection = 0 ;
                s_s8LedPWMCounter =  LED_PWM_LIMIT_MIN ;               
            }   
        }
        s_s8PWMCounter = s_s8LedPWMCounter ;  //獲取LED的占空比
    }

    if(s_s8PWMCounter > 0) //占空比大于0,則點(diǎn)亮LED,否則熄滅LED
    {
        LED_ON() ;
        s_s8PWMCounter-- ;
    }
    else
    {
        LED_OFF();   
    }

}


其實(shí)PWM技術(shù)在我們實(shí)際生活中應(yīng)用的非常多。比較典型的應(yīng)用就是控制電機(jī)的轉(zhuǎn)速,控制充電電流的大小,等等。而隨著技術(shù)的發(fā)展,也出現(xiàn)了其他類型的PWM技術(shù),如相電壓PWM,線電壓PWM,SPWM等等,如果有興趣可以到網(wǎng)上去獲取相應(yīng)資料學(xué)習(xí)。


作者: 184890962    時(shí)間: 2016-3-18 09:28
你好,請(qǐng)教下想在20S完成漸變,怎么調(diào)時(shí)間,我怎么調(diào)亮度變化值到0-400總時(shí)間怎么和0-100一樣
作者: 184890962    時(shí)間: 2016-3-18 09:28
你好,請(qǐng)教下想在20S完成漸變,怎么調(diào)時(shí)間,我怎么調(diào)亮度變化值到0-400總時(shí)間怎么和0-100一樣
作者: 184890962    時(shí)間: 2016-3-18 09:28
你好,請(qǐng)教下想在20S完成漸變,怎么調(diào)時(shí)間,我怎么調(diào)亮度變化值到0-400總時(shí)間怎么和0-100一樣

作者: 184890962    時(shí)間: 2016-3-18 09:28
你好,請(qǐng)教下想在20S完成漸變,怎么調(diào)時(shí)間,我怎么調(diào)亮度變化值到0-400總時(shí)間怎么和0-100一樣

作者: 184890962    時(shí)間: 2016-3-18 09:29
你好,請(qǐng)教下想在20S完成漸變,怎么調(diào)時(shí)間,我怎么調(diào)亮度變化值到0-400總時(shí)間怎么和0-100一樣

作者: 田贏洲    時(shí)間: 2016-3-20 12:18
你好,請(qǐng)教下想在20S完成漸變,怎么調(diào)時(shí)間,我怎么調(diào)亮度變化值到0-400總時(shí)間怎么和0-100一樣
作者: Aizlna    時(shí)間: 2021-9-26 23:55
變量名太長(zhǎng)了,看起來(lái)真費(fèi)勁




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1