HB-WS2812 灯盘模块

STM32F103C8T6 · HAL库开发 · 软件I2C通信 · 19种灯光模式

主控芯片
STM32F103C8T6
驱动芯片
STC8GK08A
灯珠数量
10 × WS2812
通信方式
I2C (0x5A)
灯光模式
19种
系统时钟
72 MHz
1传感器原理与功能

HB-WS2812 灯盘模块的工作原理与核心功能介绍

1.1 工作原理

HB-WS2812 灯盘模块由 10颗 WS2812 RGB灯珠 与 STC8GK08A 驱动芯片 组成。WS2812 是一款内置IC的三通道RGB LED,每颗灯珠内部集成了锁存器、移位寄存器和PWM控制电路,支持单线级联数据传输。

模块以 I2C协议 与STM32通信,I2C从机地址为 0x5A。STM32通过软件模拟I2C向STC8GK08A发送 模式寄存器(地址0x00) 和 亮度寄存器(地址0x01) 的数据,驱动芯片根据收到的指令控制10颗WS2812灯珠呈现不同的灯光效果。

STC8GK08A芯片内部预置了19种灯光模式(包括纯色、动态效果、呼吸灯等),通过寄存器配置即可切换模式,无需STM32逐颗发送WS2812时序数据,大大降低了主控负担。

🎨

19种灯光模式

涵盖暖白、冷白、红橙黄绿青蓝紫等纯色,以及全彩缓慢、灯珠滚动、彩色积累、灯光旋转、呼吸灯等动态效果,一键切换。

💡

亮度可调

通过I2C写入亮度寄存器(地址0x01),支持0~5共6级亮度调节,其中0为熄灭,5为最大亮度,适应不同场景的照明需求。

📡

I2C总线通信

采用软件模拟I2C协议,仅需SCL和SDA两根GPIO线即可完成双向通信,从机地址0x5A,接线简单可靠。

🖥️

OLED实时显示

外接0.96寸OLED显示屏,通过独立I2C总线(PB14/PB15)实时显示当前灯光模式名称,直观可视。

1.3 引脚定义

模块引脚类型功能说明STM32连接
VCC电源模块供电正极,3.3V~5V3.3V / 5V
GND电源模块供电负极,地线GND
SCLI2CI2C时钟线,开漏输出PB3
SDAI2CI2C数据线,开漏输出PB4
2模块外观展示

HB-WS2812灯盘模块正面与背面实物展示

模块正面
模块正面 — 10颗WS2812灯珠环形排列
模块背面
模块背面 — STC8GK08A驱动芯片及接口
3原理图与PCB封装

模块电路原理图与PCB封装设计

原理图
原理图.png
PCB封装
PCB封装.png
4程序分析

STM32F103C8T6 HAL库工程源代码深度解析

4.1 主程序逻辑 (main.c)

主程序完成系统时钟配置、GPIO初始化、OLED初始化和WS2812 I2C初始化后,进入while(1)主循环。循环中依次切换19种灯光模式,通过WS2812_Set()发送模式与亮度,OLED同步显示当前模式名。模式0~12为静态颜色,延时1秒;模式13~18为动态效果,延时5秒。

main.c
 1/* USER CODE BEGIN PV */
 2uint8_t mode;
 3
 4const char *Color[] = {
 5    "关闭", "暖白1", "暖白2", "白色", "冷色", "冷白",
 6    "红色", "橙色", "黄色", "绿色", "青色", "蓝色", "紫色",
 7    "全彩缓慢", "灯珠滚动", "彩色积累", "灯光旋转",
 8    "红色呼吸灯", "暖黄色"
 9};
