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