欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

STM32+PWM+DMA 驱动 WS2812

最编程 2024-10-18 07:29:07
...
#include "stm32f1xx_hal.h" #include "ws2812.h" // 定义WS2812的PWM参数 #define WS2812_TIM_HANDLE htim1 #define WS2812_TIM_CHANNEL TIM_CHANNEL_1 #define WS2812_DMA_HANDLE hdma_tim1_ch1 // WS2812初始化函数 void WS2812_Init(void) { // 初始化DMA HAL_DMA_Init(&WS2812_DMA_HANDLE); __HAL_RCC_DMA1_CLK_ENABLE(); // 初始化定时器 HAL_TIM_PWM_Init(&WS2812_TIM_HANDLE); TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; // 初始化占空比为0 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&WS2812_TIM_HANDLE, &sConfigOC, WS2812_TIM_CHANNEL); // 启动PWM HAL_TIM_PWM_Start(&WS2812_TIM_HANDLE, WS2812_TIM_CHANNEL); // 配置DMA HAL_TIM_PWM_Start_DMA(&WS2812_TIM_HANDLE, WS2812_TIM_CHANNEL, (uint32_t*)ws2812_buffer, LED_NUM * 24); } // 设置WS2812的颜色 void WS2812_SetPixelColor(uint16_t num, uint8_t R, uint8_t G, uint8_t B) { if (num >= LED_NUM) return; uint16_t index = num * 24; for (int i = 0; i < 8; i++) { ws2812_buffer[index + i] = (G & (0x80 >> i)) ? WS2812_BIT_1 : WS2812_BIT_0; ws2812_buffer[index + i + 8] = (R & (0x80 >> i)) ? WS2812_BIT_1 : WS2812_BIT_0; ws2812_buffer[index + i + 16] = (B & (0x80 >> i)) ? WS2812_BIT_1 : WS2812_BIT_0; } } // 更新WS2812显示 void WS2812_Show(void) { HAL_TIM_PWM_Start_DMA(&WS2812_TIM_HANDLE, WS2812_TIM_CHANNEL, (uint32_t*)ws2812_buffer, LED_NUM * 24); } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_TIM1_Init(); WS2812_Init(); while (1) { // 示例:循环设置颜色 for (int i = 0; i < LED_NUM; i++) { WS2812_SetPixelColor(i, (i * 256 / LED_NUM) % 256, (i * 512 / LED_NUM) % 256, (i * 768 / LED_NUM) % 256); } WS2812_Show(); HAL_Delay(500); } }