做小车、桌面机械臂的底座,绕不开一个东西:电机驱动。十年前大家手里都是那块红色 L298N 模块,两块叠起来带两个减速电机,跑十分钟散热片烫手,电机端的电压还要掉一截。后来 TB6612FNG 慢慢把这块市场吃了,一块小指甲盖大的板子顶两路 H 桥,1.2A 连续电流,待机电流低到可以电池常供。

这篇把 TB6612FNG 讲透:引脚怎么认、VM 和 VCC 为什么要分开、真值表怎么读、PWM 调到哪里会翻车、STBY 这根线忘了接会发生什么,最后说清楚拿它配编码器做闭环该从哪下手。参数都对着芯片数据手册和 SparkFun、Adafruit 两家的驱动板规格页核过,不同板子的取值有差别的地方我会点出来。
一、先看参数:这颗芯片到底能带多大的电机
TB6612FNG 是东芝的双路直流电机驱动 IC,内部两个完整 H 桥,输出级用的是 LD MOS,导通电阻标称 0.5Ω(上下管合计,VM 不低于 5V 时的典型值)。这个 0.5Ω 是它跟 L298N 拉开差距的地方——L298N 是双极型晶体管,压降论伏算,TB6612 论几百毫伏算,同样的电池电压下电机能多拿到一截。
| 项目 | 标称值 | 实际怎么理解 |
|---|---|---|
| 电机电源 VM | 绝对最大 15V | 芯片手册的上限,日常别顶着用 |
| 逻辑电源 VCC | 2.7V 至 5.5V | 3.3V 单片机和 5V Arduino 都能直连 |
| 连续输出电流 | 每通道 1.2A | 两路同时满载就是 2.4A,得看电池扛不扛 |
| 峰值电流 | 3.2A 短脉冲 | 只够堵转那一瞬间,不能当额定 |
| PWM 频率上限 | 100kHz | 远高于普通单片机能给的频率 |
| 内置保护 | 过热关断、低压检测 | 烧之前会先自己断,别指望它救命 |
这里有个坑要说清楚。芯片手册写 VM 绝对最大 15V,但 SparkFun 那块板子的规格页把电机电压写成 2.2V 到 13.5V,Adafruit 那块直接写 4.5V 到 13.5V、并且明说 3V 电机带不动。三个数字不矛盾,只是口径不同:15V 是芯片不炸的极限,板子上还有滤波电容和走线,厂商给的才是能长期跑的范围。照板子厂商写的来,别拿 15V 当日常电压。
Adafruit 那块还有两处跟裸芯片不一样:电机电源入口串了一颗极性保护 MOS,STBY 引脚板上自带下拉的同时又加了一颗上拉电阻。前者接反了不会炸,后者省掉你手动拉高那一根线。SparkFun 的板子没这待遇,STBY 只有芯片内部的 200kΩ 下拉,不主动拉高就一直窝在待机里,电机一声不响——新手十有八九栽在这。
二、接线:VM、VCC 和那根最容易被忘的 STBY
SparkFun 这块板把 24 脚全引到两侧 0.1 英寸排针上,输入全在一边、输出全在另一边,插面包板不容易接错。板子背面丝印把每根线的名字都印上了,照着看就行。

| 引脚 | 接什么 | 说明 |
|---|---|---|
| VM | 电池正极 | 电机电源,跟逻辑电源分开走 |
| VCC | 单片机 3.3V 或 5V | 逻辑电源,只喂芯片内部逻辑 |
| GND | 公共地 | 板子所有 GND 内部是通的,接一根也行,接两根更稳 |
| STBY | 接 VCC 或单片机 IO | 高电平才工作,低电平或悬空直接待机 |
| AIN1 / AIN2 | 两个普通 IO | A 路方向,靠这两根的组合定正反转 |
| PWMA | 带 PWM 的 IO | A 路调速,占空比决定平均电压 |
| AO1 / AO2 | 电机 A 的两根线 | 接反了只是转向反过来,不会烧 |
B 路完全对称:BIN1、BIN2 定方向,PWMB 调速,BO1、BO2 出电机。接线顺序建议先接电源和地,再接电机,最后接信号线。先接信号线的后果是上电瞬间 IO 状态不确定,电机可能抽一下。

