如何使用Black Pill板读取与输出PWM解决直流电机调速仅开关问题
问题根因与修复方案
一、代码问题(是无法调速、PWM读取异常的核心原因)
- 运算符优先级错误:你写的
if(s = (map(pulseIn(rc, HIGH), 1100, 1900, 0, 255)) > 200)存在优先级逻辑错误,比较运算符>优先级高于赋值运算符=,实际执行逻辑是先判断map输出值是否大于200,再把布尔结果(0或1)赋值给s,s只有两种取值,自然只能实现开关控制。 - 未使用PWM输出接口:全程调用
digitalWrite只能输出高低电平,要实现调速必须调用analogWrite输出可调占空比的PWM信号给MOS管。 pulseIn阻塞风险:默认pulseIn超时时间长,且是阻塞式读取,配合loop里的10ms延时,很容易漏掉接收机的PWM脉冲,导致读取失败。- 未做数值限幅:接收机输出脉宽可能超出11001900范围,map输出会溢出0255区间,直接输出会导致驱动异常。
修改后的参考代码:
int Motor = PA15; int rc = PB1; int s; void setup() { pinMode(Motor, OUTPUT); pinMode(rc, INPUT); analogWriteFrequency(Motor, 20000); // 设置PWM频率为20KHz,避免电机啸叫 analogWriteResolution(8); // 设置8位分辨率,对应0~255调节范围 digitalWrite(Motor, LOW); } void loop() { // 读取高电平脉宽,设置25ms超时(对应接收机50Hz刷新周期) unsigned int rcPulse = pulseIn(rc, HIGH, 25000); if(rcPulse > 0) { // 读取到有效脉冲再处理 s = map(rcPulse, 1100, 1900, 0, 255); s = constrain(s, 0, 255); // 限幅,避免数值溢出 } analogWrite(Motor, s); // 输出PWM调速 delay(10); }
二、硬件问题排查点
- 接收机PWM读取排查:确认接收机供电正常,信号输出电平匹配STM32的3.3V容忍范围,若接收机是5V输出,需增加1k+2k分压电路把信号压到3.3V以内,避免损坏IO或读取失效。如果对读取实时性要求高,建议改用定时器输入捕获或外部中断方式读PWM,替代阻塞的pulseIn。
- MOS管驱动排查:STP36NF06L的Vgs(th)最大阈值为4V,STM32 IO输出的3.3V不足以让MOS管进入线性调节区,甚至无法完全导通,建议更换Vgs(th)≤2.5V的逻辑电平MOS管,或者增加MOS管栅极驱动电路抬升驱动电压。同时检查电路:N沟道MOS管要做低端驱动(源极接GND,漏极接电机负极,电机正极接电源),栅极串联1k限流电阻,电机两端并联肖特基续流二极管,避免感性反向电动势烧MOS。
内容的提问来源于stack exchange,提问作者Magnesium
相关产品推荐
相关产品推荐

