使用STCF12驱动 W2812灯珠

文章介绍了如何使用STCF12单片机通过其IO口输出控制W2812RGBLED灯珠的串行数据,详细阐述了W2812的工作原理和数据通讯协议,以及通过STC32F12的高速特性实现多颗W2812级联控制的方法,展示了利用单片机控制LED灯珠颜色变化的测试效果。
摘要由CSDN通过智能技术生成

STCF12控制W2812

 

01 W2812灯珠


一、前言

W2812 LED 灯珠内部集成了三色 LED的驱动电路, RGB LED 的亮度可以独立控制, 分成 256级。  使用一个串行数据性可以控制多个W2812的颜色。  特殊定义的数据通讯协议, 使用了脉冲宽度来表示 0 和 1,  当高电平宽度大于 550ns 以上时, 对应的是 1, 否则是 0。  利用一个超过 50微秒的低电平来结束通讯。  W2812具有一个接受和发送 IO口, 可以实现多个 LED的级联。 每 24 个bite 确定串行中 一个 W2812的颜色,  从前往后 每 八个 bit 分别定义了 绿、红、蓝的亮度。 当超长的 低电平来的时候, 所有的 W2812可以同时改变颜色。 这样就可以使用一条 IO 口来控制一整条等待 W2812的颜色了。

GM1687495425_1280_800.MPG|_-10

▲ 图1.1.1  W2812灯珠

▲ 图1.1.1 W2812灯珠

二、测试效果

最近新出的 STCF12 单片机, 时钟频率已经可以达到 64MHz,  利用它的 IO 口 可以输出控制 W2812串口数据。 这样便可以应用一条 STCF12的 IO 线来控制W2812灯柱。 这是实现 W2812控制程序。 

输入参数 pBuffer, 预先存储有RGB数值, 每三个为一组控制 一个 W2812彩色亮度。  通过一个循环输出 Buffer 中所有字节的内容。 利用 Mask 右移位值,获得输出数值的每一位, 根据该位数值为 0 还是 1,  分别控制输出脉冲的高电平。 这里这里使用 NOP的多少来完成脉冲宽度的定时。 为了防止单片机中断影响输出位的数值, 在这段循环前将单片机中断关掉。 这是输出控制信号的核心程序。 非常简单。 依靠着 STC32F12 单片机的速度, 实现了W2812串行通讯信号。

GM1687496109_1280_800.MPG|_-12

STC32F12 IO 端口输出信号直接连接在第一个 W2812的 输入端口,  W2812的输出信号连接到下一LED, 这是示波器显示 W2812输出的脉冲信号, 可以看到它是将 STC32FF12输入的信号进行了重新整形输出, ·对比一下可以看到对应的高电平比 STC32F12输出信号变窄了。 信号的周期并没有改变。 这是利用STCF12控制三个 W2812的效果。 如果 W2812比较多, 可以将W2812分成若干组, 进行并行控制。 

GM1687497243_1280_800.MPG|_-8

这里对比着第一个 W2812 和第二个 W2812 数据波形, 可以看到每经过24个脉冲之后, 第一个W2812将会输出它存储的脉冲宽度。 这是第三个 W2812的数据波形, 它的数据是由第二个W2812输出的。 所以它比第一个 W2812 完了 48个脉冲。  通过这样, 可以将很多 W2812进行级联。 理论上将, 可以控制无穷多个W2812的串联。

GM1687497698_1280_800.MPG|_-6
 

  结 ※


本文测试了STC32F12 控制W2812彩色灯珠, 利用一个STC32F12的 IO 端口可以控制一组级联在一起多个 W2812彩色灯珠。 这也彰显了STC32F12 的高速运行的特色。

GM1687497859_1280_800.MPG|_-3

一、测试程序

void main(void) {
    unsigned int nCount, nSendCount;
    unsigned char ucRGB[9];
    unsigned char ucRGBCount;
    
    MainInit();            
    PM_PP(LED);
    OFF(LED);
    
    PM_PP(SPIO);
    OFF(SPIO);
    
    nCount = 0;
    nSendCount = 0;
           
    for(;;) {
        if(++nCount & 0x1) ON(LED);
        else OFF(LED);        

        WaitTime(1);        
        
        if(++nSendCount > 250) {
            nSendCount = 0;
            
            OutW2812RGB(ucRGB, sizeof(ucRGB));
            
            if(ucRGBCount == 0) {
                ucRGB[0] = 0xff;
                ucRGB[1] = 0x00;
                ucRGB[2] = 0x00;
                ucRGB[3] = 0x00;
                ucRGB[4] = 0xff;
                ucRGB[5] = 0x00;
                ucRGB[6] = 0x00;
                ucRGB[7] = 0x00;
                ucRGB[8] = 0xff;
            } else if(ucRGBCount == 1) {
                ucRGB[0] = 0x00;
                ucRGB[1] = 0xff;
                ucRGB[2] = 0x00;                
                ucRGB[3] = 0x00;
                ucRGB[4] = 0x00;
                ucRGB[5] = 0xff;                
                ucRGB[6] = 0xff;
                ucRGB[7] = 0x00;
                ucRGB[8] = 0x00;                
            } else {
                ucRGB[0] = 0x00;
                ucRGB[1] = 0x00;
                ucRGB[2] = 0xff;                
                ucRGB[3] = 0xff;
                ucRGB[4] = 0x00;
                ucRGB[5] = 0x00;                
                ucRGB[6] = 0x00;
                ucRGB[7] = 0xff;
                ucRGB[8] = 0x00;                
            }
            
            ucRGBCount ++;
            if(ucRGBCount >= 3) ucRGBCount = 0;

        }
                        
        ConsoleDebug();        
                
    }
        
}

void MainInit(void) {

    C251Init();
    STC32FInit();
    ControlInit();

    SerialTxtInit();

    WaitTime(500);
    print("C251    -- by Dr. ZhuoQing,%s,%s[%bd]\r\n\r\n", "\n",  __DATE__, "\n",  __TIME__, "\n",  WTST);
    
}

void OutW2812RGB(unsigned char * pBuffer, unsigned char ucLength) {
    unsigned char i, j, ucMask, c, a;

    EA = 0;    
    
    for(i = 0; i < ucLength; i ++) {    
        ucMask = 0x80;
        c = *(pBuffer + i);
        for(j = 0; j < 8; j ++) {D
            a = c & ucMask;
            ucMask >>= 1;
        
            ON(SPIO);
            if(a > 0) NOP(30);
            else NOP(10);
                    
            OFF(SPIO);
            if(a > 0) NOP(5);        
            else NOP(15);       
            
        }
    }
    
    EA = 1;

}
#define LED             1,0

void OutW2812RGB(unsigned char * pBuffer, unsigned char ucLength);


■ 相关文献链接:

● 相关图表链接:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卓晴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值