10
11int main(void)
12{
13  HAL_Init();
14  SystemClock_Config();
15  MX_GPIO_Init();
16  OLED_Init();
17  WS2812_I2C_Init();
18
19  WS2812_Set(mode, 5);  // 初始模式=关闭, 亮度=5
20  OLED_CenterPrintf(24, "mode:%s", Color[mode]);
21  OLED_Update();
22  HAL_Delay(1000);
23
24  while (1)
25  {
26    // 灯盘模式更新: 0→18循环
27    (mode < 18) ? (mode++) : (mode = 0);
28    WS2812_Set(mode, 5);  // 发送模式+亮度
29
30    // OLED显示更新
31    OLED_Clear();
32    OLED_CenterPrintf(24, "mode:%s", Color[mode]);
33    OLED_Update();
34
35    // 动态效果延时5s, 静态颜色延时1s
36    if(mode >= 13)
37      HAL_Delay(5000);
38    else
39      HAL_Delay(1000);
40  }
41}

4.2 WS2812 I2C驱动 (WS2812.c)

软件模拟I2C协议,使用GPIO开漏输出模式(PB3=SCL, PB4=SDA)。实现了完整的I2C时序函数:起始信号、停止信号、字节发送/接收、ACK应答等。WS2812_Set()向从机地址0x5A写入模式寄存器(地址0x00)和亮度寄存器(地址0x01)。

WS2812.c
 1#include "./HAL/WS2812/WS2812.h"
 2
 3#define WS2818_ADDRESS 0x5a
 4
 5static void Delay_1us(uint16_t time)
 6{
 7  uint8_t i;
 8  while(time)
 9  {
10    for (i = 0; i < 10; i++) {}
11    time--;
12  }
13}
14
15/* SCL写位 */
16void WS2812_I2C_W_SCL(uint8_t BitValue)
17{
18  HAL_GPIO_WritePin(WS2812_W_SCL_Port, WS2812_W_SCL_Pin, (GPIO_PinState)BitValue);
19  Delay_1us(10);
20}
21
22/* SDA写位 */
23void WS2812_I2C_W_SDA(uint8_t BitValue)
24{
25  HAL_GPIO_WritePin(WS2812_W_SDA_Port, WS2812_W_SDA_Pin, (GPIO_PinState)BitValue);
26  Delay_1us(10);
27}
28
29/* GPIO初始化: 开漏输出模式 */
30void WS2812_I2C_Init(void)
31{
32  __HAL_RCC_GPIOB_CLK_ENABLE();
33  GPIO_InitTypeDef GPIO_InitStruct = {0};
34  GPIO_InitStruct.Pin = WS2812_W_SCL_Pin|WS2812_W_SDA_Pin;
35  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;  // 开漏输出
36  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
37  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
38  WS2812_I2C_W_SCL(1);
39  WS2812_I2C_W_SDA(1);
40}
41
42/* I2C起始信号 */
43void WS2812_I2C_Start(void)
44{
45  WS2812_I2C_W_SDA(1);
46  WS2812_I2C_W_SCL(1);
47  WS2812_I2C_W_SDA(0);
48  WS2812_I2C_W_SCL(0);
49}
50
51/* I2C停止信号 */
52void WS2812_I2C_Stop(void)
53{
54  WS2812_I2C_W_SDA(0);
55  WS2812_I2C_W_SCL(1);
56  WS2812_I2C_W_SDA(1);
57}
58
59/* 写寄存器: 地址+数据 */
60void WS2812_WriteByte(unsigned char WordAddress, unsigned char Data)
61{
62  WS2812_I2C_Start();
63  WS2812_I2C_SendByte(WS2818_ADDRESS);   // 从机地址 0x5A
64  WS2812_I2C_ReceiveAck();
65  WS2812_I2C_SendByte(WordAddress);        // 寄存器地址
66  WS2812_I2C_ReceiveAck();
67  WS2812_I2C_SendByte(Data);               // 数据
68  WS2812_I2C_ReceiveAck();
69  WS2812_I2C_Stop();
70}
71
72/* 设置模式与亮度 */
73void WS2812_Set(uint8_t WS2812_Mode, uint8_t WS2812_Light)
74{
75  WS2812_WriteByte(0, WS2812_Mode);    // 寄存器0=模式
76  WS2812_WriteByte(1, WS2812_Light);  // 寄存器1=亮度
77}

