打印
[技术讨论]

基于华芯微特SWM180CBT6的串口驱动真彩色WS2812灯带的应用实例

[复制链接]
2483|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
缥缈九哥|  楼主 | 2017-8-19 14:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
不多说请看注释及源码,有用到或转发的请记住这是缥缈九哥(yuanxihua@21cn.com)原创:
/*******************************************************************************************
WS2812S的标准时序如下:
TH+TL=1.25us±150ns, RES>50us
T0H=0.25us±150ns = 0.10us - 0.40us
T1H=1.00us±150ns = 0.85us - 1.15us
T0L=1.00us±150ns = 0.85us - 1.15us
T1L=0.25us±150ns = 0.10us - 0.40us
占空比取1:3,Bit = 0.290us - 0.350us , T=1.160us - 1.40us

用UART的TXD驱动WS2812,采用3M即0.333US的波特率。
那么起始位+D0D1D2位组合成0111做为WS2812的0码,D3D4D5D6位0001做为WS2812的1码;
或者起始位+D0D1D2位组合成0001做为WS2812的1码,D3D4D5D6位0111做为WS2812的0码;
而且剩下的D7+结束位+2位字间空隙组合成固定的1111为新的空闲位。
那么只要外置74HC04做反相功能,即可符合标准的WS2812的接收的时序要求。
即是T0H=0.333US,T0L=0.999US,T1H=0.999US,T1L=0.333US;
即是TH+TL=1.332us 小于周期1.4US,而且 IDLE=1.332uS 小于RES的50us时间,以上状态会保持下去。
结论:用连续12个字节的UART信号即可传送一个WS2812显示像素24位数据。
*********************************************************************************************/
#include "SWM1800.h"
#include "cmsis_os.h"
#include "string.h"
#include <stdlib.h>
typedef __packed struct
{
        uint8_t blue;
        uint8_t green;
        uint8_t red;
        uint8_t white;
}pixel_t;
void UART1Init(void)
{
        UART_InitStructure UART_initStruct;
       
        PORT_Init(PORTA, PIN0, FUNMUX_UART1_RXD, 1);        //GPIOA.0配置为UART1输入引脚
        PORT_Init(PORTA, PIN1, FUNMUX_UART1_TXD, 0);        //GPIOA.1配置为UART1输出引脚
       
        UART_initStruct.Baudrate                 = 3000000;        //=clk/16/x BIT = 0.333us
        UART_initStruct.TXThreshold         = 0;                //取值0--7
        UART_initStruct.TXThresholdIEn         = 0;                //当TX FIFO中数据个数 <= TXThreshold时触发中断
        UART_initStruct.RXThreshold         = 7;                //取值0--7
        UART_initStruct.RXThresholdIEn         = 1;                //当RX FIFO中数据个数 >= RXThreshold时触发中断
        UART_initStruct.TimeoutTime         = 20;                //超时时长 = TimeoutTime/(Baudrate/10) 秒
        UART_initStruct.TimeoutIEn                = 1;                //超时中断,超过 TimeoutTime/(Baudrate/10) 秒没有在RX线上接收到数据时触发中断
       
        UART_Init(UART1, &UART_initStruct);
        UART_Open(UART1);
}
void Uart1Write(char data)
{
        UART_WriteByte(UART1, data);       
        while(UART_IsTXBusy(UART1));        
}
#if 0
void Uart1Test(void)
{       
        UART1Init();
        while(1){Uart1Write(0x55);}
}
void Ws2812Reset(void)
{       
        GPIO_Init(GPIOA, PIN1, 1, 0, 0, 0);                                //GPIOA.1配置为输出引脚,推挽输出
        GPIO_SetBit(GPIOA, PIN1);
        osDelay(1);//延时60us以上
        PORT_Init(PORTA, PIN1, FUNMUX_UART1_TXD, 0);        //GPIOA.1配置为UART1输出引脚
}
#endif
void Ws2812WriteByte(uint8_t byte)
{
        for(uint8_t i=0;i<4;i++)
        {
                uint8_t data=((byte&0x80)?0x04:0x07)|((byte&0x40)?0x40:0x70)|0x80; // D0-D2:D3-D6:D7
                Uart1Write(data);
                byte<<=2;
        }
}
void Ws2812Pixel(pixel_t *pixel,uint32_t length)
{
        osDelay(1);//延时1ms以复位
        __disable_irq();
        for(uint32_t i=0;i<length;i++)
        {
                Ws2812WriteByte(pixel.green);        //绿色
                Ws2812WriteByte(pixel.red);                //红色
                Ws2812WriteByte(pixel.blue);                //蓝色
        }
        __enable_irq();
}
void Ws2812Test(void)
{
        uint32_t i=0,j,color[8],len=8,dly=4;
        UART1Init();
        while(1)
        {
                while(i++<255){for(j=0;j<8;j++){color[j]=i<<16;}Ws2812Pixel((pixel_t *)color,len);osDelay(dly);}
                while(i-->  1){for(j=0;j<8;j++){color[j]=i<<16;}Ws2812Pixel((pixel_t *)color,len);osDelay(dly);}
                while(i++<255){for(j=0;j<8;j++){color[j]=i<< 8;}Ws2812Pixel((pixel_t *)color,len);osDelay(dly);}
                while(i-->  1){for(j=0;j<8;j++){color[j]=i<< 8;}Ws2812Pixel((pixel_t *)color,len);osDelay(dly);}
                while(i++<255){for(j=0;j<8;j++){color[j]=i<< 0;}Ws2812Pixel((pixel_t *)color,len);osDelay(dly);}
                while(i-->  1){for(j=0;j<8;j++){color[j]=i<< 0;}Ws2812Pixel((pixel_t *)color,len);osDelay(dly);}
        }
}
全文完毕。

相关帖子

沙发
缥缈九哥|  楼主 | 2017-8-19 14:18 | 只看该作者
顶起。现在不常用QQ:14131338了。习惯了用微信PM9GZY。

使用特权

评论回复
板凳
缥缈九哥|  楼主 | 2017-8-19 14:19 | 只看该作者
现在也不喜欢上论坛了。

使用特权

评论回复
地板
ligen13872| | 2017-8-20 15:30 | 只看该作者
赞,,,,,,,,,,

使用特权

评论回复
5
@若水| | 2017-8-20 17:51 | 只看该作者

使用特权

评论回复
6
奔跑Robin| | 2020-7-7 11:22 | 只看该作者
技术分享,赞!!

使用特权

评论回复
7
天真的傻子| | 2020-11-25 09:34 | 只看该作者
沙发点赞

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

1868

帖子

272

粉丝