控制核心内容
时间的控制是关键
查看手册分析,数据传送中的逻辑0和1都有高低电平,主要控制高电平时间。

颜色分析
每个灯需要24bit的数据控制一个灯的亮度和颜色显示。

个人遇到的问题的原因分析
时间的控制,个人遇到一直显示白光,这表示数据逻辑都发送是逻辑1,也就是高电平时间太长。如果一直是白色光,那么只要减少高电平时间就可以,若直到减少到一个时钟周期nop依然显示白光,那么就需要提高周期频率。
单片机运行周期分析
在传统的51单片机 中,晶振频率如果是12MHZ,那么机械周期被12分频,那么一个时钟频率就是1Mhz,也就是最小时钟周期是1x10-6 s=1us,但对于逻辑的0和1控制的ns明显时间控制完全不行,不会传输逻辑0的数据。
在stc/AI8G1K08中,内部默认晶振是24MHZ,而且时钟周期不用12分频,那么时钟周期就是1/24x10-6 s=1/24us ≈41.67ns ,可以看出时间控制的准确性也不太理想,而且在函数调用过程中的时间消耗也变得不可忽略。在尝试后发现,若把软延迟通过函数调用则需要再次减少NOP时间。
硬件连接设计

PCB图像

模拟3D的PCBA的图像,中间图像控制开关,圆形触摸控制灯亮的方式

整体程序分析
下面是传送一个字节数据的时候逻辑值的部分代码,

整体LED控制程序如下,
c
#include "intrins.h"
#include "STC8G.h"
#include "delay.h"
#include "led.h"
sbit WS2812_DIN = P5^5;
/*24Mhz时,每个nop表示一个时钟周期也是一个机械周期,不是传统51还需要12分频才是1个机械周期
一个nop周期约为1000/24ns约等于41.67ns
0:高电平:7个nop约290ns;低电平:20个nop约800ns
1:高电平:20个nop;低电平7个nop
void delay290ns(void);
void delay800ns(void);
*/
void led_init(void){
P5M1 &= ~0x20; /* 清除 P5.5 的 M1 位0010 0000*/
P5M0 |= 0x20; /* 设置 P5.5 为推挽输出*/
}
void send_bit(unsigned char one_bit){
WS2812_DIN =1;
if(one_bit){
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //到7个就认为是逻辑1,不用到22个nops
}
else{
_nop_();_nop_();_nop_();_nop_();
}
WS2812_DIN =0;
_nop_();_nop_();_nop_();_nop_();
}
void led_sendbyte(unsigned char dat)
{
unsigned char i;
for (i = 0; i < 8; i++) {
if (dat & 0x80) {
send_bit(1);
}
else{
send_bit(0);
}
dat <<= 1;
}
}
void led_send_led(unsigned char g, unsigned char r, unsigned char b)
{
led_sendbyte(g);
led_sendbyte(r);
led_sendbyte(b);
}
void led_reset(void)
{
WS2812_DIN =0;
Delay1us(300);
}