好学天上
发表于 2024-8-5 10:02:12
梁工,请问我用STC8G1K08A的芯片驱动这个WS2812然后接了可能五百个灯,我就想用串口发送灯选择和颜色选择,每次一个灯亮就行应该怎么写呀,看这个代码里面看不懂{:4_184:}。就是比如说我发996W,就是第九九六个灯亮白色,亮度就最亮,然后其他的灯都是灭的。可以解惑一下莫{:4_197:}
梁工
发表于 2024-8-5 14:50:35
好学天上 发表于 2024-8-5 10:02
梁工,请问我用STC8G1K08A的芯片驱动这个WS2812然后接了可能五百个灯,我就想用串口发送灯选择和颜色选择, ...
WS2812是一个个往后传数据的,每个灯3个字节,每个灯接收到3个字节就旁路掉数据,之后的数据就往后传。你要点亮第996个灯,前面995个灯也要发数据,不亮就发0x00,要先发995*3个字节,接着发3个字节才是第996个灯的数据。
好学天上
发表于 2024-8-5 15:02:06
梁工 发表于 2024-8-5 14:50
WS2812是一个个往后传数据的,每个灯3个字节,每个灯接收到3个字节就旁路掉数据,之后的数据就往后传。你 ...
#define MAIN_Fosc 11059200 //定义主时钟
#include "STC8Hxxx.h"
#include"intrins.h"
#define WS2812 P54 //GPIO
#define LED 1 //灯珠个数
unsigned char RED,GREEN,BLUE;
/*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
void Delay_10us(void)
{
unsigned char i;
i=35;
while(--i);
}
/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
while(x--)
Delay_10us();
}
/*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
//void Delay_10ms(void)
//{
// unsigned char i,j;
// _nop_();
// _nop_();
// i=144;
// j=157;
// do
// {
// while(--j);
// }while(--i);
//}
/*----------------------------延时x10ms----------------------------*/
//void Delay_x10ms(unsigned char x)
//{
// while(x--)
// Delay_10ms();
//}
void WS2812_Reset(void)
{
WS2812=0;
Delay_x10us(10);
}
void WS2812_Write_Byte(unsigned char data temp) //STC-Y6@11.0592MHz 0:375ns+1350ns 1:925ns+1350ns
{
unsigned char data i=8;
while(i)
{
temp<<=1;
WS2812=1;
if(CY)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
WS2812=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
i--;
}
}
unsigned int LED_ON = 5; //第几个亮
void WS2812_Write(void)
{
unsigned int i;
WS2812_Reset();
i=0;
while(1)
{
if(i==LED_ON)
{
WS2812_Write_Byte(GREEN);
WS2812_Write_Byte(RED);
WS2812_Write_Byte(BLUE);
break;
}
else
{
WS2812_Write_Byte(0);
WS2812_Write_Byte(0);
WS2812_Write_Byte(0);
i++;
}
}
}
void Init(void)
{
P5M0 = 0x10;
P5M1 = 0x00;
}
void main(void)
{
Init();
while(1)
{
RED=255; //红 0~255
GREEN=0; //绿 0~255
BLUE=0; //蓝 0~255
WS2812_Write();
}
}
我这样整但他还是全亮,然后颜色也是白色
梁工
发表于 2024-8-5 16:12:10
好学天上 发表于 2024-8-5 15:02
我这样整但他还是全亮,然后颜色也是白色
时序明显不对,发数据位0时全部是高电平,这是不对的。
数据0:高电平0.9us,低电平大于等于0.35us。
数据1:高电平0.3us,低电平大于等于0.95us。
好学天上
发表于 2024-8-5 17:30:06
梁工 发表于 2024-8-5 16:12
时序明显不对,发数据位0时全部是高电平,这是不对的。
数据0:高电平0.9us,低电平大于等于0.35us。
数 ...
按照这个要几个nop函数呀,我看百度说12MHZ一个nop()是1微秒,可是我要延时零点几微秒叻
好学天上
发表于 2024-8-5 17:35:45
梁工 发表于 2024-8-5 16:12
时序明显不对,发数据位0时全部是高电平,这是不对的。
数据0:高电平0.9us,低电平大于等于0.35us。
数 ...
void send_L(void)
{
WS2812=0;
_nop_();
_nop_();
WS2812=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
WS2812=0;
}
void send_H(void)
{
WS2812=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
WS2812=1;
_nop_();
_nop_();
_nop_();
WS2812=0;
}
void rest(void)
{
WS2812=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
WS2812=0;
}
void send_one_byte(unsigned char in_data)
{
unsigned char temp1=0;
unsigned char temp2=0;
unsigned char temp3=0;
unsigned char i=0;
temp1=in_data;
for(i=0;i<8;i++)//八位,循环八次
{
if(temp1&0x01)
send_H();
else
send_L();
temp1 >>= 1;//从最低位到最高位
}
}
void set_one_led(unsigned char R_data,unsigned char G_data,unsigned char B_data)
{
send_one_byte(R_data);
send_one_byte(G_data);
send_one_byte(B_data);
}
void WS2812_Write(void)
{
unsigned int i;
WS2812_Reset();
i=0;
while(1)
{
if(i==LED_ON)
{
set_one_led(RED,GREEN,BLUE);
break;
}
else
{
set_one_led(0,0,0);
i++;
}
}
}
这样写还是不行,还是全亮{:4_184:}
梁工
发表于 2024-8-5 17:51:57
好学天上 发表于 2024-8-5 17:35
这样写还是不行,还是全亮
你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。如此简单的时序:
对于12MHz,发数据1:
DIN = 1;
10个NOP;
DIN=0;
3个NOP;
对于12MHz,发数据0:
DIN = 1;
3个NOP;
DIN=0;
10个NOP
好学天上
发表于 2024-8-5 18:22:57
本帖最后由 好学天上 于 2024-8-5 18:25 编辑
梁工 发表于 2024-8-5 17:51
你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。如此简单的时序:
对于12MHz, ...
<ol class="code_ol_R87" style="list-style-position: initial; list-style-image: initial; font-family: monospace; white-space: pre; background-color: rgb(240, 240, 240);"><li style="padding-left: 5px; list-style-position: initial; list-style-image: initial; border-left: 1px solid rgb(205, 205, 205) !important;"><div class="blockcode"><blockquote>void send_L(void)
{
WS2812=1;
_nop_();
_nop_();
_nop_();
WS2812=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void send_H(void)
{
WS2812=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
WS2812=0;
_nop_();
_nop_();
_nop_();
}void send_one_byte(unsigned char in_data)
{
unsigned char temp1=0;
unsigned char temp2=0;
unsigned char temp3=0;
unsigned char i=0;
temp1=in_data;
for(i=0;i<8;i++)//八位,循环八次
{
if(temp1&0x01)
send_H();
else
send_L();
temp1 >>= 1;//从最低位到最高位
}
}
void set_one_led(unsigned char R_data,unsigned char G_data,unsigned char B_data)
{
send_one_byte(R_data);
send_one_byte(G_data);
send_one_byte(B_data);
}
void WS2812_Write(void)
{
unsigned int i;
WS2812_Reset();
i=0;
while(1)
{
if(i==LED_ON)
{
set_one_led(RED,GREEN,BLUE);
break;
}
else
{
set_one_led(0,0,0);
i++;
}
}
}
void Init(void)
{
P5M0 = 0x10;
P5M1 = 0x00;
}
void main(void)
{
Init();
WS2812_Reset();
while(1)
{
// RED=255; //红 0~255
// GREEN=0; //绿 0~255
// BLUE=0; //蓝 0~255
set_one_led(0,255,255);
set_one_led(0,0,0);
WS2812_Reset();
}
}void WS2812_Reset(void)
{
WS2812=0;
Delay_x10us(10);
}这样还是不行
好学天上
发表于 2024-8-5 19:12:53
梁工 发表于 2024-8-5 17:51
你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。如此简单的时序:
对于12MHz, ...
真的想不通{:4_184:}在下愚钝
梁工
发表于 2024-8-5 22:42:03
好学天上 发表于 2024-8-5 19:12
真的想不通在下愚钝
仔细看下W2812的手册,MSB先发的哦。
示波器看下波形正常没有。