<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        單片機PWM技術實現呼吸燈和KTV等娛樂場所的燈光閃爍效果

        作者:寒竹子   來源:本站原創   點擊數:  更新時間:2014年04月15日   【字體:

        程序是在51hei單片機開發板上面做的,電路很簡單,最小系統+P0的八個led即可.ADDR0和ENLED那是開發板上的led使能電路控制端,如果是你自己做的電路 可以刪掉這幾個語句.或者不用管他,不會影響程序的運行.

        /**
          ************************************************************************************************************
          * @file   :      main.c 
          * @author :      xr
          * @date   :      2014年4月15日20:34:05 - 2014年4月15日22:28:08
          * @version: V1.2.3
          * @brief  :      PWM技術實現呼吸燈和KTV等娛樂場所的燈光閃爍效果 單片機STC89C52RC MCU 晶振 11.0592MHZ
          ************************************************************************************************************
          */
        #include <reg52.h>

        //74HC138
        sbit ADDR0 = P1^0;
        sbit ADDR1 = P1^1;
        sbit ADDR2 = P1^2;
        sbit ADDR3 = P1^3;
        sbit ENLED = P1^4;

        //sbit PWMOUT = P0^0;//PWM輸出
        #define PWMOUT P0   //8個LED小燈同時呼吸

        //燈光控制編碼(調整PWM的占空比)
        unsigned char code PWM_Table[] = {
          1,  3,  8,  11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50,
          53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 95, 98, 99
        }; //34個占空比

        unsigned char heighHR0, heighLR0;//PWM高電平計數初值的高字節和低字節
        unsigned char lowHR0, lowLR0;   //PWM低電平計數初值的高字節和低字節
        unsigned char thr1, tlr1;       //T1計數初值高字節和低字節
        unsigned long PWMCounter = 0;      //PWM設定頻率后的對應的所需計數值 UL型

        void Initial();
        void ConfigPWM(unsigned int fr, unsigned char dc);
        void ConfigTimer1(unsigned int xms);

        void main(void)
        {
        Initial();
        /**********呼吸燈效果***************/
        ConfigPWM(100, 5);//設定PWM的脈沖寬度為100hz,即10ms,占空比為5%,當PWM的脈沖寬度小于100HZ時,形成的是閃爍的燈光效果
        ConfigTimer1(50);  //定時50ms調整PWM占空比

        /*PWM技術實現KTV等娛樂場所的燈光閃爍效果*/
        /***************燈光閃爍****************/
        /*
        ConfigPWM(10, 5); //PWM脈沖寬度為10HZ,即1ms, 占空比5%
        ConfigTimer1(50); //定時20ms調整PWM占空比
        */

        while (1);
        }

        /*初始化*/
        void Initial()
        {
        ADDR3 = 1;
        ENLED = 0;//選擇LED

        ADDR2 = 1;
        ADDR1 = 1;
        ADDR0 = 0;//選擇LEDS6,即流水燈
        }

        /*使用定時器T0配置PWM*/
        void ConfigPWM(unsigned int fr, unsigned char dc) //參數:fr PWM配置的頻率,當是100時,即是100HZ,周期是10ms,dc為占空比
        {
        unsigned long tmp;
        unsigned int heigh, low;//分別存放高電平計數值和低電平計數值

        tmp = 11059200/12;//一個機器周期的計數頻率
        PWMCounter = tmp / fr;//一個機器周期計數頻率是多少個fr計數頻率,即fr頻率需要的計數值
        heigh = (PWMCounter * dc) / 100;//高電平所需計數值 1/fr周期內高電平計數值
        low   = PWMCounter - heigh;//低電平所需計數值  1/fr周期內低電平計數值
        heigh = 65536-heigh;       //高電平時定時器需要裝入的初值
        low   = 65536-low;    //低電平時定時器需要裝入的初值

        heighHR0 = (unsigned char)(heigh >> 8);
        heighLR0 = (unsigned char)heigh;
        lowHR0   = (unsigned char)(low >> 8);
        lowLR0   = (unsigned char)low;

        TMOD &= 0xF0;//清零T0控制位
        TMOD |= 0x01;//Timer0方式1,16位可設定定時模式
        TH0 = heighHR0;
        TL0 = heighLR0;//裝入高電平時的初值
        PWMOUT = 0xFF;//開始PWM輸出高電平
        TR0 = 1;//啟動定時器T0
        ET0 = 1;//開啟T0中斷
        EA  = 1;//開總中斷
        }

        /*配置定時器Timer1,用于定時xms調整PWM的占空比*/
        void ConfigTimer1(unsigned int xms)
        {
        unsigned long tmp;
        tmp = 11059200/12;//一個機器周期的計數頻率
        tmp = (tmp * xms) /1000;//定時xms需要的計數頻率(即計數次數)
        tmp = 65536-tmp;//定時xms需要裝入的計數初值
        thr1 = (unsigned char)(tmp >> 8);//取高八位
        tlr1 = (unsigned char)tmp;

        TMOD &= 0x0F;//清零T1控制位
        TMOD |= 0x10;//定時器T1方式1,16位可設定時器
        TH1 = thr1;
        TL1 = tlr1;
        TR1 = 1;//啟動timer1
        ET1 = 1;//開啟定時器T1中斷
        EA  = 1;//開啟總中斷
        }

        /*調整PWM占空比*/
        void AdjustPWMdc(unsigned char dc)
        {
        unsigned int heigh, low;
        heigh = (PWMCounter * dc) / 100; //PWM脈沖中高脈沖所需計數值
        low   = PWMCounter - heigh;//PWM脈沖中低脈沖所需的計數值
        heigh = 65536-heigh;//高脈沖裝入計數的初值
        low   = 65536-low;  //低脈沖裝入計數的初值

        /*調整PWM高低脈沖計數初值,來調整PWM的占空比*/
        heighHR0 = (unsigned char)(heigh >> 8);
        heighLR0 = (unsigned char)heigh;
        lowHR0   = (unsigned char)(low >> 8);
        lowLR0   = (unsigned char)low;
        }

        /*定時器Timer0中斷服務*/
        void Timer0_ISP() interrupt 1
        {
        //在中斷中對PWM的輸出電平進行判斷,若當前輸出是高電平,則開始裝入低電平的計數初值,PWM輸出低電平
        if (PWMOUT)
        {
        //Timer0裝入PWM一個周期中低脈沖的計數初值
        TH0 = lowHR0;
        TL0 = lowLR0;
        PWMOUT = 0x00;//PWM輸出低電平
        }
        else  //否則裝入高電平的計數初值,輸出高電平
        {
        //Timer0裝入PWM一個周期中高脈沖的計數初值
        TH0 = heighHR0;
        TL0 = heighLR0;
        PWMOUT = 0xFF;//PWM輸出高脈沖
        }
        }

        /*定時器Timer1中斷服務*/
        void Timer1_ISP() interrupt 3
        {
        //注意:index和dir在每次進入中斷后都要使用上一次的值,因此必須定義為靜態類型
        static unsigned char index = 0;//占空比索引
        static bit dir = 0;//方向位,0燈光由亮->暗 1燈光由暗->亮

        TH1 = thr1;
        TL1 = tlr1;

        AdjustPWMdc(PWM_Table[index]);//調用調整PWM占空比函數,調整PWM占空比

        if (dir == 0)
        {
        index++;   //索引++
        if (index >= 33)     //34個占空比
        {
        index = 33;
        dir = 1;//改變方向
        }
        }
        else
        {
        index--; //索引--
        if (index == 0)
        {
        index = 0;
        dir = 0;//改變方向
        }
        }
        }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