Files
ZhaTianRC/Core/Src/pwm_out.c

133 lines
3.9 KiB
C

/**
* PWM 输出与 LED 控制模块实现
*/
#include "pwm_out.h"
/* 全局配置 */
uint8_t pwm1_mode = PWM_MODE_DISABLED;
uint8_t pwm2_mode = PWM_MODE_DISABLED;
uint8_t ws2812_effect = WS2812_MODE_RAINBOW_BREATH;
uint8_t led_brightness = 50;
uint8_t vibrate_level = 5;
/* LED 闪烁状态 */
static uint8_t led_nrf_mode = 3; /* 0=慢闪, 1=快闪, 2=常亮, 3=灭 */
static uint8_t led_crfs_mode = 3;
static uint16_t led_tick = 0;
static uint8_t led_blink_state = 0;
/* WS2812 动画状态 */
static uint8_t ws2812_tick = 0;
static uint8_t ws2812_hue = 0;
void PWM_Init(void) {
/* 启动 TIM3 PWM (LED 指示灯) */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); /* PC6 - 系统状态 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); /* PC7 - NRF 状态 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); /* PC8 - CRFS 状态 */
/* 初始全灭 */
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
/* TIM4 初始关闭 */
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_4);
}
/* ---- LED 指示灯 ---- */
void LED_SetSystem(uint8_t on) {
/* PC6: 系统状态 - 开机常亮 */
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, on ? 65535 : 0);
}
void LED_SetNRF(uint8_t mode) {
led_nrf_mode = mode;
}
void LED_SetCRFS(uint8_t mode) {
led_crfs_mode = mode;
}
void LED_Update(void) {
led_tick++;
/* NRF LED (PC7) */
uint16_t nrf_val = 0;
switch (led_nrf_mode) {
case 0: /* 慢闪: 500ms on / 500ms off */
nrf_val = ((led_tick % 100) < 50) ? 65535 : 0;
break;
case 1: /* 快闪: 100ms on / 100ms off */
nrf_val = ((led_tick % 20) < 10) ? 65535 : 0;
break;
case 2: /* 常亮 */
nrf_val = 65535;
break;
case 3: /* 灭 */
default:
nrf_val = 0;
break;
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, nrf_val);
/* CRFS LED (PC8) */
uint16_t crfs_val = 0;
switch (led_crfs_mode) {
case 0: crfs_val = ((led_tick % 100) < 50) ? 65535 : 0; break;
case 1: crfs_val = ((led_tick % 20) < 10) ? 65535 : 0; break;
case 2: crfs_val = 65535; break;
default: crfs_val = 0; break;
}
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, crfs_val);
}
/* ---- PWM 输出控制 ---- */
void PWM_SetMode(uint8_t ch, uint8_t mode) {
if (ch == 0) {
pwm1_mode = mode;
if (mode == PWM_MODE_DISABLED) {
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3);
} else {
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
}
} else {
pwm2_mode = mode;
if (mode == PWM_MODE_DISABLED) {
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_4);
} else {
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
}
}
}
void PWM_SetWS2812Mode(uint8_t mode) {
if (mode >= WS2812_MODE_COUNT) return;
ws2812_effect = mode;
ws2812_tick = 0;
ws2812_hue = 0;
}
void PWM_SetLEDBrightness(uint8_t brightness) {
if (brightness > 100) brightness = 100;
led_brightness = brightness;
uint16_t pwm_val = (uint32_t)65535 * brightness / 100;
/* 应用到已启用的 LED 模式通道 */
if (pwm1_mode == PWM_MODE_LED)
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, pwm_val);
if (pwm2_mode == PWM_MODE_LED)
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, pwm_val);
}
void PWM_SetVibrateLevel(uint8_t level) {
if (level < VIBRATE_LEVEL_MIN) level = VIBRATE_LEVEL_MIN;
if (level > VIBRATE_LEVEL_MAX) level = VIBRATE_LEVEL_MAX;
vibrate_level = level;
uint16_t pwm_val = (uint32_t)65535 * level / VIBRATE_LEVEL_MAX;
if (pwm1_mode == PWM_MODE_VIBRATE)
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, pwm_val);
if (pwm2_mode == PWM_MODE_VIBRATE)
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, pwm_val);
}