ISKBoard example project
guowenxue
5 days ago 49447b2738a874071a2a4bb61b3e0c2af6be989f
WS2812B Led灯带程序
2 files added
1 files modified
249 ■■■■■ changed files
Core/Src/board/ws2812b.c 183 ●●●●● patch | view | raw | blame | history
Core/Src/board/ws2812b.h 55 ●●●●● patch | view | raw | blame | history
Core/Src/main.c 11 ●●●● patch | view | raw | blame | history
Core/Src/board/ws2812b.c
New file
@@ -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);
        }
    }
}
Core/Src/board/ws2812b.h
New file
@@ -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_ */
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 */