找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5093|回復: 7
打印 上一主題 下一主題
收起左側

單片機脈寬調制應用-漸明漸暗的燈

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

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






Timer.c內容如下。
#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 ; //中斷計數(shù)
static uint8 s_u8LedDirection = 0 ; //LED方向控制 0 :漸亮 1 :漸滅
static int8  s_s8LedPWMCounter  = 0 ; //LED占空比
void Timer0Init(void)
{
    TMOD &= 0xf0 ;
    TMOD |= 0x01 ;     //定時器0工作方式1
    TH0  =     0xff ;     //定時器初始值(200us中斷一次)
    TL0  =  0x47 ;
    TR0  = 1 ;
    ET0  = 1 ;
}

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

    if(++s_u8TimeCounter >= 100) //每20MS調整一下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,則點亮LED,否則熄滅LED
    {
        LED_ON() ;
        s_s8PWMCounter-- ;
    }
    else
    {
        LED_OFF();   
    }

}


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

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:109460 發(fā)表于 2016-3-18 09:28 | 只看該作者
你好,請教下想在20S完成漸變,怎么調時間,我怎么調亮度變化值到0-400總時間怎么和0-100一樣
回復

使用道具 舉報

板凳
ID:109460 發(fā)表于 2016-3-18 09:28 | 只看該作者
你好,請教下想在20S完成漸變,怎么調時間,我怎么調亮度變化值到0-400總時間怎么和0-100一樣
回復

使用道具 舉報

地板
ID:109460 發(fā)表于 2016-3-18 09:28 | 只看該作者
你好,請教下想在20S完成漸變,怎么調時間,我怎么調亮度變化值到0-400總時間怎么和0-100一樣
回復

使用道具 舉報

5#
ID:109460 發(fā)表于 2016-3-18 09:28 | 只看該作者
你好,請教下想在20S完成漸變,怎么調時間,我怎么調亮度變化值到0-400總時間怎么和0-100一樣
回復

使用道具 舉報

6#
ID:109460 發(fā)表于 2016-3-18 09:29 | 只看該作者
你好,請教下想在20S完成漸變,怎么調時間,我怎么調亮度變化值到0-400總時間怎么和0-100一樣
回復

使用道具 舉報

7#
ID:96172 發(fā)表于 2016-3-20 12:18 | 只看該作者
你好,請教下想在20S完成漸變,怎么調時間,我怎么調亮度變化值到0-400總時間怎么和0-100一樣
回復

使用道具 舉報

8#
ID:540334 發(fā)表于 2021-9-26 23:55 來自手機 | 只看該作者
變量名太長了,看起來真費勁
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表