前言
到了本系列的一个终结了。前篇中接入了EC11进行调光,但是对三基色进行整体调光,本文加入三基色分别调光。
正文
上篇文章中我们利用到EC11的两个脉冲接口,本次加入按键功能。在51代码中实现按键扫描,监测EC11的按键是否被按下,如果有按,则循环当前切换的颜色,并用4脚三基色led标识出当前要调整的色彩,并启用一个定时器进行4秒左右的倒计时,时间到了时就把led熄灭,并关闭定时器。
键盘扫描代码:
//检测到按键
if(p01 == 0) {
//消抖
delays(1);
if(p01 == 0) {
controlC = (controlC + 1) % 4;
TR0 = 0; //先关计时器,重新计数
TH0 = 0; //重新装填计数
TL0 = 0;
coutrolCount = 0;
TR0 = 1;//再开
redLed = 1;
greenLed = 1;
blueLed = 1;
if(controlC == CRED) {
redLed = 0;
} else if(controlC == CGREEN) {
greenLed = 0;
} else if(controlC == CBLUE) {
blueLed = 0;
}
delays(200);
}
}
注意在里面有对定时器进行重置的操作,在编码器的外部中断中也需要有这样的操作,以免时钟计时时间到了对三色无法调节。
搞定三基色调光,我们再来考虑断电保存三色值,以便下次启动时能直接使用上次值,提高用户体验度。断电保存要使用到EEPROM,正好51系列内部都带有大小不等的EEPROM,对于保存我们的三色值是足够的。
对于EEPROM的资料网上很多,在此不做过多描述,下面是读写擦除的代码:
void IapIdle()
{
IAP_CONTR = 0;
IAP_CMD = 0;
IAP_TRIG = 0;
IAP_ADDRH = 0X80;
IAP_ADDRL = 0;
}
//EEPROM 读取一个byte
uchar IapReadByte(int addr)
{
uchar dat;
EA = 0;
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_READ;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0X46;
IAP_TRIG = 0XB9;
delays(1);
dat = IAP_DATA;
IapIdle();
EA = 1;
return dat;
}
//EEPROM 写一个byte 该地址必须要擦写过的,或是0xff,要不然数据是不对的
void IapWriteByte(int addr,uchar dat)
{
EA = 0;
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_PROGRAM;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_DATA = dat;
IAP_TRIG = 0X46;
IAP_TRIG = 0XB9;
delays(1);
IapIdle();
EA = 1;
}
//EEPROM 擦写一个扇区
void IapEraseSector(int addr)
{
EA = 0;
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_ERASE;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0X46;
IAP_TRIG = 0XB9;
delays(14);
IapIdle();
EA = 1;
}
电路图
结束语
终于完结了ws2812b的一系列调光调色,最终回头看看本系列用到的51知识:键盘扫描,外部中断,计时器
,还有外部输出频率的精确控制,能学得的东西学是不少的。
下一步准备把做成的调色调光集成后做成一个台灯,到时会出一个制作视频,敬请期待!
附程序下载链接: