新聞中心

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

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

作者: 時(shí)間:2016-11-25 來(lái)源:網(wǎng)絡(luò) 收藏
//讀取EEPROM,因?yàn)镋EPROM只存兩個(gè)變量,故讀取直接改變變量
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();
}
//寫(xiě)EEPROM
void write_eeprom(unsigned int add,unsigned char dat)
{
if(PCON&0x20)return; //如果電壓過(guò)低,不操作
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()
{
//因?yàn)槟J角袚Q無(wú)非是改變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); //將模式寫(xiě)入EEPROM
while((key_cont&0x03)==0x03); //直到按鍵釋放
}
void main()
{
P3M1=0x0f;
P3M0=0x0f; //P3為開(kāi)漏模式
PCON=0x00; //清除低電壓標(biāo)志(必須)
LED2=LED1=OFF;
read_eeprom(); //讀取狀態(tài)
timer_init(); //計(jì)數(shù)器初始化
cmp_temp=pwm_cmp;
while(1)
{
cmp_temp=pwm_cmp; //儲(chǔ)存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) //延時(shí),延時(shí)時(shí)間為PWM周期*30
{
//如果按鍵長(zhǎng)按,則每次延時(shí)周期自加減,實(shí)現(xiàn)長(zhǎng)按快速調(diào)光
if((key_cont&0x01)&&(pwm_cmp<180))
pwm_cmp++;
if((key_cont&0x02)&&(pwm_cmp>1))
pwm_cmp--;
pwm_delay=0; //重新計(jì)時(shí)
//如果兩個(gè)按鍵都是按下的,則改變模式
if((key_cont&0x03)==0x03)model_change();
}
//如果比較值改變了,而且只是上升沿和下降沿,則寫(xiě)入EEPROM
//因?yàn)镋EPROM操作時(shí)間較長(zhǎng),所以如果每次改變都寫(xiě)入,則在長(zhǎng)按狀態(tài)下會(huì)出現(xiàn)閃爍現(xiàn)象
//所以只在單次按下或按鍵長(zhǎng)按釋放時(shí)寫(xiě)入EEPROM
if((pwm_cmp^cmp_temp)&&(key_down|key_up))
{
//關(guān)停LED再做寫(xiě)入操作,如果寫(xiě)入操作前LED為亮的狀態(tài)
//則在整個(gè)EEPROM操作時(shí)間里L(fēng)ED都為亮,故出現(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; //按鍵長(zhǎng)效值
pwm_num++; //PWM周期數(shù)自加
if(pwm_num //控制PWM輸出
P3&=(0xf3|led_model); //開(kāi)
else
P3|=0x0c; //關(guān)
if(pwm_num>200) //PWM周期
{
pwm_num=0;
pwm_delay++;
}
}
這里要說(shuō)說(shuō)程序下載的問(wèn)題,因?yàn)檫@片單片機(jī)是沒(méi)有外部晶振的,所以下載時(shí)要確認(rèn)單片機(jī)完全掉電,就連串口的GND端都要從電路板上拔出.下載軟件我用的是STC-ISP V4.88 beta版本,下載時(shí)選好型號(hào),然后修改最低波特率為2400,在我實(shí)際應(yīng)用中,默認(rèn)的4800是寫(xiě)不進(jìn)去的,RC頻率按自己要求修改,其他的默認(rèn)就好了.單片機(jī)如果第一次寫(xiě)可能要將P3.2和P3.3接GND,如果勾選<下次冷啟動(dòng)P3.2/P3.3與下載無(wú)關(guān)>(默認(rèn)),那以后就不用在乎它們的狀態(tài)了.
好了,程序也貼了,也沒(méi)什么可以供我訴說(shuō)的了,實(shí)物太丑陋,就不貼了.

上一頁(yè) 1 2 下一頁(yè)

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