第一章 电机控制算法:从PWM到智能调速
各位工程师朋友,今天我们来聊聊剃须刀最核心的部件——电机控制。说实话,一把剃须刀好不好用,九成功力都在电机控制算法上。我做了十几年嵌入式开发,踩过的坑比走过的路还多,今天就把这些经验分享给你。
1.1 直流电机PWM调速原理
先说说PWM调速。说白了,就是通过快速开关电源,让电机"感觉"到不同的电压。你想想看,如果给电机通100%的电,它就全速转;给50%的电,它就半速转。但问题来了——怎么给50%的电?
答案就是PWM。我们用一个高频开关信号,让电机在"通电"和"断电"之间快速切换。比如10kHz的频率,每秒钟开关一万次。占空比50%,就相当于电机吃到了50%的能量。
核心公式:
电机平均电压 = 电源电压 × 占空比
比如5V电源,占空比60%,电机实际感受到的就是3V
// 我常用的PWM初始化代码(STM32为例)
void Motor_PWM_Init(void) {
TIM_HandleTypeDef htim2;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; // 72MHz / 72 = 1MHz
htim2.Init.Period = 999; // 1MHz / 1000 = 1kHz PWM频率
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&htim2);
// 设置占空比50%
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 500);
}
我的经验:PWM频率别选太高也别太低。太低会有噪音(人耳能听到),太高会增加MOS管开关损耗。我个人习惯用10kHz-20kHz,既听不到噪音,效率也还行。
1.2 恒功率控制策略
剃须刀最怕什么?胡子一多,电机就转不动了。这时候如果只是简单调压,用户体验会很差。我做过一个项目,用户反馈说"剃到浓密处就卡住了"——这就是典型的功率不足。
恒功率控制,就是让电机不管负载怎么变,输出功率都保持稳定。怎么实现?看公式:
功率 = 电压 × 电流
我们实时检测电流,如果电流增大(说明负载变重了),就适当降低电压,让功率保持恒定。反过来,电流小了就升压。
// 恒功率控制伪代码
void Constant_Power_Control(void) {
uint16_t target_power = 3000; // 目标功率,单位mW
uint16_t current = Get_Motor_Current();
uint16_t voltage = Get_Motor_Voltage();
uint16_t actual_power = voltage * current / 1000;
if (actual_power < target_power) {
// 功率不足,升压
pwm_duty += 5;
if (pwm_duty > 1000) pwm_duty = 1000;
} else if (actual_power > target_power + 100) {
// 功率过高,降压
pwm_duty -= 5;
if (pwm_duty < 200) pwm_duty = 200; // 最低不低于20%
}
}
注意:恒功率控制有个坑——电流采样要准。我曾经用了一个便宜的采样电阻,温度一高阻值就漂,导致控制完全乱套。后来换了低温漂电阻,问题才解决。
1.3 堵转检测与保护
堵转,就是电机被卡住转不动了。剃须刀里最常见的情况是:刀网里卡了一根粗胡子,或者刀头被胡茬堵死。如果不做保护,电机电流会飙升,轻则烧MOS管,重则冒烟。
怎么检测堵转?我总结了三个方法:
- 电流检测法:正常运行时电流在200-500mA,堵转时瞬间飙到2A以上
- 转速检测法:用霍尔传感器测转速,如果设定转速和实际转速偏差超过30%,判定堵转
- 反电动势检测法:电机断电后测反电动势,堵转时反电动势几乎为零
我个人最常用的是电流检测法,简单可靠。但要注意——不能只看瞬时电流,要加一个时间窗口。比如连续50ms电流超过阈值,才判定为堵转。为什么?因为启动瞬间也会有电流尖峰,别误判了。
// 堵转检测实现
#define STALL_CURRENT_THRESHOLD 2000 // 2A
#define STALL_TIME_THRESHOLD 50 // 50ms
uint8_t Check_Stall(void) {
static uint16_t stall_count = 0;
uint16_t current = Get_Motor_Current();
if (current > STALL_CURRENT_THRESHOLD) {
stall_count++;
if (stall_count > STALL_TIME_THRESHOLD) {
return 1; // 堵转!
}
} else {
stall_count = 0;
}
return 0;
}
void Stall_Protection(void) {
if (Check_Stall()) {
Motor_Stop(); // 立即停止
Delay_ms(1000); // 等待1秒
Motor_Start_LowPower(); // 以低功率重启
}
}
避坑指南:我曾经遇到过一个问题——堵转保护太灵敏,用户胡子稍微浓密一点就触发保护,体验很差。后来我加了一个"软启动"机制:检测到堵转后,先尝试以20%功率运行0.5秒,如果电流降下来了就继续,否则才彻底停机。这样既保护了电机,又不影响正常使用。
1.4 多档位平滑切换
现在的剃须刀都有好几个档位:轻柔模式、标准模式、强力模式。但档位切换如果做得不好,用户体验会很糟糕。你想想看,正剃着胡子,突然电机从低速跳到高速——"嗡"的一声,吓一跳不说,还可能刮伤皮肤。
平滑切换的核心思想是:不要让占空比突变,而是让它慢慢爬升或下降。我一般用两种方法:
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 线性渐变 | 每次增加/减少固定步长 | 实现简单 | 加速感不够自然 |
| S曲线渐变 | 用正弦曲线或指数曲线控制变化率 | 手感顺滑 | 计算量稍大 |
// 线性渐变切换
void Smooth_Switch(uint16_t target_duty) {
static uint16_t current_duty = 0;
int16_t step = 5; // 每次变化5个单位
if (current_duty < target_duty) {
current_duty += step;
if (current_duty > target_duty) current_duty = target_duty;
} else if (current_duty > target_duty) {
current_duty -= step;
if (current_duty < target_duty) current_duty = target_duty;
}
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, current_duty);
Delay_ms(10); // 每10ms变化一次
}
我的建议:档位切换时间控制在300-500ms比较合适。太快了感觉突兀,太慢了用户会以为机器坏了。另外,切换过程中最好保持恒功率控制开启,这样即使负载变化,转速也能平稳过渡。
嗯,以上就是电机控制算法的核心内容。说白了,PWM是基础,恒功率是灵魂,堵转保护是安全底线,平滑切换是体验加分项。把这四点做好了,你的剃须刀电机控制就基本合格了。
下一章我们聊聊传感器融合——怎么让剃须刀"感知"到用户的胡须密度和皮肤状态。敬请期待。