From 49447b2738a874071a2a4bb61b3e0c2af6be989f Mon Sep 17 00:00:00 2001 From: guowenxue <guowenxue@gmail.com> Date: Wed, 08 Oct 2025 19:31:43 +0800 Subject: [PATCH] WS2812B Led灯带程序 --- Core/Src/board/ws2812b.h | 55 +++++++++++ Core/Src/board/ws2812b.c | 183 ++++++++++++++++++++++++++++++++++++ Core/Src/main.c | 11 +- 3 files changed, 243 insertions(+), 6 deletions(-) diff --git a/Core/Src/board/ws2812b.c b/Core/Src/board/ws2812b.c new file mode 100644 index 0000000..074992a --- /dev/null +++ b/Core/Src/board/ws2812b.c @@ -0,0 +1,183 @@ +/********************************************************************** + * Copyright: (C)2024 LingYun IoT System Studio + * Author: GuoWenxue<guowenxue@gmail.com> + * + * Description: WS2812B strip lights driver on ISKBoard + * + * Reference : https://blog.csdn.net/Lennon8_8/article/details/108980808 + * + * ChangeLog: + * Version Date Author Description + * V1.0.0 2024.08.29 GuoWenxue Release initial version + * + ***********************************************************************/ +#include <string.h> +#include <stdint.h> +#include "ws2812b.h" +#include "miscdev.h" + +#ifdef USE_FREERTOS +#include "cmsis_os.h" +#define mdelay(ms) osDelay(ms) +#else +#define mdelay(ms) HAL_Delay(ms) +#endif + +static color_t g_ColorPanel[WS2812_NUM]; + +typedef struct ws_gpio_s +{ + GPIO_TypeDef *group; + uint16_t pin; +} ws_gpio_t; + +static ws_gpio_t ws_gpio = /* IO pin connected to PC2 */ +{ + .group = GPIOC, + .pin = GPIO_PIN_2, +}; + +#define ws_setpin(x) if(!x) ws_gpio.group->BRR=ws_gpio.pin; else ws_gpio.group->BSRR=ws_gpio.pin + +/* + * 1 NOP = 1/80MHz = 12.5ns => 200ns = 8 * NOP + * + * */ +#define delay_200ns() { __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); \ + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); } + +void ws2812b_init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + GPIO_InitStruct.Pin = ws_gpio.pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + + HAL_GPIO_Init(ws_gpio.group, &GPIO_InitStruct); + + ws2812b_reset(); + + return ; +} + +static inline void ws2812b_WriteByte(uint8_t byte) +{ + int i; + + for(i=0; i<8; i++) + { + if(byte & 0x80) + { + /* Sequence Send 1: T1H: 580ns~1.6us T1L: 200ns~420ns: + * + * +--------------+ + + * |<- T1H ->|<- T1L ->| + * | +---------+ + */ + ws_setpin(1); // T1H + udelay(1); + + ws_setpin(0); // T1L + delay_200ns(); //200ns test okay + } + else + { + /* Sequence Send 0: T0H: 220ns~380ns T0L: 580ns~1.6ns: + * + * +---------+ + + * |<- T0H ->|<- T0L ->| + * | +--------------+ + */ + ws_setpin(1); // T0H + delay_200ns(); //200ns test okay + + ws_setpin(0); // T0L + udelay(1); + } + + byte<<=1; + } + + return ; +} + +void ws2812b_reset(void) +{ + /* Sequence Reset: Treset >280us: + * + * + + + * |<- Treset ->| + * +--------------+ + */ + ws_setpin(0); + udelay(300); + + memset(g_ColorPanel, 0, sizeof(g_ColorPanel)); + + return ; +} + +static inline void ws2812b_SendColor(color_t color) +{ + ws2812b_WriteByte(color.pixel.green); + ws2812b_WriteByte(color.pixel.red); + ws2812b_WriteByte(color.pixel.blue); + + return ; +} + +static inline void ws2812b_Refresh(void) +{ + int i; + + for(i=0; i<WS2812_NUM; i++) + { + ws2812b_SendColor(g_ColorPanel[i]); + } + + return ; +} + +static inline int ws2812b_SetPixel(int which, color_t color) +{ + if( which<0 || which>=WS2812_NUM ) + return -1; + + g_ColorPanel[which].pixel.red = color.pixel.red; + g_ColorPanel[which].pixel.green = color.pixel.green; + g_ColorPanel[which].pixel.blue = color.pixel.blue; + + return 0; +} + +int ws2812b_turn(int which, color_t color) +{ + if( which<0 || which>=WS2812_NUM ) + return -1; + + ws2812b_SetPixel(which, color); + ws2812b_Refresh(); + + return 0; +} + +void ws2812b_blink(void) +{ + int c, i; + color_t colors[4] = {[0].data=PIXEL_B, [1].data=PIXEL_R, [2].data=PIXEL_G, [3].data=PIXEL_W}; + color_t color_off = {.data = PIXEL_OFF}; + + for(c=0; c<4; c++) /* color */ + { + for(i=0; i<WS2812_NUM; i++) + { + ws2812b_turn(i, colors[c]); + mdelay(200); + ws2812b_turn(i, (color_t)color_off); + mdelay(200); + } + } +} + diff --git a/Core/Src/board/ws2812b.h b/Core/Src/board/ws2812b.h new file mode 100644 index 0000000..2f48bb5 --- /dev/null +++ b/Core/Src/board/ws2812b.h @@ -0,0 +1,55 @@ +/********************************************************************** + * Copyright: (C)2024 LingYun IoT System Studio + * Author: GuoWenxue<guowenxue@gmail.com> + * + * Description: WS2812B strip lights driver on ISKBoard + * + * Reference : https://blog.csdn.net/Lennon8_8/article/details/108980808 + * + * ChangeLog: + * Version Date Author Description + * V1.0.0 2024.08.29 GuoWenxue Release initial version + * + ***********************************************************************/ + +#ifndef __WS2812B_H_ +#define __WS2812B_H_ + +#include "stm32l4xx_hal.h" + +#define WS2812_NUM 3 + +#define PIXEL_OFF 0 /* off */ +#define PIXEL_B (0xFF<<0) /* blue */ +#define PIXEL_R (0xFF<<8) /* red */ +#define PIXEL_G (0xFF<<16) /* green */ +#define PIXEL_W (0xFFFFFF) /* white */ + +/* Composition of 24 bits data: GRB888 + * +----+----+----+----+----+----+----+----+----+ + * | G7 | ...| G0 | R7 | ...| R0 | B7 | ...| B0 | + * +----+----+----+----+----+----+----+----+----+ + */ +typedef struct pixel_s +{ + uint32_t blue:8; + uint32_t red:8; + uint32_t green:8; +} pixel_t; + +typedef union color_u +{ + pixel_t pixel; + uint32_t data; +} color_t; + + +extern void ws2812b_init(void); + +extern void ws2812b_reset(void); + +extern int ws2812b_turn(int which, color_t color); + +extern void ws2812b_blink(void); + +#endif /* __WS2812B_H_ */ diff --git a/Core/Src/main.c b/Core/Src/main.c index 970851f..6e3ad7a 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -26,6 +26,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "miscdev.h" +#include "ws2812b.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -95,19 +96,17 @@ MX_TIM1_Init(); /* USER CODE BEGIN 2 */ - init_relay(); - init_led(); - + ws2812b_init(); beep_start(2, 300); + /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { - toggle_led(Led_B); - for(int i=0; i<1000; i++) - udelay(3000); + /* Blink WS2812B strip lights */ + ws2812b_blink(); /* USER CODE END WHILE */ -- Gitblit v1.9.1