基于STC15L104E單片機(jī)模擬PWM調(diào)光小夜燈
//讀取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();
}
//寫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()
{
//因?yàn)槟J角袚Q無非是改變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; //清除低電壓標(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();
}
//如果比較值改變了,而且只是上升沿和下降沿,則寫入EEPROM
//因?yàn)镋EPROM操作時(shí)間較長(zhǎng),所以如果每次改變都寫入,則在長(zhǎng)按狀態(tài)下會(huì)出現(xiàn)閃爍現(xiàn)象
//所以只在單次按下或按鍵長(zhǎng)按釋放時(shí)寫入EEPROM
if((pwm_cmp^cmp_temp)&&(key_down|key_up))
{
//關(guān)停LED再做寫入操作,如果寫入操作前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); //開
else
P3|=0x0c; //關(guān)
if(pwm_num>200) //PWM周期
{
pwm_num=0;
pwm_delay++;
}
}
這里要說說程序下載的問題,因?yàn)檫@片單片機(jī)是沒有外部晶振的,所以下載時(shí)要確認(rèn)單片機(jī)完全掉電,就連串口的GND端都要從電路板上拔出.下載軟件我用的是STC-ISP V4.88 beta版本,下載時(shí)選好型號(hào),然后修改最低波特率為2400,在我實(shí)際應(yīng)用中,默認(rèn)的4800是寫不進(jìn)去的,RC頻率按自己要求修改,其他的默認(rèn)就好了.單片機(jī)如果第一次寫可能要將P3.2和P3.3接GND,如果勾選<下次冷啟動(dòng)P3.2/P3.3與下載無關(guān)>(默認(rèn)),那以后就不用在乎它們的狀態(tài)了.
關(guān)鍵詞:
STC15L104E單片機(jī)模擬PWM調(diào)光小夜
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論