131 lines
6.7 KiB
C
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();
|
|
}
|