/* * 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(); }