当前位置: 首页 > 科技观察

一个IO控制很多个LED,这个技能你Get到了吗

时间:2023-03-15 00:49:04 科技观察

一个IO控制很多LED,你掌握这个技能了吗?这种级联方式只需要用一个IO口(单片机引脚)控制尽可能多的LED。每个LED内部集成了一个驱动芯片,这使得我们的LED变得智能和可寻址。每个内部都有一个恒流驱动,所以LED的颜色非常一致。即使电压略有波动,电压变化也是一样的。无需外接电阻-限流电阻,使LED灯的布局设计变得简单。单线通信可以最大程度地减少单片机IO口的压力。另外,这款RGB灯采用了WS2812B驱动芯片,使得外围电路只需要一个电容就可以满足电路要求,让电路尽可能的简洁美观。特点智能反接保护,电源反接不会损坏IC;IC控制电路与LED点光源共用一个电源;控制电路与RGB芯片集成在一个5050封装元件中,形成一个外接控制像素;内置信号整形电路,任意一个像素点接收到信号后,经过波形整形后输出,保证线路波形失真不累积;内置上电复位和断电复位电路;每个像素的三基色可实现256级亮度显示,完成16777216种颜色的全真彩色显示,扫描频率不低于400Hz;串行级联接口,通过一根信号线即可完成数据接收和解码;当任意两点之间的传输距离不超过5米时,无需额外附加电路;刷新率为30帧/秒时,级联数不少于1024点;数据传输速度可达800Kbps;光色高度一致,性价比高。注意:800Kbps相当于1.25us传输一位数据。引脚图引脚功能说明:NO.符号功能说明1VDDLED电源,Vdd范围+3.5~+5.3V2DOUT控制信号数据输出脚3VSS地4DIN控制信号数据输入脚串联典型电路该方法原理图只需要额外加一个0.1uF的电容除了灯珠。硬件连接STM32F103RET6核心板WS2812B模块PA6DINVCC+5VGNDGND驱动原理数据协议采用单线归零码通讯方式。像素点上电复位后,DIN端接收到控制器传来的数据,第一个发送的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩下的数据经过内部整形处理电路整形放大后,再通过DOUT端口转发输出到下一个级联像素。对于一个像素的传输,信号减少了24位。像素点采用自动整形转发技术,使级联像素点数量不受信号传输限制,仅受信号传输速度要求限制。由于数据内部锁存,只要颜色值不变(模块持续供电),颜色就不会改变,不需要持续提供设置颜色的脉冲(模块复位)单片机无作用),只需要修改颜色值即可,发送一次即可。0和1Treset的区别:复位时间可以从上图看出。要发送“0”,我们需要将GPIO引脚设置为高电平0.4us(400ns),然后将GPIO引脚设置为低电平0.85us(850ns)。这个过程就是完成0码的发送。具体代码实现如下:voidsend_0(void){IN_H;Wait400ns;IN_L;Wait850ns;}我们要发送'1',需要将GPIO引脚置高0.85us(850ns),此时GPIO为置低持续0.4us(400ns),这个过程就是完成1个代码的发送,具体代码实现如下:voidsend_1(void){IN_H;等待850ns;IN_L;等待400ns;取相对准确的延迟时间400ns和850ns。延时函数的实现单片机中的延时函数一般通过执行一些无意义的循环来延时,比如定义如下函数:voiddelay(unsignedchari){while(--i);}这里我们需要的延时周期很小,只有1.25us,因为函数的调用需要入栈出栈,所以如果用上面的延迟函数方法,那么进出一次,将近几百ns的时间就没有了,所以为了精确控制,我们这里的延时函数的定义如下:__NOP();__NOP();}#defineWait250ns{__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();}#defineWait400ns{Wait250ns;Wait10nop;}//388#defineWait850ns{Wait250ns;Wait10nop;Wait10nop;Wait10nop;Wait10nop;__NOP();__NOP();__NOP();__NOP();__NOP();}//860我们在main函数中使用下面的方法来测试这个延时函数n:while(1){IN_H;//Wait250ns;Wait850ns;IN_L;//Wait250ns;Wait850ns;}然后用示波器观察模块DIN脚连接的GPIO输出的脉冲信号,检查其是否highlevel是否符合我们预先定义的,如果不一致,则增加或减少空指令来调整。注意:一次__NOP();的耗时空指令约为:1000/72≈14ns。您可以增加或减少__NOP();的数量。根据上述定义随意清空指令。》注意空指令前面有两个“_”,经过示波器测量和常数调整,上面定义的Wait250ns宏的耗时如下图所示,经过示波器测试,上面的Wait400ns时间-耗时为388ns,Wait850ns耗时为860ns,满足上面“0”和“1”的时间区间范围。24位数据的组成注:数据传输顺序按GRB顺序传输,高位在前。voidws2812_rgb(u8ws_num,u8ws_r,u8ws_g,u8ws_b){ws_data[(ws_num-1)*3]=ws_g;ws_data[(ws_num-1)*3+1]=ws_r;ws_data[(ws_num-1)*3+2]=ws_b;}ws_data[]数组用来记录要传输的RGB数据。每个灯珠的颜色占用三个字节,因为数据传输顺序是按照GRB的顺序传输的,所以赋值的时候要注意顺序。上面的函数是设置某个灯珠的颜色值。ws_data[]数组中的颜色值设置好之后,要把这个数组的数据发送给模块。具体实现函数如下:voidws2812_refresh(u8ws_count){u8ws_ri=0;for(;ws_ri8)times=0;switch(times){case0:ws2812_rgb(1,WS_RED);ws2812_rgb(2,WS_GREEN);ws2812_rgb(3,WS_BLUE);ws2812_rgb(4,WS_WHITE);ws2812_rgb(5,WS_PURPLE);ws2812_rgb(6,WS_YELLOW);ws2812_rgb(7,WS_BROWN);ws2812_rgb(8,WS_BLUE);ws2812_rgb(8,WS_BLUE);ws2812_refresh(8);ws2812_rgb(6,WS_YELLOW)case1:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(1,WS_RED);ws2812_refresh(8);break;case2:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(2,WS_GREEN);ws2812_refresh(8);break;case3:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(3,WS_BLUE);ws2812_refresh(8);break;case4:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(4,WS_WHITE);ws2812_refresh(8);break;case5:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(5,WS_PURPLE);ws2812_refresh(8);break;case6:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(6,WS_YELLOW);ws2812_refresh(8);break;case7:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(7,WS_BROWN);ws2812_refresh(8);break;case8:memset(ws_data,0,WS_ARRAY_SIZE*sizeof(u8));ws2812_rgb(8,WS_BLUE);ws2812_refresh(8);break;}delay_ms(1000);}}颜色RGB值查询颜色RGB值及名称可参考以下链接:https://code.ziqiangxuetang.com/try/color.py程序中预定义颜色如下:#defineWS_DARK0,0,0#defineWS_WHITE255,255,255#defineWS_RED255,0,0#defineWS_GREEN0,255,0#defineWS_BLUE0,0,255#defineWS_YELLOW255,255,0#defineWS_PURPLE255,0,255#defineWS_CYAN0,255,255#defineWS_BROWN165,42,42可以根据自己的喜好随意更改颜色请联系Embeddedfrom0to1公众号转载本文。