WS2812彩色灯驱动代码
·23 字·1 分钟阅读
嵌入式开发
ws2812.h
#ifndef __WS2812_H__
#define __WS2812_H__
#include "SYSCFG.h"
#include "utils.h"
#define WS2812_LED_NUM 1U
#define WS2812_PIN_HIGH (RA2 = 1)
#define WS2812_PIN_LOW (RA2 = 0)
void WS2812_Init(void);
void WS2812_Write_Byte(uint8_t byte);
void WS2812_Write_RGB(uint8_t r, uint8_t g, uint8_t b);
void WS2812_Reset(void);
void WS2812_Clear(void);
void WS2812_Manage(void);
#endif
ws2812.c
注意WS2812时序,不然WS2812很有可能一直显示白色
#include "ws2812.h"
uint8_t led_color_index = 0;
/*-------------------------------------------------
* 函数名:WS2812_Init
* 功能: WS2812初始化,配置PA2为输出引脚
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void WS2812_Init(void)
{
TRISA &= ~(1 << 2);
WS2812_PIN_LOW;
}
/*-------------------------------------------------
* 函数名:WS2812_Write_Byte
* 功能: 向WS2812写入一个字节数据
* WS2812时序:T0H≈0.35us, T1H≈0.9us, T0L≈0.9us, T1L≈0.35us
* 高位在前,GRB顺序
* 系统时钟16MHz / 2T
* 输入: byte - 要写入的字节数据
* 输出: 无
--------------------------------------------------*/
void WS2812_Write_Byte(uint8_t byte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
if (byte & 0x80)
{
WS2812_PIN_HIGH;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
WS2812_PIN_LOW;
NOP();
NOP();
}
else
{
WS2812_PIN_HIGH;
NOP();
WS2812_PIN_LOW;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
}
byte <<= 1;
}
}
/*-------------------------------------------------
* 函数名:WS2812_Write_RGB
* 功能: 向WS2812写入RGB颜色数据
* WS2812数据格式:GRB(绿、红、蓝)
* 输入: r - 红色分量 (0-255)
* g - 绿色分量 (0-255)
* b - 蓝色分量 (0-255)
* 输出: 无
--------------------------------------------------*/
void WS2812_Write_RGB(uint8_t r, uint8_t g, uint8_t b)
{
uint8_t gie;
gie = GIE;
GIE = 0;
WS2812_Write_Byte(g);
WS2812_Write_Byte(r);
WS2812_Write_Byte(b);
GIE = gie;
}
/*-------------------------------------------------
* 函数名:WS2812_Reset
* 功能: 发送WS2812复位信号(低电平>50us)
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void WS2812_Reset(void)
{
WS2812_PIN_LOW;
Delay_Us(100);
}
/*-------------------------------------------------
* 函数名:WS2812_Clear
* 功能: 清除所有LED(设置为全黑)
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void WS2812_Clear(void)
{
WS2812_Write_RGB(0, 0, 0);
WS2812_Reset();
}
void WS2812_Manage(void)
{
switch (led_color_index)
{
case 0:
WS2812_Write_RGB(255, 0, 0);
WS2812_Reset();
break;
case 1:
WS2812_Write_RGB(0, 255, 0);
WS2812_Reset();
break;
case 2:
WS2812_Write_RGB(0, 0, 255);
WS2812_Reset();
break;
default:
break;
}
led_color_index = (led_color_index + 1) % 3;
}