一、RGB三色灯模块介绍
RGB三色灯模块是一种可以显示多种颜色的LED模块。RGB代表红色(Red)、绿色(Green)和蓝色(Blue)三种基本颜色。通过调节每种颜色的亮度,RGB灯可以混合出数百万种不同的颜色,因此它常用于各种电子项目、灯光效果、显示器背光等应用中。

RGB三色灯模块基本介绍:
1工作原理:
RGB三色灯模块包含三个独立的LED芯片:一个红色LED、一个绿色LED和一个蓝色LED。当这三个LED的亮度按不同的比例变化时,它们可以混合出不同的颜色。例如:
红色:只有红色LED亮起。
绿色:只有绿色LED亮起。
蓝色:只有蓝色LED亮起。
白色:红、绿、蓝三个LED都亮起。 通过调整每个LED的亮度,可以获得不同的颜色。
常见类型:
共阴RGB LED:所有的LED的阴极(负极)端共享一个引脚,而红、绿、蓝的阳极(正极)分别有各自的引脚。
共阳RGB LED:所有的LED的阳极(正极)端共享一个引脚,而红、绿、蓝的阴极(负极)分别有各自的引脚。
不同的模块和控制方式会根据使用的LED类型(共阴或共阳)有所不同。
OK,接下来进入我们的配置时间,首先打开cubemx,按照自己的单片机型号配置好时钟和然后在调试接口里面选择SW ,我这里用的是正点原子的精英开发板,所以按照此方法操作
1. 新建工程并选择芯片
-
打开 STM32CubeMX,点击
ACCESS TO MCU SELECTOR -
搜索并选择:STM32F103ZET6
-
双击确认
2. 配置调试接口(重要!)
在 Pinout & Configuration 界面:
-
点击
System Core→SYS -
将
Debug设置为Serial Wire
如果不设置这一步,下载一次程序后芯片可能被锁住无法再次下载。
3. 配置时钟源
-
点击
System Core→RCC -
将
High Speed Clock (HSE)设置为Crystal/Ceramic Resonator(外部晶振) -
将
Low Speed Clock (LSE)设置为Disable(暂时不用)
4. 配置定时器 TIM3 为 PWM 输出(核心步骤)
在左侧 Timers 中找到并点击 TIM3:
第一步:激活三个通道
-
Channel1设置为PWM Generation CH1 -
Channel2设置为PWM Generation CH2 -
Channel3设置为PWM Generation CH3
此时你会在芯片引脚图上看到 PA6、PA7、PB0 被自动分配为 TIM3 的通道引脚。
第二步:配置参数(重要!因为模块是共阳、低电平有效)
点击 Parameter Settings 选项卡,按以下值设置:
| 参数 | 设置值 | 说明 |
|---|---|---|
| Prescaler (预分频器) | 72-1 | 72MHz ÷ 72 = 1MHz,每 1us 计数一次 |
| Counter Mode | Up (向上计数) | 标准模式 |
| Counter Period (ARR) | 100-1 | 计数值范围 0-99,共 100 个等级 |
| Auto-reload preload | Enable | 使能自动重装 |
| Pulse (CH1) | 0 | 初始占空比 0%,后续代码中动态修改 |
| Pulse (CH2) | 0 | 同上 |
| Pulse (CH3) | 0 | 同上 |
| CH Polarity | Low | ⚠️ 关键!低电平为有效电平,适配共阳模块 |
参数计算验证:
-
PWM 频率 = 72MHz ÷ 72 ÷ 100 = 10kHz
-
占空比精度 = 1/100 = 1% 步进
-
这个频率下 LED 看起来是常亮的,不会闪烁
5. 配置时钟树
点击 Clock Configuration 选项卡:
-
HSE输入:8 MHz(根据你板子上实际晶振频率) -
PLL Source Mux:选择 HSE -
PLL Mul:选择x9(8MHz × 9 = 72MHz) -
最终确认
SYSCLK= 72 MHz
STM32F103 最高频率为 72MHz,这是最常用的配置。
然后打开Connectivity-USART1,将Mode设置为Asynchronous,cubemx会自动配置好串口1,波特率等默认即可
接下来点击Project Manager,按图中配置将Toolchain /IDE选为cMake

完成后点击右上角生成代码即可
接下里将生成的代码用vscode打开,在main.c中添加代码,如下所示
cs
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* Start all 3 PWM channels for RGB LED */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); /* LED_R on PB4 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); /* LED_B on PB5 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); /* LED_G on PB0 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* ── 1. Red ─────────────────────────────────── */
{
uint8_t msg[] = "Color: Red\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
HAL_Delay(1);
}
/* ── 2. Green ───────────────────────────────── */
{
uint8_t msg[] = "Color: Green\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
/* ── 3. Blue ────────────────────────────────── */
{
uint8_t msg[] = "Color: Blue\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
HAL_Delay(1);
}
/* ── 4. Yellow (Red + Green) ────────────────── */
{
uint8_t msg[] = "Color: Yellow\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
/* ── 5. Purple (Red + Blue) ─────────────────── */
{
uint8_t msg[] = "Color: Purple\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
HAL_Delay(1);
}
/* ── 6. Cyan (Green + Blue) ─────────────────── */
{
uint8_t msg[] = "Color: Cyan\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
/* ── 7. White (Red + Green + Blue) ──────────── */
{
uint8_t msg[] = "Color: White\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg) - 1, 100);
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
for (uint16_t p = 0; p < 500; p++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
for (uint16_t p = 500; p > 0; p--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, p);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, p);
HAL_Delay(1);
}
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
七色呼吸循环
Red → Green → Blue → Yellow → Purple → Cyan → White → Red...
每个颜色的行为:
- 串口输出当前颜色名称
- 渐亮 1 秒(PWM 0→499)
- 渐暗 1 秒(PWM 499→0)
| 顺序 | 颜色 | 混合方式 | 串口输出 |
|---|---|---|---|
| 1 | 🔴 红 | R 单独 | Color: Red |
| 2 | 🟢 绿 | G 单独 | Color: Green |
| 3 | 🔵 蓝 | B 单独 | Color: Blue |
| 4 | 🟡 黄 | R+G 同步 | Color: Yellow |
| 5 | 🟣 紫 | R+B 同步 | Color: Purple |
| 6 | 🔵 青 | G+B 同步 | Color: Cyan |
| 7 | ⚪ 白 | R+G+B 同步 | Color: White |
复合颜色(黄/紫/青/白)呼吸时,多个通道的 PWM 同步渐变,保证色相始终一致。每个颜色 2 秒,完整一轮约 14 秒。
现象如下

三色rgbled