前言
淘宝买的编码器到货,开始手动编码调试,踩了一些坑,不过最终还是搞定。
目标
上篇文章中是用ADC转换电位器阻值来对WS2812B来进行调光的,如果想分别调三基色的亮暗,那就得用三个电位器三个ADC,或是基于片选的一个ADC转换和三个电位器,电路比较麻烦。如果使用EC11,则可以同时实现以上功能同时减少电器元件的使用。
思路
EC11(此处有别人描述非常非常详细的资料,相看自己去看,我就不贴了)有五个脚,其中两个脚DE为开关,可以实现按键开关的用途,在本例中可以实现按一下切换调色菜单;ABC三脚则可以实现调亮调暗。
本文先实现ABC三脚进行白光的调亮调暗,下一篇再进行三基色的调亮调暗。
ABC三相的电路思路:AB脚接上拉10K电阻,A相接51的外部0号中断,设置为下降沿触发,B相接51的P2.1引脚,用于A相中断到来时通过B脚电平的高低来判断是正转还是反转;C相接地。
中断初始化:
EA=1;//全局中断开
EX0=1;//外部中断0开
IT0=1;//下降沿有效
中断处理函数中,我们要判断B相的电平高低来做调亮与调暗,比如高电平时为正转,低电平时为反转。但是实际调试中发现如果你一直正转或反转时,中断的时候总有那么一个脉冲跟其他的脉冲是相反的,不知道是劣质元件还是我劣质的编程水平引起的。。。所以我们要引入一个变量来消除这个抖动的脉冲:
#define UDDEFAULT 10 //用于清除中断抖动的变量初始值
#define STEP 2 //清除抖动的阀值,含意为必须有两次同向转动中断才能触发,阀值不能太大,
//太大的话会让你旋钮转很多格数但是亮度调节动不明显
#define RGBSTEP 15 //调光时每次的递增/减量
以下为最终的中断实现函数:
void interves(void) interrupt 0
{
//1ms延时,消抖
delays(1);
//中断到来时不直接去调亮度,而是先把这次脉冲记录下来
if(p21==0) {
upDown --;
} else {
upDown ++;
}
//当脉冲数量达到一定的阀值时再去做调节亮度
if(upDown == UDDEFAULT - STEP) {
if(led.G_VAL > RGBSTEP) {//uchar一直加会溢出到从0开始
led.G_VAL -= RGBSTEP;
led.B_VAL -= RGBSTEP;
led.R_VAL -= RGBSTEP;
} else {
led.G_VAL = 0;
led.B_VAL = 0;
led.R_VAL = 0;
}
SendAllLeds();
//做完后重置脉冲计数器,恢复计数
upDown = UDDEFAULT;
}
if(upDown == UDDEFAULT + STEP) {
if(led.G_VAL < 255 - RGBSTEP) {
led.G_VAL += RGBSTEP;
led.B_VAL += RGBSTEP;
led.R_VAL += RGBSTEP;
} else {
led.G_VAL = 0xff;
led.R_VAL = 0xff;
led.B_VAL = 0xff;
}
SendAllLeds();
upDown = UDDEFAULT;
}
}
电路图
电路图如下:
![EC11调亮度电路图](https://i-blog.csdnimg.cn/blog_migrate/946f4e503b6b71f985acdc8a0f9fff6f.png)
最后,附上protues电路图和源代码(因代码是在一块51集成板上做的开发,有一些代码是做一些关闭电路的操作):
https://download.csdn.net/download/yaleond/10777470