标题: WS2812B灯珠RGB调色单片机程序,只是能亮,完全不受控制 [打印本页]

作者: 大飞0011    时间: 2018-10-19 15:13
标题: WS2812B灯珠RGB调色单片机程序,只是能亮,完全不受控制
MCU型号为:STC12C5A60S2,晶振11.0592mhz现在想点亮一个WS2812B的rgb灯珠调色!但试了好多程序案例,但只是能亮,完全不受控制!求大神分享一下设计思路


WS2812B参数如下:

数据传输时间( TH+TL=1.25μs±600ns)
T0H
0码,  高电平时间
0.4μs
±150ns
T1H
1码,  高电平时间
0.8 μs
±150ns
T0L
0码,  低电平时间
0.85μs
±150ns
T1L
1码,  低电平时间
0.45 μs
±150ns
RES
帧单位,低电平时间
50μs以上

时序波形图


WS2812B
输入码型:
连接方法:


WS2812B


WS2812B
数据传输方法:
注:其中D1为MCU端发送的数据,D2、D3、D4为级联电路自动整形转发的数据。
24bit数据结构:
G7
G6
G5
G4
G3
G2
G1
G0
R7
R6
R5
R4
R3
R2
R1
R0
B7
B6
B5
B4
B3
B2
B1
B0
注:高位先发,按照GRB的顺序发送数据。
典型应用电路:




作者: omikeai    时间: 2018-11-2 14:36
楼主解决了吗?我用STM32,再示波器上看时序都是对的 ,就是颜色完全不受控制。。。
作者: 大飞0011    时间: 2018-11-16 10:08
一样,色彩完全不受控制。全亮白光!
作者: 王灵    时间: 2018-12-29 21:02
楼主,我的一只亮红光,咋办呀
作者: jinsheng7533967    时间: 2018-12-30 20:49
先顶起!大家都在努力中!,不过晶振11.0592mhz是不行的,最起码要24MHZ
作者: Alen-sjg    时间: 2019-4-18 13:07
控制时序没有写对,我发个测试程序给你参考:
#include "IAP15F105W.h"
#include "intrins.h"

typedef unsigned char uchar;
typedef unsigned int  uint;

#define  Number 20

sbit DAI=P3^2;

void Delay (uint x)  // 1ms Delay
{
    uint t;
    t = 0;
    while (x--)
                {
      WDT_CONTR|=0x10;         
                        for (t = 0; t < 175; t++);
    }
}

void send_2811_24bits(uchar dat1,uchar dat2,uchar dat3)   // ·¢?íêy?Y
{
        uchar a,b;
        for(a=0;a<8;a++)         //dat1
        {
                if(dat1&0x80)
                {
                        DAI=1;                                              // CODE "1"
                        for(b=0;b<2;b++)
                        {
                                _nop_(); _nop_();
                        }
                        DAI=0;       
                }
                else
                {               
                        DAI=1;                                //CODE "0"
                        for(b=0;b<1;b++);
                        DAI=0;         
                        for(b=0;b<1;b++);
                }
                dat1=dat1<<1;               
        }
        for(a=0;a<8;a++)                       //dat2
        {       
                if(dat2&0x80)
                {                  
                        DAI=1;                                              // CODE "1"
                        for(b=0;b<2;b++)
                        {
                        _nop_(); _nop_();
                        }
                        DAI=0;                       
                }
                else
                {               
                        DAI=1;                                //CODE "0"
                        for(b=0;b<1;b++);
                        DAI=0;         
                  for(b=0;b<1;b++);
                }
                dat2=dat2<<1;       
        }                                                 
        for(a=0;a<8;a++)                      //dat3
        {       
                if(dat3&0x80)
                {               
                        DAI=1;                                              // CODE "1"
                        for(b=0;b<2;b++)
                        {
                                _nop_();  _nop_();
                        }
                        DAI=0;
                }
                else
                {       
                        DAI=1;                                //CODE "0"
                        for(b=0;b<1;b++);
                        DAI=0;         
                        for(b=0;b<1;b++);
                }
                dat3=dat3<<1;               
        }
}

void rst()
{
        uchar s;
        DAI=0;
        WDT_CONTR|=0x10;     
        for(s=0;s<50;s++);  
}
void Flowing()
{
        uint i;
        uint Stack;
        Stack=0;
        while(1)
        {
                for(i=0;i<Stack;i++)
                {
                        send_2811_24bits(255,255,255);
                }
                for(i=0;i<Number-Stack;i++)
                {
                        send_2811_24bits(0,0,0);
                }
                rst();
                Delay(1000);
                Stack++;
                if(Stack>Number)
                {
                        break;
                }
        }
}
void main()
{
        P3M0=0x04;                 
        P3M1=0x00;
        P32=0;
        WDT_CONTR=0x3F;         
        while(1)
        {
                Flowing();
        }
}
作者: 汉神俊    时间: 2019-7-20 11:11
虽然是挖坟 但我也找了好多资料才研究到规律  想炫耀一下
第一点  nop数量为(1/(晶频))我的是33.1776  所以每条nop需要(1 / 33.1776)us
第二点  尽量用减法  减法比加法省时间  nop数会更准确
第三点  用#define    比调用函数省时间  nop数会更准确

亮白点因为nop数不对 延迟时间不对
不符合灯条的要求
作者: a8619300    时间: 2019-11-19 15:05
汉神俊 发表于 2019-7-20 11:11
虽然是挖坟 但我也找了好多资料才研究到规律  想炫耀一下
第一点  nop数量为(1/(晶频 ...

第一点怎么算,他不是分0和1吗,怎么分配
作者: dzzsz2019    时间: 2021-1-22 13:36
本帖最后由 dzzsz2019 于 2021-1-28 14:09 编辑

用逻辑分析仪看看时序,注意的是一个灯珠的24信号 ,每8bit后要增加1个bit的低电平时间,每个灯珠要增加2个bit的低电平时间
最近也在做led的控制程序,发现有些带自控的芯片,当在一定时间没控制信号输入时,就转入自控程序,这个时间大概有7-8ms。所以如果发现led不受控,可以提高刷新率,以免芯片进入自控程序而造成不受控的现 象。


作者: 人人学会单片机    时间: 2021-2-22 20:18
89C52驱动WS2812 http://www.51hei.com/bbs/dpj-170855-1.html




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1