新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 基于STC15L104E單片機模擬PWM調(diào)光小夜燈

        基于STC15L104E單片機模擬PWM調(diào)光小夜燈

        作者: 時間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
        //讀取EEPROM,因為EEPROM只存兩個變量,故讀取直接改變變量
        void read_eeprom()
        {
        IAP_CONTR=0x83;
        IAP_CMD =0x01;
        IAP_ADDRL=MODEL_ADDR;
        IAP_ADDRH=MODEL_ADDR>>8;
        IAP_TRIG =0x5a;
        IAP_TRIG =0xa5;
        _nop_();_nop_();_nop_();
        led_model=IAP_DATA;
        IAP_CMD =0x01;
        IAP_ADDRL=PWM_CMP_ADDR;
        IAP_ADDRH=PWM_CMP_ADDR>>8;
        IAP_TRIG =0x5a;
        IAP_TRIG =0xa5;
        _nop_();_nop_();_nop_();
        pwm_cmp=IAP_DATA;
        if(pwm_cmp>180)pwm_cmp=0x01;
        eeprom_dle();
        }
        //寫EEPROM
        void write_eeprom(unsigned int add,unsigned char dat)
        {
        if(PCON&0x20)return; //如果電壓過低,不操作
        eeprom_erase(add);
        IAP_CONTR =0x83;
        IAP_CMD =0x02;
        IAP_ADDRL =add;
        IAP_ADDRH =add>>8;
        IAP_DATA =dat;
        IAP_TRIG =0x5a;
        IAP_TRIG =0xa5;
        _nop_();_nop_();_nop_();
        eeprom_dle();
        }
        //模式切換
        void model_change()
        {
        //因為模式切換無非是改變P3^2,P3^3狀態(tài)而led_model是直接賦值給P3的(在T0中斷函數(shù)里)
        //所以相應(yīng)的只改變led_model相應(yīng)位即可
        led_model+=4;
        write_eeprom(MODEL_ADDR,led_model); //將模式寫入EEPROM
        while((key_cont&0x03)==0x03); //直到按鍵釋放
        }
        void main()
        {
        P3M1=0x0f;
        P3M0=0x0f; //P3為開漏模式
        PCON=0x00; //清除低電壓標志(必須)
        LED2=LED1=OFF;
        read_eeprom(); //讀取狀態(tài)
        timer_init(); //計數(shù)器初始化
        cmp_temp=pwm_cmp;
        while(1)
        {
        cmp_temp=pwm_cmp; //儲存pwm比較值
        if((key_down&0x01)&&(pwm_cmp<180))
        {
        //如果KEY1按下,比較值加一,相應(yīng)的是LED變亮
        pwm_cmp++;
        pwm_delay=0;
        }
        if((key_down&0x02)&&(pwm_cmp>1))
        {
        //如果KEY2按下,比較值減一,相應(yīng)的是LED變暗
        pwm_cmp--;
        pwm_delay=0;
        }
        if(pwm_delay>30) //延時,延時時間為PWM周期*30
        {
        //如果按鍵長按,則每次延時周期自加減,實現(xiàn)長按快速調(diào)光
        if((key_cont&0x01)&&(pwm_cmp<180))
        pwm_cmp++;
        if((key_cont&0x02)&&(pwm_cmp>1))
        pwm_cmp--;
        pwm_delay=0; //重新計時
        //如果兩個按鍵都是按下的,則改變模式
        if((key_cont&0x03)==0x03)model_change();
        }
        //如果比較值改變了,而且只是上升沿和下降沿,則寫入EEPROM
        //因為EEPROM操作時間較長,所以如果每次改變都寫入,則在長按狀態(tài)下會出現(xiàn)閃爍現(xiàn)象
        //所以只在單次按下或按鍵長按釋放時寫入EEPROM
        if((pwm_cmp^cmp_temp)&&(key_down|key_up))
        {
        //關(guān)停LED再做寫入操作,如果寫入操作前LED為亮的狀態(tài)
        //則在整個EEPROM操作時間里LED都為亮,故出現(xiàn)"爆閃"現(xiàn)象
        EA=0;
        P3|=0x0c;
        write_eeprom(PWM_CMP_ADDR,pwm_cmp);
        EA=1;
        }
        }
        }
        void timer0() interrupt 1
        {
        unsigned char read_data=(P3&0x03)^0x03; //按鍵掃描
        key_down=read_data&(read_data^key_cont); //按鍵上升沿
        key_up=key_cont&(read_data^key_cont); //按鍵下降沿
        key_cont=read_data; //按鍵長效值
        pwm_num++; //PWM周期數(shù)自加
        if(pwm_num //控制PWM輸出
        P3&=(0xf3|led_model); //開
        else
        P3|=0x0c; //關(guān)
        if(pwm_num>200) //PWM周期
        {
        pwm_num=0;
        pwm_delay++;
        }
        }
        這里要說說程序下載的問題,因為這片單片機是沒有外部晶振的,所以下載時要確認單片機完全掉電,就連串口的GND端都要從電路板上拔出.下載軟件我用的是STC-ISP V4.88 beta版本,下載時選好型號,然后修改最低波特率為2400,在我實際應(yīng)用中,默認的4800是寫不進去的,RC頻率按自己要求修改,其他的默認就好了.單片機如果第一次寫可能要將P3.2和P3.3接GND,如果勾選<下次冷啟動P3.2/P3.3與下載無關(guān)>(默認),那以后就不用在乎它們的狀態(tài)了.
        好了,程序也貼了,也沒什么可以供我訴說的了,實物太丑陋,就不貼了.

        上一頁 1 2 下一頁

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 红安县| 江永县| 张家港市| 德化县| 甘孜| 土默特右旗| 高唐县| 财经| 德安县| 浦县| 蓬溪县| 进贤县| 潜山县| 崇左市| 深州市| 拉孜县| 华宁县| 古丈县| 鹰潭市| 阿拉善左旗| 灵武市| 乌苏市| 宁南县| 大足县| 包头市| 贞丰县| 昆山市| 弥渡县| 塔河县| 京山县| 青铜峡市| 姜堰市| 肇庆市| 台江县| 彰化市| 嫩江县| 北安市| 昌图县| 太原市| 嘉义县| 库尔勒市|