经典三问
Q: 舵机收到的是什么?
A: 一段 PWM 里高电平脉宽代表的目标角度。舵机内部自己完成"读位置、算误差、转到位"的全过程,外界只给它目标值。
Q: 舵机和普通直流电机差在哪?
A: 直流电机收到的是电压,电压就是驱动力;舵机内部有电机、减速、电位器和一块控制板,外界给的是"目标",不是"力气"。
Q: 为什么要先认识电机家族?
A: 写程序前先分清楚:这一台是"给目标"还是"给力气"。把舵机的代码直接搬到直流电机上,转起来的现象会完全不同。
舵机里面不只是一个电机
把 SG90 的壳打开看,里面有四样东西:一只小直流电机、一组减速齿轮、一个电位器、一块小控制板。
电位器装在输出轴上。轴转到哪儿,电位器就把位置翻译成一个电压。控制板干的事很固定:读电位器,和你给的目标角度比一比,算出差多少,然后驱动小电机正转或反转,直到误差归零。
舵机当然也有电机,但光说"能转的电机"就把它说窄了。它其实是一套自己会调节的小闭环 。你写 Servo_SetAngle(0),并不是在给它通电让它往 0 度转------是在告诉它"0 度到了没",剩下的事它自己做。
你给的是目标,不是力气
普通直流电机不一样。
把电压加到直流电机两端,电流穿过线圈,轴就转。你给的占空比、方向脚,直接决定了它拿多少力气、往哪个方向使劲。给多少,就是多少------没有人在中间帮它看"到了没有"。
text
直流电机:给电压/占空比 = 给力气,力气决定转速和方向
舵机: 给脉宽 = 给目标,目标决定停在哪
这也是为什么舵机堵转时会一直嗡嗡响:它认为还没到目标,就持续发力,直到卡住的机构自己让步,或者烧掉。这时候加大 PWM 救不了它------你给的是目标,不是力气,目标没变,它只会更用力地撞墙。
同一句"PWM 控制",落到两种器件上是两种语义:一个在听每个脉冲有多长 ,一个在感受一段时间里拿到多少能量。代码不能互换,原因在这里。
电机家族:先认四个成员
直流有刷电机:最老实的成员。线圈通电就转,换向靠里面的电刷和换向片机械完成。你给它电压,它就出力,关系最直接。小车现在用的就是这种,只是外面多了一层减速齿轮。缺点也写在结构里:电刷会磨损,高速时会有火花和噪声。
直流无刷电机:把"换向"从机械电刷搬到了外面的控制器。控制器要知道转子转到哪了,才能按时换通电方向------它靠霍尔传感器或反电动势猜位置。所以无刷电机很少单独出现,常以"电机+控制器"的形式卖。没有电刷,寿命和效率都好看,代价是控制器变复杂。无刷也不是云台的专属------机器人、航模、电动车里它越来越多,寿命和效率是它推开有刷的原因,代价是每台都要陪一个控制器。
步进电机:把一整圈分成固定步数,每收到一个脉冲就精确走一步。它听的是"步数",不靠反馈也能停在开环位置------前提是别丢步。走得快、负载重的时候,它容易跟不上脉冲,这就是"丢步"。步进在工业里很常见:3D 打印机、数控、送料,凡是"按步数走"的位置活都有它,云台只是主线里用到它的地方。
舵机(位置伺服的一种):前面拆过的那套:电机+减速+电位器+控制板。"伺服"是个泛称,指带反馈、能自己把输出调到目标上的执行器。工业上的伺服电机是更精密的版本:电机+编码器+驱动器,力气大、精度高、价格也高。SG90 是这条线里最便宜的一号------塑料齿、小力矩,但闭环的逻辑一模一样。
| 成员 | 你给它 | 它回报 | 常在哪儿 |
|---|---|---|---|
| 直流有刷 | 电压/占空比(力气) | 转速,开环 | 小车车轮、玩具 |
| 直流无刷 | 换相时序(由控制器转交) | 大扭矩、高转速、长寿命 | 机器人、航模、电动车 |
| 步进 | 一个个脉冲(步数) | 精确的角度步进 | 3D 打印机、数控、工业定位 |
| 舵机 | 脉宽(目标角度) | 自己转到位并停住 | 转向、云台、机械臂关节 |
先动手把 SG90 转起来
SG90 三根线:5V 接电源线,GND 接地,信号线接 PA3。降压模块的 GND 和 STM32 的 GND 接在一起。舵机电源不要从 STM32 的 3.3V 挤出来:STM32 只发命令,5V 负责出力。颜色只能当提示,以你手里那只的说明书为准。
TIM2_CH4(PA3)做 50 Hz 周期:PSC = 72-1 让计数步进 1 us,ARR = 20000-1 凑成 20 ms,比较值写在 CCR4:
text
PSC = 72 - 1 72 MHz / 72 = 1 MHz,1 个计数约 1 us
ARR = 20000 - 1 数满 20000 个计数,周期约 20 ms
CCR4 = 1166 高电平约 1.166 ms(-60°)
CCR4 = 1500 高电平约 1.5 ms(0°)
CCR4 = 1833 高电平约 1.833 ms(+60°)
三档取值是算出来的,不是随手取的:pulse = 1000 + (角度 + 90) × 1000 / 180------1000~2000 us 对应 -90° ~ +90°,所以 -60°/0°/+60° 落在 1166 / 1500 / 1833 us 上。
程序让输出轴按 -60° → 0° → +60° 每个位置停 1.5 秒,用 TIM1 的更新中断换位置(中断函数名要写成启动文件里的向量名 TIM1_UP_IRQHandler,写错不报错、只是永远不进),不在 while (1) 里睡延时。
把舵盘装好,它会向一边停住、回到中间、再向另一边停住。1500 us 在这里不是"绝对中位":连杆孔位、舵盘齿位、车轮安装角都会移动真正的直行位置。要精确找中位,拆下舵盘,固定输出 1500 us,再把舵盘插到最接近机械中位的齿位;还偏,就在应用层存一个校准值,例如 center_offset_us = -35,别把机械误差藏进定时器初始化。
脉宽边界控制在 1000~2000 us,输入越界代码会截断。网上常见的 500~2500 us 不是所有 SG90 都能承受,连杆装上后更不能拿它当盲扫范围。可以把 ARR 临时改成 2000-1 做一次"周期改坏"实验:舵机不动、抖动或发出细响,改回 20000-1 恢复------重点是学会先按公式算周期,再判断现象。
现场故障:它们都在说同一件事
程序明明在发命令,舵机却一动不动。
先证明"命令确实在发":把当前角度和脉宽打到 OLED 上,数字在跳,说明信号线在工作------这一步不需要示波器。命令在走、舵机却不动,就只剩供电和共地两个嫌疑人:降压模块输出有没有掉、共地线有没有断。恢复稳定 5V 和共地,问题消失。
只在一边嗡嗡响。 连杆被拧到机械尽头,舵机仍认为没到目标,持续发力。马上断电,松开连杆,重新找中位。正确指令救不了卡死的机构,堵转发热很快。
方向反了。 把 Servo_SetAngle() 的两端映射交换,或把舵盘换一个齿位。方向由"脉宽映射+机械安装"共同决定,别急着改驱动代码。
抖,STM32 还复位。 让舵机快速来回扫,5V 端并万用表看电压。负载一大,电源就下陷。先减小负载、缩短线、确认降压模块额定电流,再谈软件参数。
同一个壳,可能装着另一套耳朵
普通 SG90 的脉宽是"目标位置"。还有一种连续旋转舵机,外形几乎一样,脉宽却变成"方向和速度":中间附近停,往两边偏就转,偏得越多越快。把普通舵机代码直接搬过去,现象完全不同。买到模块先看型号说明,别只看外壳颜色。
最后橘猫说
直流电机是执行器,给力气就转,转速靠猜------它不知道自己转多快,也不知道轮子走了多远。想要它变成"知道自己做到没有"的执行器,需要一双眼睛把转动报回来,那是编码器的事。到那时,直流电机也会站进"带反馈"的那一排。
舵机先认识到这里:它听的从来不是"PWM 信号"本身,而是脉宽写进去的那个目标角度;目标以内,力气是它自己的。写程序前先问一句------这台电机,我是该给它力气,还是给它目标?