RGB灯珠SK6812(WS2812)的简单学习和应用


一、SK6812是什么?

SK6812是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个SMD5050顶面发光LED灯珠相同 ,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,电源稳压电路,内置 恒流电路,高精度RC振荡器,输出驱动采用专利PWM技术,有效保证了像素点内光的颜色高一致性。

1、工作原理

SK6812和WS2812一样,数据协议都是采用单极性归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整形放大后 通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit。像素点采用自动整形 转发技术,使得该像素点的级联个数不受信号传送的限制,仅仅受限信号传输速度要求。

这时候你肯定会有疑问,什么是单极性归零码?
在这里插入图片描述
由上面这张图你就知道单极性归零码是一种编码方式,包含“0”码和“1”码,高电平时间宽度决定了你发送的是“0”码还是“1”码。

2、典型电路

在这里插入图片描述
这是规格书上的简单的典型应用电路,实际我们应用的时候还可以在电路上加一个钽电容以及在每一个RGB旁放置一个小电容。

为什么我们要这么做呢?这是因为:

1.总所周知,电解电容具有良好的滤波性能,可以稳定电源电压并减小电源噪声。RGB LED需要比较高精度的电源电压,我们在电路中加入钽电容可以有效地过滤掉电源中的高频噪声,确保RGB LED的电压稳定;
2.在RGB LED的亮度调节过程中,会产生较大的瞬态电流。加入钽电容可以提供充足的电流支撑,使RGB LED的亮度调节更加平稳,减少闪烁和颜色失真等问题。
3.在每一个LED灯珠旁边放置电容的作用是为了进一步稳定LED灯珠的工作电压,并提高LED灯珠的寿命。由于LED灯珠对电压的要求较高,且其内部具有较大的电容负载,因此在LED灯珠旁边加入电容可以减小电源对LED灯珠的影响,提高LED灯珠的工作效率。

3、驱动代码

3.1 初始化代码如下(示例):

DIN输入脚我们配置为推挽输出模式

/*******************************************************************************
 * 函数名:RGB_GPIO_Init
 * 描述  :RGB引脚配置初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void RGB_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
	
  /*Configure GPIO pin : Pin */
  GPIO_InitStruct.Pin = DIN1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(RGB_GPIO_Port, &GPIO_InitStruct);			
}

3.2 时序代码如下(示例):

在这里插入图片描述
根据时序表,我们写出发送“0”码和发送“1”码


//以下的时间延时基于STM32G0单片机,时间不是特别准确。更换MCU需要自行修改,用示波器确认时间
#define _delay_300ns()                                            \
do{                                                             \
      uint8_t   delay_300ns_cnt = 0;                               \
      for(delay_300ns_cnt = 0;delay_300ns_cnt < 2;delay_300ns_cnt++)  \
       {                                                        \
         __NOP();                                        \
       }                                                        \
}while(0)

#define _delay_1us()                                            \
do{                                                             \
      uint8_t   delay_1us_cnt = 0;                               \
      for(delay_1us_cnt = 0;delay_1us_cnt < 6;delay_1us_cnt++)  \
       {                                                        \
         __NOP();                                        \
       }                                                        \
}while(0)


#define SEND_BIT_VOL(n) \
do{\
	if(!n) \
	{HAL_GPIO_WritePin(RGB_GPIO_Port,DIN1_Pin,GPIO_PIN_SET);__NOP();LED_DIN1_OFF();_delay_1us();}\
	else \
	{LED_DIN1_ON();_delay_300ns();LED_DIN1_OFF();_delay_1us();}\
	}while(0)```

3.3 写数据代码如下(示例):

/*******************************************************************************
 * 函数名:Out8
 * 描述  :往对应位置写入8位数据
 * 输入  :dat
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void Out8(uint8_t dat)
{
    volatile uint8_t i;
    uint8_t tmp;
    tmp = dat;
    for(i = 0;i < 8;i++)
    {
        if(tmp & 0x80 )
        {
            SEND_BIT_VOL(1);				
        }
        else
        {
            SEND_BIT_VOL(0);					
        }
        tmp <<= 1;
    }
}

这里解释下为什么要关总中断,再开启总中断。是因为我在测试呼吸RGB的时候发现如果写入数据量太大,会导致个别灯珠异常,查找问题发现是中断导致的,所以才加了这个。
然后为什么还有个W,是因为我用到的是RGBW灯珠,相比较RGB灯珠,它多了一路白光控制通道,使得在调节亮度和色彩饱和度时更加灵活,并且能够呈现更加自然的白光。

/*******************************************************************************
 * 函数名:Out32
 * 描述  :往对应位置写入32位数据
 * 输入  :clg,clr,clb,clw 
 * 输出  :void
 * 调用  :
 * 备注  :R,G,B,W
 *******************************************************************************/
void Out32(uint8_t clg,uint8_t clr,uint8_t clb,uint8_t clw )
{
    __disable_irq();//关总中断						
	
    Out8 ( clg );
	
    Out8 ( clr );
	
    Out8 ( clb );
	
    Out8 ( clw );
		
   __enable_irq();//使能总中断
}

在这里插入图片描述

3.4 流水灯代码如下(示例):

如需更改颜色,修改.h文件里面的值即可

//********************    G    R    B    W
#define COLOR_WHILE       0 ,  0 ,  0,   20	
#define COLOR_BLUE        0 ,  0 , 20,   0
#define COLOR_RED         0 , 20 ,  0,   0
#define COLOR_GREEN       20,  0 ,  0,   0
/*******************************************************************************
 * 函数名:Running_RGB
 * 描述  :流水RGB
 * 输入  :void
 * 输出  :void
 * 调用  :
 * 备注  :1蓝
 *******************************************************************************/
void Running_RGB(void)
{	
    uint8_t i;
    uint8_t j;		
	for ( i = 0; i <= MAX_NUM; i++ )
	{
		for ( j = 0; j < i; j++ )
		{							
             Out32(COLOR_BLUE);//blue									
		}
		LED_DIN1_OFF();		
		_delay_100us();//复位需要大于80us		
		if(MAX_NUM == 50)
		{
			delay_syms(10);
		}
		else
		{
			delay_syms(20);
		}		
     }			
	delay_syms(100);
	Close_All_RGB();
}

二、总结

今天介绍了RGB灯珠的的原理和简单应用,有兴趣的可以下载驱动附件参考,附件有多种颜色的流水,呼吸等效果,感谢你的观看,谢谢!

在这里插入图片描述

  • 28
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xiaobuding_QAQ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值