HB-WS2812 灯盘模块
STM32F103C8T6 · HAL库开发 · 软件I2C通信 · 19种灯光模式
STM32F103C8T6 · HAL库开发 · 软件I2C通信 · 19种灯光模式
HB-WS2812 灯盘模块的工作原理与核心功能介绍
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时序数据,大大降低了主控负担。
涵盖暖白、冷白、红橙黄绿青蓝紫等纯色,以及全彩缓慢、灯珠滚动、彩色积累、灯光旋转、呼吸灯等动态效果,一键切换。
通过I2C写入亮度寄存器(地址0x01),支持0~5共6级亮度调节,其中0为熄灭,5为最大亮度,适应不同场景的照明需求。
采用软件模拟I2C协议,仅需SCL和SDA两根GPIO线即可完成双向通信,从机地址0x5A,接线简单可靠。
外接0.96寸OLED显示屏,通过独立I2C总线(PB14/PB15)实时显示当前灯光模式名称,直观可视。
| 模块引脚 | 类型 | 功能说明 | STM32连接 |
|---|---|---|---|
| VCC | 电源 | 模块供电正极,3.3V~5V | 3.3V / 5V |
| GND | 电源 | 模块供电负极,地线 | GND |
| SCL | I2C | I2C时钟线,开漏输出 | PB3 |
| SDA | I2C | I2C数据线,开漏输出 | PB4 |
HB-WS2812灯盘模块正面与背面实物展示
模块电路原理图与PCB封装设计
STM32F103C8T6 HAL库工程源代码深度解析
主程序完成系统时钟配置、GPIO初始化、OLED初始化和WS2812 I2C初始化后,进入while(1)主循环。循环中依次切换19种灯光模式,通过WS2812_Set()发送模式与亮度,OLED同步显示当前模式名。模式0~12为静态颜色,延时1秒;模式13~18为动态效果,延时5秒。
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}
软件模拟I2C协议,使用GPIO开漏输出模式(PB3=SCL, PB4=SDA)。实现了完整的I2C时序函数:起始信号、停止信号、字节发送/接收、ACK应答等。WS2812_Set()向从机地址0x5A写入模式寄存器(地址0x00)和亮度寄存器(地址0x01)。
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}
CubeMX生成的GPIO初始化仅使能了GPIOD和GPIOA时钟(用于HSE晶振和SWD调试)。WS2812和OLED的GPIO初始化在各自驱动文件中完成,均使用GPIOB端口。
1void MX_GPIO_Init(void) 2{ 3 __HAL_RCC_GPIOD_CLK_ENABLE(); 4 __HAL_RCC_GPIOA_CLK_ENABLE(); 5}
使用外部高速晶振(HSE)8MHz,通过PLL倍频9倍得到72MHz系统时钟。APB1分频为36MHz,APB2保持72MHz。Flash等待周期设为2个等待状态。
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}
19种灯光模式及其I2C寄存器值、颜色效果对照。模式0~12为静态颜色,模式13~18为动态效果。程序中亮度固定为5(最大亮度)。
| 模式值 | 枚举名 | 中文名称 | 颜色效果 | 类型 |
|---|---|---|---|---|
| 0 | Off | 关闭 | 熄灭 | 静态 |
| 1 | WarWhite_1 | 暖白1 | 暖白光 | 静态 |
| 2 | WarmWhite_2 | 暖白2 | 暖白光 | 静态 |
| 3 | White | 白色 | 纯白光 | 静态 |
| 4 | Cold | 冷色 | 冷色光 | 静态 |
| 5 | ColdWhite | 冷白 | 冷白光 | 静态 |
| 6 | Red | 红色 | 纯红 | 静态 |
| 7 | Orange | 橙色 | 橙色 | 静态 |
| 8 | Yellow | 黄色 | 纯黄 | 静态 |
| 9 | Green | 绿色 | 纯绿 | 静态 |
| 10 | Cyan | 青色 | 纯青 | 静态 |
| 11 | Blue | 蓝色 | 纯蓝 | 静态 |
| 12 | Purple | 紫色 | 纯紫 | 静态 |
| 13 | Colour | 全彩缓慢 | RGB渐变 | 动态 |
| 14 | ColorScrolling | 灯珠滚动 | 逐颗点亮 | 动态 |
| 15 | ColorAccumulation | 彩色积累 | 色彩叠加 | 动态 |
| 16 | ColourRotation_2 | 灯光旋转 | 旋转扫描 | 动态 |
| 17 | RedBreathing | 红色呼吸灯 | 红色呼吸 | 动态 |
| 18 | Yellow_2 | 暖黄色 | 暖黄光 | 静态 |
STM32主程序执行流程,含while(1)主循环
模拟HB-WS2812灯盘模块工作过程,左侧模拟灯盘,右侧模拟OLED显示
左侧Canvas模拟HB-WS2812灯盘的10颗WS2812灯珠环形排列,根据当前模式实时渲染颜色与动态效果。右侧模拟0.96寸OLED显示屏,显示当前模式名称,并展示I2C寄存器数据。点击"开始"自动循环切换19种模式,也可点击下方模式按钮手动切换。