教程 · 入门 · 30 分钟
A4988 接线与 Vref:设定步进电机限流
把 A4988 接到 Arduino 和 NEMA 17 上,再用万用表设定限流值。本文给出 Vref 公式、采样电阻的陷阱,以及跳过这一步的代价。
这个驱动器到底在做什么
A4988 不是一个开关,它是一个顺便在开关的稳流器。
这个区别很要紧,因为步进电机绕组是一个低电阻电感,典型值 2 到 4 欧。把一个 2.8 Ω 的绕组直接接到 24 V 上,欧姆定律给出的电流是 8.6 A,几秒就能把电机烧掉。驱动器要做的是每秒把电源斩波几千次通断,让平均电流稳定在你选定的数值上,再把这个电流按让磁场旋转的规律在两个线圈之间来回切换。
所以需要告诉驱动器的只有一个数字:每相多少电流。这就是限流,也是板上唯一一处需要调节的地方。其余的——微步、方向、使能——都是设一次就固定的引脚。
怎么接线
| A4988 引脚 | 接到 | 说明 |
|---|---|---|
| VMOT | 8–35 V 电机电源 | 不要接 Arduino 的 5 V。永远不要。 |
| GND(VMOT 旁) | 电机电源地 | 大电流回流路径 |
| VDD | Arduino 5 V | 逻辑电源,几毫安 |
| GND(VDD 旁) | Arduino GND | 必须与电机电源共地 |
| 1A、1B | 一相电机线圈 | 哪端接哪端都行——只会影响方向 |
| 2A、2B | 另一相电机线圈 | 配对接错是致命错误 |
| STEP | 任意 Arduino 输出 | 一个脉冲一个微步 |
| DIR | 任意 Arduino 输出 | 高低电平决定方向 |
| ENABLE | GND 或某个 Arduino 引脚 | 低电平有效:拉低才通电 |
| RESET、SLEEP | 互相短接 | 两者都必须为高; 用跳线短接即可 |
| MS1、MS2、MS3 | 见下表 | 悬空即整步 |
两条接线规则承担了几乎全部风险:
- **在 VMOT 与 GND 之间、贴近板子处并一只 100 µF 电解电容。**这不是可选项。数据手册和每一家载板的文档都这么说,原因是斩波器以尖锐的脉冲取电;附近附近没有大电容时,电源线的电感会把这些脉冲变成电压尖峰,超过芯片 35 V 的额定值。板子往往是在上电瞬间死掉而不是运行中死掉,通常就是这个原因。
- **驱动器带电时绝不要拔电机线。**中断一个通电的绕组会产生一个无处可去的大感性反冲。每次都先断电。
如果电机的四根线没有标签,用万用表找出配对:同一相绕组内部会量到几欧,两相之间则是开路。按通断配好对,一对接 1A/1B,另一对接 2A/2B。
设置限流
板上有一个电位器,转动它会改变一个参考电压,芯片拿这个电压和采样电阻两端的电压作比较。这个参考电压就是 Vref,在电位器滑动端与地之间测量。
A4988 的公式是:
Vref = I_phase × R_sense × 8
这里有个坑,坑里埋着不少烧掉的电机:**R_sense 在不同板子上并不一样。**载板出厂时可能装 0.1 Ω,也可能装 0.05 Ω 的采样电阻,公式算出来的答案会差整整两倍:
| 采样电阻 | 板上丝印 | 1.0 A 对应 Vref | 1.2 A 对应 Vref | 1.5 A 对应 Vref |
|---|---|---|---|---|
| 0.1 Ω | R100 |
0.80 V | 0.96 V | 1.20 V |
| 0.05 Ω | R050 |
0.40 V | 0.48 V | 0.60 V |
| 0.068 Ω | R068 |
0.54 V | 0.65 V | 0.82 V |
动手算之前,先读板子底部附近那两颗黑色贴片电阻上的丝印。在装 0.05 Ω 电阻的板子上把 Vref 设成 1.2 V,等于向一台 1.7 A 的电机索要 3 A。
步骤如下:
- 给板子供电——VMOT 接上,电机断开。芯片需要电机电压才能稳流,但你不需要电机转起来。
- 查电机的额定相电流。常见的 NEMA 17 是 1.5 A 或 1.7 A。
- 取其中 70–85% 作为目标。额定电流假定的是数据手册里的散热条件,而你未必有;最后那 20% 电流买到的转矩很少,产生的热量却很多。
- 按公式和你实际装的采样电阻算出 Vref。
- 黑表笔接地脚,红表笔放在电位器的金属螺丝上。慢慢转——四分之一圈就是很大的变化——直到表上读到你算出的数值。
值得用一把小陶瓷螺丝刀。金属螺丝刀在板子带电时把电位器搭到别处,是烧掉驱动器的常见方式。
值得明说的是:限流值就是支配步进电机一切行为的转矩方程里的 T_peak。设低了,同样负载下电机落后更多,更早丢步;设高了,电机就为未必需要的转矩而发热。这个数字值得你认真对待。
微步引脚
MS1、MS2、MS3 内部有下拉,所以任何悬空的脚都会被读成低电平:
| MS1 | MS2 | MS3 | 分辨率 | 每转步数 |
|---|---|---|---|---|
| low | low | low | 整步 | 200 |
| high | low | low | 半步 | 400 |
| low | high | low | 1/4 步 | 800 |
| high | high | low | 1/8 步 | 1600 |
| high | high | high | 1/16 步 | 3200 |
大多数作品把三个都短接为高,然后就不再动了。理由不是精度——负载下微步并不买来精度——而是 1/16 步能消除电机每步之间的振铃,机器因此安静下来,纹波也不会再出现在加工件表面。代价是你的单片机每毫米要发出十六倍多的脉冲,在 Arduino Uno 上每秒约 10 000 步以上就是一个实打实的约束。
驱动起来
最小可用的程序。注意这里不需要任何库:一步就是一个脉冲,真的仅此而已。
const int STEP_PIN = 3;
const int DIR_PIN = 4;
const int EN_PIN = 5; // active LOW
void setup() {
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(EN_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW); // energise the coils
digitalWrite(DIR_PIN, HIGH);
}
void loop() {
// One revolution at 1/16 stepping = 3200 pulses.
for (int i = 0; i < 3200; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(2); // datasheet minimum is 1 us
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(300); // this delay IS the speed
}
delay(1000);
}
这段代码能跑,而且它也正是你不该交付的东西,原因有两个。
第一,步频从零直接跳到全速。要的频率超过电机起动频率上限时,它只会原地嗡嗡响——步进模拟器的默认设置下,从静止直接给全速,一次 60 mm 的移动会丢掉 280 个整步,轴停在 4 mm 处。同样的移动加上斜坡就精确落在目标上。这就是加速度曲线带来的差别,它不是锦上添花。
第二,delayMicroseconds 是阻塞的。循环在步进的时候,单片机上其他什么都不跑——没有限位检查,没有串口,没有第二根轴。要做真东西,就用非阻塞时序写法,或者交给 AccelStepper,它替你实现斜坡和调度:
#include <AccelStepper.h>
AccelStepper axis(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
pinMode(EN_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW);
axis.setMaxSpeed(8000); // steps/s -> 100 mm/s at 80 steps/mm
axis.setAcceleration(16000); // steps/s2 -> 200 mm/s2
axis.moveTo(80 * 50); // 50 mm
}
void loop() {
axis.run(); // returns immediately; call it constantly
}
setMaxSpeed 和 setAcceleration 给你的是梯形曲线,仅此而已——没有 S 曲线选项。如果你要 限制跃度的曲线,就得自己生成设定点。
A4988 还是它的替代品?
| 驱动器 | 电流 | 微步 | 噪声 | 什么时候选它 |
|---|---|---|---|---|
| A4988 | 裸装 1 A,散热后约 1.5 A | 到 1/16 | 有声 | 便宜、到处都买得到、文档齐全 |
| DRV8825 | 裸装 1.5 A,散热后约 2.2 A | 到 1/32 | 有声 | 需要更大电流或更细分 |
| TMC2208 | 约 1.2 A | 到 1/256 | 近乎静音 | 噪声要紧;打印机转向它就是为了这个 |
| TMC2209 | 约 1.7 A | 到 1/256 | 近乎静音 | 同上,外加无感回零 |
| ULN2003 + 28BYJ-48 | 约 0.3 A | 半步 | 嗡嗡响 | 玩具级演示,不是机器 |
DRV8825 引脚兼容,但它的 Vref 公式不一样——Vref = I × 0.5——而且电位器旋向相反。换上去却不重读公式,是烧掉电机的经典做法。
TMC 系列的价钱,在机器放到你听得到它响的地方之后就值了。它们做的是同一件事,只是电流波形更平滑——这就是为什么装了它们的打印机发出的是风扇声而不是电机声。
出问题时
| 现象 | 原因 | 解决 |
|---|---|---|
| 电机振动但不转 | 线圈配对接错 | 用通断挡找出配对,重新接线 |
| 完全没反应 | ENABLE 悬空或为高,或 RESET/SLEEP 为低 | 把 ENABLE 拉低;RESET 与 SLEEP 短接 |
| 驱动器烫到不敢碰,然后停机 | 限流设得太高 | 重测 Vref;加散热片和风扇 |
| 电机烫但驱动器正常 | 正常 | 壳温 60–80 °C 属预期 |
| 只有快速移动时丢步 | 该速度下电源电压太低 | 提高 VMOT——加电流没用 |
| 只有急加速时丢步 | 斜坡太陡,或电流太小 | 降加速度,或把 Vref 往额定值提 |
| 一上电板子就死 | VMOT 上缺大电容 | 贴近引脚并一只 100 µF 电解 |
| 能保持位置但转动发涩 | 整步模式 | 把 MS1–MS3 短接为高,用 1/16 |
| 某一“对”之间量到开路 | 这两根线来自不同的相 | 重新配对 |
下一步
驱动配好之后,剩下的问题是每毫米行程该值多少个脉冲——这完全取决于轴在带动什么。那就是每毫米步数,机器上其他每个部分都是照着这个数标定的。
探索关联图谱
本教程所属的搭建
包含本教程的项目和学习路线。
延伸阅读