基于STC15L104E单片机模拟PWM调光小夜灯
IAP_ADDRH=MODEL_ADDR>>
IAP_ADDRH=PWM_CMP_ADDR>>
if(pwm_cmp>
IAP_TRIG
IAP_TRIG
_nop_();_nop_();_nop_();
eeprom_dle();
}
//模式切换
void model_change()
{
//因为模式切换无非是改变P3^2,P3^3状态而led_model是直接赋值给P3的(在T0中断函数里)
//所以相应的只改变led_model相应位即可
led_model+=4;
write_eeprom(MODEL_ADDR,led_model); //将模式写入EEPROM
while((key_cont&0x03)==0x03); //直到按键释放
}
void main()
{
P3M1=0x0f;
P3M0=0x0f;
PCON=0x00;
LED2=LED1=OFF;
read_eeprom();
timer_init();
cmp_temp=pwm_cmp;
while(1)
{
cmp_temp=pwm_cmp; //储存pwm比较值
if((key_down&0x01)&&(pwm_cmp<180))
{
//如果KEY1按下,比较值加一,相应的是LED变亮
pwm_cmp++;
pwm_delay=0;
}
if((key_down&0x02)&&(pwm_cmp>1))
{
//如果KEY2按下,比较值减一,相应的是LED变暗
pwm_cmp--;
pwm_delay=0;
}
if(pwm_delay>30)
{
//如果按键长按,则每次延时周期自加减,实现长按快速调光
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操作时间较长,所以如果每次改变都写入,则在长按状态下会出现闪烁现象
//所以只在单次按下或按键长按释放时写入EEPROM
if((pwm_cmp^cmp_temp)&&(key_down|key_up))
{
//关停LED再做写入操作,如果写入操作前LED为亮的状态
//则在整个EEPROM操作时间里LED都为亮,故出现"爆闪"现象
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); //按键下降沿
pwm_num++; //PWM周期数自加
if(pwm_num //控制PWM输出
P3&=(0xf3|led_model); //开
else
P3|=0x0c; //关
if(pwm_num>200) //PWM周期
{
pwm_num=0;
pwm_delay++;
}
}
这里要说说程序下载的问题,因为这片单片机是没有外部晶振的,所以下载时要确认单片机完全掉电,就连串口的GND端都要从电路板上拔出.下载软件我用的是STC-ISP V4.88 beta版本,下载时选好型号,然后修改最低波特率为2400,在我实际应用中,默认的4800是写不进去的,RC频率按自己要求修改,其他的默认就好了.单片机如果第一次写可能要将P3.2和P3.3接GND,如果勾选<下次冷启动P3.2/P3.3与下载无关>(默认),那以后就不用在乎它们的状态了.
好了,程序也贴了,也没什么可以供我诉说的了,实物太丑陋,就不贴了.
STC15L104E单片机模拟PWM调光小夜 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)