PWM实现LED渐变效果及彩灯控制
一、硬件
1. 核心电路设计
| 模块 | 参数要求 | 典型值 |
|---|---|---|
| PWM控制器 | 带PWM输出的MCU | STM32F103/ESP32 |
| LED类型 | 共阳/共阴RGB LED | WS2812B(数字控制) |
| 限流电阻 | 根据LED正向压降计算 | 220Ω-1kΩ |
| 电源 | 3.3V/5V系统供电 | 200mA以上 |
连接示例(STM32):
STM32引脚 → RGB LED
---------------------
TIM3_CH2 → R (PB5)
TIM3_CH3 → G (PB0)
TIM3_CH4 → B (PB1)
GND → 公共地
3.3V → 电源输入
2. 电气参数计算
-
限流电阻计算:
![]()
(示例:V_CC=3.3V,V_f=2V,I=20mA → R=65Ω)
-
PWM频率选择:
![]()
(推荐值:500Hz-2kHz)
二、软件
1. 基础渐变算法
// 定义颜色通道结构体
typedef struct {
uint16_t duty; // 占空比(0-65535)
GPIO_TypeDef* port;
uint16_t pin;
} LED_Channel;
// 线性渐变函数
void linear_fade(LED_Channel* channels, uint8_t num_channels,
uint32_t target_duty, uint32_t step,
uint32_t delay_ms) {
static int16_t direction = 1;
static uint32_t current_duty = 0;
for(int i=0; i<num_channels; i++) {
current_duty += step * direction;
if(current_duty >= 65535 || current_duty <= 0) {
direction *= -1;
current_duty = constrain(current_duty, 0, 65535);
}
ledc_set_duty(LEDC_HIGH_SPEED_MODE, channels[i].channel, current_duty);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, channels[i].channel);
}
vTaskDelay(delay_ms / portTICK_PERIOD_MS);
}
2. 呼吸灯实现(STM32 HAL库)
// 定时器配置(TIM3)
void MX_TIM3_Init(void) {
TIM_HandleTypeDef htim3;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 72-1; // 1MHz
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535; // 最大占空比
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim3);
// 通道配置
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2); // R
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3); // G
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4); // B
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
}
// 呼吸灯主循环
void breathing_led() {
uint16_t duty = 0;
uint8_t dir = 1;
while(1) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, duty);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 65535-duty);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0);
duty += dir;
if(duty == 0 || duty == 65535) dir = -dir;
HAL_Delay(1);
}
}
三、进阶功能实现
1. 彩虹渐变算法
// HSV转RGB算法
void hsv2rgb(float h, float s, float v, uint16_t* r, uint16_t* g, uint16_t* b) {
float c = v * s;
float x = c * (1 - fabs(fmod(h/60.0, 2) - 1));
float m = v - c;
if(h >= 0 && h < 60) { *r = c; *g = x; *b = 0; }
else if(h >= 60 && h < 120) { *r = x; *g = c; *b = 0; }
else if(h >= 120 && h < 180) { *r = 0; *g = c; *b = x; }
else if(h >= 180 && h < 240) { *r = 0; *g = x; *b = c; }
else if(h >= 240 && h < 300) { *r = x; *g = 0; *b = c; }
else { *r = c; *g = 0; *b = x; }
*r = (uint16_t)((*r + m) * 65535 / 255);
*g = (uint16_t)((*g + m) * 65535 / 255);
*b = (uint16_t)((*b + m) * 65535 / 255);
}
// 彩虹渐变主循环
void rainbow_fade() {
float hue = 0.0;
while(1) {
hsv2rgb(hue, 1.0, 1.0, &r_duty, &g_duty, &b_duty);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, RED_CHANNEL, r_duty);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, GREEN_CHANNEL, g_duty);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, BLUE_CHANNEL, b_duty);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, RED_CHANNEL);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, GREEN_CHANNEL);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, BLUE_CHANNEL);
hue += 0.5;
if(hue >= 360) hue = 0;
HAL_Delay(10);
}
}
2. 呼吸灯优化方案
// 正弦波呼吸算法
void sine_wave_breathing() {
float phase = 0.0;
while(1) {
float duty = (sin(phase * M_PI / 180) + 1) * 32767; // 16位范围
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (uint32_t)duty);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 65535 - (uint32_t)duty);
phase += 1;
if(phase >= 360) phase = 0;
HAL_Delay(1);
}
}
四、工程实现要点
1. 硬件保护电路
LED驱动电路设计
----------------
MCU PWM → 电阻 → 二极管 → 电感 → LED
↑
续流二极管
2. 中断服务程序
// 定时器中断处理
void TIM3_IRQHandler() {
if(TIM_GetITStatus(TIM3, TIM_IT_UPDATE) != RESET) {
TIM_ClearITPendingBit(TIM3, TIM_IT_UPDATE);
// 动态调整占空比
static uint16_t duty = 0;
duty = (duty + 1024) % 65536;
TIM_SetCompare2(TIM3, duty);
}
}
3. 低功耗优化
// 进入睡眠模式
void enter_sleep_mode() {
HAL_PWR_DisablePVD();
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
// 唤醒配置
void EXTI0_IRQHandler() {
if(EXTI_GetITStatus(EXTI_Line0) != RESET) {
EXTI_ClearITPendingBit(EXTI_Line0);
HAL_PWR_DisableSleepDeep();
}
}
参考代码 基于PWM的LED渐变效果及彩灯 www.youwenfan.com/contentcnj/72808.html
五、扩展应用场景
1. 智能照明系统
// 光照感应控制
void ambient_light_control() {
float lux = read_lux_sensor();
float target_duty = 65535 * (lux / 10000.0); // 0-10000lux
ledc_set_duty(LEDC_HIGH_SPEED_MODE, RED_CHANNEL, target_duty);
}
2. 节日灯光秀
// 预设灯光模式
typedef enum {
MODE_STATIC,
MODE_FADE,
MODE_BREATHE,
MODE_RAINBOW
} LightMode;
void execute_light_show() {
static LightMode current_mode = MODE_STATIC;
switch(current_mode) {
case MODE_STATIC:
set_static_color(0xFFFF, 0x0000, 0x0000); // 纯红色
break;
case MODE_FADE:
linear_fade(channels, 3, 65535, 1024, 50);
break;
case MODE_BREATHE:
sine_wave_breathing();
break;
case MODE_RAINBOW:
rainbow_fade();
break;
}
}


浙公网安备 33010602011771号