上图是 SparkFun 教程里的标准接法:电池盒进 VM 和 GND,Arduino Pro Mini 的 5V 和 GND 进 VCC 和 GND,四根信号线从单片机拉到 AIN1、AIN2、PWMA、STBY,两个电机的线分别进 AO1/AO2 和 BO1/BO2。注意电池地和单片机地必须连在一起,两套电源共地是这类驱动最基本的规矩。SparkFun 规格页也写了,板子两路电源各带了滤波电容,所以电源线不用另加电容,但线别拉太长。
换一块板子,逻辑一模一样。Adafruit 那块把引脚重新排过,接法只是位置换了:

这张图里带的是步进电机,不是直流电机。一颗 TB6612FNG 的两个 H 桥能拼成一个完整的双极步进驱动,四根线正好接 AO1、AO2、BO1、BO2。Adafruit 的产品页也写了这块板能带一台双极或单极步进、或者两到四个电磁铁(同时只能动两个,还得在对角的两座上)。想省一颗驱动器的时候这条路是通的。
三、真值表:正转、反转、短路刹车和停止
TB6612FNG 只有两根方向线加一根 PWM,四种状态全靠组合出来。SparkFun 教程里的表长这样,我按 A 路整理,B 路同理,前提是 STBY 为高:
| IN1 | IN2 | PWM | OUT1 | OUT2 | 状态 |
|---|---|---|---|---|---|
| H | L | H | H | L | 正转 |
| L | H | H | L | H | 反转 |
| H | H | H 或 L | L | L | 短路刹车 |
| H | L | L | L | L | 短路刹车 |
| L | L | H | 断开 | 断开 | 停止,自由滑行 |
多数人第一次看这张表会卡在第四行:方向给的是正转,为什么 PWM 拉低就变成刹车了?因为 TB6612FNG 的 PWM 不是切断输出,而是在"通电"和"两个输出短在一起"之间切。占空比 50% 就是一半时间在推、一半时间在短路制动,平均下来转速降一半。这跟很多老驱动"PWM 低就断电滑行"是两套逻辑。
实际影响有两个。一是低速时电机会有一种一顿一顿的顿挫感,尤其是减速比大的齿轮箱,占空比低于某个门槛根本转不起来,只在那里嗡嗡响;二是想让车"松油门滑行"必须把 IN1、IN2 都拉低,光把 PWM 归零是刹停,不是滑行。做惯性滑行的小车,这一点不注意就会觉得车尾特别"黏"。
短路刹车本身不是缺点。机械臂关节要停在某个角度不动,靠刹车比靠位置环硬顶省电得多;小车急停也是同理。真正要留意的是别在电机还在高速转的时候直接从正转切反转,电流会瞬间冲到峰值,3.2A 那条线就是这么被踩爆的。想换向先刹停,停稳了再给反向。
四、PWM 调速与待机:频率和占空比的门道
芯片标称 PWM 频率能到 100kHz,普通单片机根本给不到这个数,Arduino 的 analogWrite 默认频率离上限差着两个数量级,所以绝大多数 DIY 场景里你不需要担心频率超限,反而要担心频率太低:几百赫兹的 PWM 落在人耳可听范围,电机低速时会发出尖锐的啸叫,长时间听着难受。想安静,把定时器预分频调高,把 PWM 推到 20kHz 以上,超出听觉范围,代价是低占空比的分辨率变粗。
占空比和转速不是线性关系。电机有静摩擦和齿隙,占空比从 0 慢慢往上加,前一段电机完全不动,只是发热和响;过了启动门槛才开始转。所以做速度控制别直接拿目标速度当占空比,得留一个启动补偿,或者干脆走闭环。这也是为什么同一个 TB6612FNG,有人做出的小车起步平顺,有人做出来一耸一耸。
待机是这块芯片被低估的功能。STBY 拉低,两个 H 桥全关,输出高阻,芯片进入省电状态,静态电流比工作状态低一个量级。做电池供电的桌面小车,停在架子上几小时不掉电,靠的就是这一步。但要注意 STBY 只有芯片内部 200kΩ 的下拉,单片机复位或者 IO 悬空的时候它自己会掉到低电平,车就"死"在那里——所以 STBY 要么硬接 VCC,要么在代码里第一件事就拉高,别放在初始化末尾。
还有个小电流场景值得提:带小功率电机(比如 130 减速电机)的时候,1.2A 的余量很大,芯片几乎不发热,这时候 PWM 频率可以随便调高,不用担心开关损耗。反而是带 520 电机、堵转电流接近 1A 的场合,要在电机两端并一颗小电容压火花,不然换向瞬间的尖峰容易触发低压检测。
五、想上闭环,编码器该往哪儿接
TB6612FNG 只负责"执行",它不知道电机转了多少。要做位置或速度闭环,编码器是另一套东西,接法跟驱动器没关系,直接进单片机。
增量式编码器一般四根线:VCC、GND、A 相、B 相。A、B 两相相差 90 度,单片机用两个外部中断分别接 A、B,靠哪一相先跳变判断转向,靠跳变次数算位移。只接一相也能测速,但分不出正反转,做闭环基本没用。有些编码器还有 Z 相,每圈给一个零位脉冲,做绝对定位的时候用来消除累积误差。
闭环的骨架其实很简单:定时器每隔固定时间读一次编码器计数,换算成实际转速,跟目标转速相减得到误差,PID 算出一个占空比,再写进 PWM 寄存器。TB6612FNG 在里面的角色就是把占空比变成电压,仅此而已。所以选型的时候别指望换一颗更贵的驱动芯片就能把控制精度提上去,环调不好,换什么驱动都是一样抖。
真正容易翻车的是这几处。第一,PWM 和编码器读数抢同一个定时器,或者中断优先级排错,读数会跳。第二,PID 的输出限幅要跟 1.2A 的电流能力对上,积分项一路累加,输出早就超过满占空比,表现出来就是超调之后长时间回调不过来。第三,减速箱的齿隙会让编码器在换向时出现一段"空转",这段区间里 PID 会误以为电机没动,疯狂加输出。工程上的做法是给死区补偿,或者在换向瞬间冻结积分。
至于 PID 参数,没有万能值。同一个环,空载和带负载能差好几倍,机械臂那种变负载的场合更麻烦。我的习惯是先只上 P,加到刚好开始等幅振荡,再退回来一点,然后加一点点 I 消稳态误差,D 项在电机这种有明显惯性的负载上经常帮倒忙,能不加以免。调参的时候把目标速度、实际速度、占空比三个量一起打到串口上看曲线,比盯着车看有用得多。
最后说句实在话。TB6612FNG 不是性能最好的驱动,1.2A 的连续电流在现在的桌面机械臂面前有点紧,大扭矩关节该上的是带电流环的专用驱动。但它的定位很清晰:便宜、够小、逻辑电平宽、待机省电,做两路小电机的入门项目、做教学套件、做电池供电的桌面小车,它是那个"不用想太多就能用"的选择。真要带大电流,再往上换型号,别在这颗芯片上硬榨。


真值表第四行我看了三遍才反应过来。以前一直以为PWM给0就是松油门,结果车尾特别黏,还以为是齿轮箱的锅。后来才想明白它是在通电和短路制动之间切,占空比越低刹得越勤。做那种靠惯性溜一段的小车,确实得把IN1 IN2都拉低才行,光归零PWM等于一直在点刹。
STBY悬空电机纹丝不动那个坑我踩过,查了一晚上以为是焊接,最后发现杜邦线没插到底 ?
0.5Ω导通电阻这条是真差距。之前用L298N带12V减速电机,实测电机端只剩9V多,剩下全喂散热片了。换TB6612之后同样电池明显有劲,虽然1.2A的余量确实不宽裕。
拿一颗带四线步进那段挺实用,省一颗驱动器
闭环部分说的齿隙我深有体会。减速箱换向那一下编码器读数几乎不涨,PID以为没动就猛加输出,结果一冲一冲的。后来在换向瞬间冻结积分才好点,不过调起来还是烦。