4.3 GPIO配置 (gpio.c)

CubeMX生成的GPIO初始化仅使能了GPIOD和GPIOA时钟(用于HSE晶振和SWD调试)。WS2812和OLED的GPIO初始化在各自驱动文件中完成,均使用GPIOB端口。

gpio.c
 1void MX_GPIO_Init(void)
 2{
 3  __HAL_RCC_GPIOD_CLK_ENABLE();
 4  __HAL_RCC_GPIOA_CLK_ENABLE();
 5}

4.4 系统时钟配置 (SystemClock_Config)

使用外部高速晶振(HSE)8MHz,通过PLL倍频9倍得到72MHz系统时钟。APB1分频为36MHz,APB2保持72MHz。Flash等待周期设为2个等待状态。

main.c - SystemClock_Config
 1void SystemClock_Config(void)
 2{
 3  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 4  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 5
 6  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 7  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 8  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
 9  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
10  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
11  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 8MHz×9=72MHz
12  HAL_RCC_OscConfig(&RCC_OscInitStruct);
13
14  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
15                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
16  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
17  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;   // AHB=72MHz
18  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;   // APB1=36MHz
19  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;   // APB2=72MHz
20  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
21}

4.5 灯光模式对照表

19种灯光模式及其I2C寄存器值、颜色效果对照。模式0~12为静态颜色,模式13~18为动态效果。程序中亮度固定为5(最大亮度)。

模式值枚举名中文名称颜色效果类型
0Off关闭 熄灭静态
1WarWhite_1暖白1 暖白光静态
2WarmWhite_2暖白2 暖白光静态
3White白色 纯白光静态
4Cold冷色 冷色光静态
5ColdWhite冷白 冷白光静态
6Red红色 纯红静态
7Orange橙色 橙色静态
8Yellow黄色 纯黄静态
9Green绿色 纯绿静态
10Cyan青色 纯青静态
11Blue蓝色 纯蓝静态
12Purple紫色 纯紫静态
13Colour全彩缓慢 RGB渐变动态
14ColorScrolling灯珠滚动 逐颗点亮动态
15ColorAccumulation彩色积累 色彩叠加动态
16ColourRotation_2灯光旋转 旋转扫描动态
17RedBreathing红色呼吸灯 红色呼吸动态
18Yellow_2暖黄色 暖黄光静态
5程序流程图

STM32主程序执行流程,含while(1)主循环

开始 HAL_Init() 系统初始化 SystemClock_Config() 时钟72MHz MX_GPIO_Init() GPIO初始化 OLED_Init() OLED初始化 WS2812_I2C_Init() I2C初始化 WS2812_Set(mode=0, 亮度=5) OLED显示 "mode:关闭" + HAL_Delay while(1) 主循环 mode自增: 0→18循环 WS2812_Set(mode, 亮度=5) OLED清屏+显示模式名+更新 mode≥13? 是 Delay 5s 否 Delay 1s 返回循环顶部
6交互式动画演示

模拟HB-WS2812灯盘模块工作过程,左侧模拟灯盘,右侧模拟OLED显示

灯盘模拟 (10×WS2812)
OLED显示屏
mode:关闭
亮度仪表
I2C地址: 0x5A
模式寄存器(0x00): 0x00
亮度寄存器(0x01): 0x05
延时: 1000ms

动画说明

左侧Canvas模拟HB-WS2812灯盘的10颗WS2812灯珠环形排列,根据当前模式实时渲染颜色与动态效果。右侧模拟0.96寸OLED显示屏,显示当前模式名称,并展示I2C寄存器数据。点击"开始"自动循环切换19种模式,也可点击下方模式按钮手动切换。