2023-10-19 13:56:26 +08:00

131 lines
6.7 KiB
C

/*
* ws2812.c
*
* Created on: 2021年12月30日
* Author: User
*/
#include "ws2812.h"
#include "delay.h"
// @20MHz
#define WS2812_SEND_BIT(b) \
do { \
if (!(b)) { \
WS2812B_DATA = 1; \
NOP7(); \
WS2812B_DATA = 0; \
NOP12(); \
Delay10us(); \
} else { \
WS2812B_DATA = 1; \
NOP15(); \
WS2812B_DATA = 0; \
NOP5(); \
Delay10us(); \
} \
} while (0)
#define WS2812_SEND_BYTE(B) \
do { \
WS2812_SEND_BIT(B & 0x80); \
WS2812_SEND_BIT(B & 0x40); \
WS2812_SEND_BIT(B & 0x20); \
WS2812_SEND_BIT(B & 0x10); \
WS2812_SEND_BIT(B & 0x08); \
WS2812_SEND_BIT(B & 0x04); \
WS2812_SEND_BIT(B & 0x02); \
WS2812_SEND_BIT(B & 0x01); \
} while (0)
#define WS2812_SEND_START() \
do { \
WS2812B_DATA = 0; \
Delay50us(); \
Delay50us(); \
Delay50us(); \
Delay50us(); \
Delay50us(); \
Delay50us(); \
ea = EA; \
EA = 0; \
} while (0);
#define WS2812_SEND_END() \
do { \
NOP6(); \
WS2812B_DATA = 0; \
EA = ea; \
} while (0)
void ws2812ShowLeds(u32 *led, u8 count) {
bit ea;
u8 color[MAX_LED_COUNT * 3], i;
u32 *p_led = led;
if (count > MAX_LED_COUNT) count = MAX_LED_COUNT;
for (i = 0; i < count * 3; i += 3, p_led++) {
color[i] = (*p_led >> 8) & 0xFF; // G
color[i + 1] = (*p_led >> 16) & 0xFF; // R
color[i + 2] = (*p_led >> 0) & 0xFF; // B
}
WS2812_SEND_START();
WS2812_SEND_BYTE(color[0]);
WS2812_SEND_BYTE(color[1]);
WS2812_SEND_BYTE(color[2]);
#if MAX_LED_COUNT > 1
WS2812_SEND_BYTE(color[3]);
WS2812_SEND_BYTE(color[4]);
WS2812_SEND_BYTE(color[5]);
#endif
#if MAX_LED_COUNT > 2
WS2812_SEND_BYTE(color[6]);
WS2812_SEND_BYTE(color[7]);
WS2812_SEND_BYTE(color[8]);
#endif
#if MAX_LED_COUNT > 3
WS2812_SEND_BYTE(color[9]);
WS2812_SEND_BYTE(color[10]);
WS2812_SEND_BYTE(color[11]);
#endif
#if MAX_LED_COUNT > 4
WS2812_SEND_BYTE(color[12]);
WS2812_SEND_BYTE(color[13]);
WS2812_SEND_BYTE(color[14]);
#endif
#if MAX_LED_COUNT > 5
WS2812_SEND_BYTE(color[15]);
WS2812_SEND_BYTE(color[16]);
WS2812_SEND_BYTE(color[17]);
#endif
#if MAX_LED_COUNT > 6
WS2812_SEND_BYTE(color[18]);
WS2812_SEND_BYTE(color[19]);
WS2812_SEND_BYTE(color[20]);
#endif
#if MAX_LED_COUNT > 7
WS2812_SEND_BYTE(color[21]);
WS2812_SEND_BYTE(color[22]);
WS2812_SEND_BYTE(color[23]);
#endif
#if MAX_LED_COUNT > 8
WS2812_SEND_BYTE(color[24]);
WS2812_SEND_BYTE(color[25]);
WS2812_SEND_BYTE(color[26]);
#endif
#if MAX_LED_COUNT > 9
WS2812_SEND_BYTE(color[27]);
WS2812_SEND_BYTE(color[28]);
WS2812_SEND_BYTE(color[29]);
#endif
#if MAX_LED_COUNT > 10
WS2812_SEND_BYTE(color[30]);
WS2812_SEND_BYTE(color[31]);
WS2812_SEND_BYTE(color[32]);
#endif
WS2812_SEND_END();
}