WS2812 通常需要按位发送 24 位颜色数据
(8 位 R+8 位 G+8 位 B),
其缓冲区设计常面临对齐挑战:
问题场景
c
运行
// 错误示例:WS2812数据缓冲区可能存在对齐问题
uint8_t ws2812_buffer[NUM_LEDS * 24]; // 每个LED需要24位数据
// 当使用32位DMA传输时,若缓冲区地址未4字节对齐
// GD32等严格对齐的MCU会出现传输错误
HAL_DMA_Start(&hdma_tim2_ch1, (uint32_t)ws2812_buffer, ...);
解决方案 1:结构体封装与强制对齐
利用编译器特性强制缓冲区地址对齐:
c
运行
// 适用于需要32位对齐的MCU
#define NUM_LEDS 16
#define WS2812_BUF_SIZE (NUM_LEDS * 24)
// 使用结构体和编译器属性强制对齐
typedef struct {
uint8_t data[WS2812_BUF_SIZE];
} __attribute__((aligned(4))) WS2812_Buffer; // GCC编译器
// #pragma pack(4) // Keil编译器
WS2812_Buffer ws2812_buf;
// 验证对齐是否正确
bool is_aligned(void) {
return ((uint32_t)&ws2812_buf.data[0] % 4) == 0;
}
简单直接,适用于固定大小的缓冲区缺点:可能浪费少量内存
|
|