基于TC78B043FNG与STM32F303VE的三相BLDC电机控制方案设计与实现
1. 项目缘起与整体方案拆解1.1 为什么选这两个芯片搭伙干活工业现场和机器人关节驱动里三相无刷直流电机BLDC几乎是默认选项。它效率高、扭矩密度大、寿命长但前提是驱动方案得靠谱。我手头这个项目要做的是一套中等功率的三相 BLDC 控制平台目标场景是协作机器人关节、AGV 驱动轮以及一些小型工业自动化设备。选型阶段对比过不少组合最终落在TC78B043FNG加STM32F303VE上原因很实在。TC78B043FNG 是东芝的一款三相无刷电机预驱芯片内置了栅极驱动、电流检测放大器和一套相当完整的保护逻辑。它本身不跑算法只负责把 MCU 给出的六路 PWM 信号放大成能驱动外部功率 MOSFET 的栅极信号同时把母线电流、反电动势过零这些模拟信息整理好交给 MCU。换句话说它把“脏活累活”揽了MCU 只需要专注在控制算法上。STM32F303VE 则是 ST 家带浮点运算单元的 Cortex-M4 芯片主频 72MHz片上资源对电机控制来说非常宽裕4 个独立 ADC、多个高级定时器TIM1、TIM8 都带互补输出和死区插入、运算放大器、比较器一应俱全。最关键的是它支持硬件浮点跑 FOC磁场定向控制或者六步换相时数学运算不会成为瓶颈。这两个搭在一起分工非常清晰STM32F303VE 负责“想”TC78B043FNG 负责“干”。我实测下来这套组合在 24V 母线、额定 10A 相电流的场景下跑 FOC 可以做到电流环 20kHz 稳定运行六步换相更是轻松。对于刚接触 BLDC 控制的工程师来说这套方案的学习曲线也比较友好因为预驱芯片把很多容易出错的功率级保护做掉了。1.2 整体控制架构长什么样整个系统的信号流是这样的STM32F303VE 通过高级定时器 TIM1 产生三对互补 PWM经过死区插入后送给 TC78B043FNG 的输入引脚。TC78B043FNG 内部有电平转换和栅极驱动输出直接推外部三相全桥的 MOSFET。电机三相线上的电流通过采样电阻或者芯片内置的电流检测放大器反馈回 STM32 的 ADC。同时三相反电动势经过分压和滤波后接入 STM32 的 ADC 或比较器用于过零检测。控制策略上我做了两套固件一套是六步换相梯形波控制适合对成本敏感、对转矩脉动要求不高的场合另一套是 FOC 正弦波控制适合机器人关节这种要求低噪声、低脉动的场景。两套固件共用同一套硬件通过编译宏切换。这里有个设计取舍值得说TC78B043FNG 支持外部 MOSFET也支持内部集成 MOSFET 的版本具体型号后缀不同。我选的是预驱版本因为工业场景下功率等级变化大外部 MOSFET 可以根据实际需求灵活选型从 30V 到 100V 的管子都能配。如果选集成 MOSFET 的版本功率等级就被锁死了后续产品线扩展会受限。1.3 这套方案解决了哪些实际问题最直接的问题是保护。工业现场电机堵转、短路、过温是家常便饭。TC78B043FNG 内置了过流保护、过温保护、欠压锁定和死区时间控制。死区时间这个事如果让 MCU 软件去算一旦中断延迟或者时钟抖动上下桥臂直通就是炸管。硬件死区虽然不够灵活但胜在可靠。我实测过在 20kHz PWM 下TC78B043FNG 的死区时间典型值在 200ns 左右对于大多数 24V 母线场景足够安全。第二个问题是电流采样精度。FOC 控制的效果很大程度上取决于相电流采样的质量。TC78B043FNG 内置的电流检测放大器增益可调配合 STM32F303VE 的 12 位 ADC实际有效位数约 10.5 位在 10A 量程下分辨率可以做到 10mA 左右。这个精度对于机器人关节的力矩控制已经够用了。第三个问题是开发效率。STM32 的生态不用多说CubeMX 配置定时器和 ADC 非常方便HAL 库虽然有人吐槽效率低但对于快速原型验证来说省时间。TC78B043FNG 的引脚定义清晰数据手册里给了完整的真值表和时序图照着接基本不会错。2. 硬件设计与关键细节解析2.1 功率级电路怎么搭功率级是三相全桥六个 N 沟道 MOSFET。选管子的原则是耐压至少是母线电压的两倍24V 母线选 60V 或 100V 的管子。我用的是一颗 60V/30A 的管子导通电阻 8mΩ栅极电荷 15nC。这个栅极电荷很关键因为 TC78B043FNG 的栅极驱动电流能力有限如果管子栅极电荷太大开关速度会变慢开关损耗增加。计算一下驱动能力TC78B043FNG 的峰值拉电流和灌电流在数据手册里标的是 1A 左右具体看型号后缀。对于 15nC 的栅极电荷理论上开关时间可以做到 15ns但实际因为线路电感我实测上升沿在 50ns 左右。这个速度对于 20kHz PWM 来说完全够用开关损耗可以接受。自举电容是另一个关键点。上桥臂的栅极驱动需要自举电容供电容值一般选 100nF 到 1μF。我选的是 1μF 的 X7R 陶瓷电容耐压 25V。这里有个坑自举电容太小上桥臂在低频或者大占空比下会掉电太大则充电时间变长高频下可能来不及充满。我实测 1μF 在 20kHz 下表现稳定占空比从 5% 到 95% 都没有问题。采样电阻放在下桥臂和地之间三个电阻分别采三相电流。阻值选 5mΩ功率至少 1W。为什么选 5mΩ因为 TC78B043FNG 的电流检测放大器增益是固定的几档我选的是 20 倍增益。5mΩ 乘以 10A 是 50mV放大 20 倍是 1V正好落在 STM32 ADC 的 0-3.3V 量程内而且留了足够余量。如果选 10mΩ10A 时放大后是 2V虽然也能用但大电流时容易饱和。2.2 反电动势过零检测电路六步换相需要知道什么时候换相最常用的方法就是检测未导通相的反电动势过零点。三相反电动势经过分压后接入 STM32 的 ADC 或者比较器。分压比怎么定母线 24V反电动势峰值理论上不会超过母线电压但实际因为 PWM 调制相电压会在 0 到 24V 之间跳变。分压到 3.3V 以内分压比至少是 24/3.3 ≈ 7.3。我选的是 10:1 分压用 9kΩ 和 1kΩ 电阻。这里有个细节分压电阻不能太大否则 ADC 采样保持电容充电时间不够采样值会偏低。STM32F303VE 的 ADC 采样时间可以配置我设的是 181.5 个时钟周期对应 72MHz 下约 2.5μs。配合 10kΩ 级别的源阻抗采样误差在可接受范围内。如果分压电阻选到 100kΩ 级别就必须加电压跟随器了。滤波电容也要加但容值不能太大。我一开始加了 100nF结果过零点检测延迟太大高速时换相滞后严重。后来改成 1nF延迟降到微秒级效果就好多了。这个电容的作用是滤掉 PWM 开关噪声但代价是引入相位延迟。在 20kHz PWM 下1nF 配合 10kΩ 源阻抗截止频率约 16kHz对基波影响很小。2.3 STM32F303VE 的外设配置要点TIM1 配置成中心对齐模式产生三对互补 PWM。中心对齐的好处是 PWM 谐波集中在开关频率附近对电机噪声和 EMI 都更友好。死区时间通过 TIM1 的 BDTR 寄存器配置我设的是 200ns和 TC78B043FNG 的内部死区形成双重保护。ADC 配置成三通道规则组由 TIM1 的更新事件触发。采样时刻选在 PWM 中心点这时候开关噪声最小。ADC 时钟配置成 72MHz 的 1/6即 12MHz采样时间 181.5 周期总转换时间约 2.5μs 12.5 周期 ≈ 3.5μs。三通道轮流转换总时间约 10.5μs在 20kHz50μs 周期下完全来得及。运算放大器用来做电流信号的偏置和放大。TC78B043FNG 输出的电流检测信号是双向的需要加一个 1.65V 的偏置才能被单极性 ADC 正确读取。STM32F303VE 内置的运放可以配置成跟随器或者同相放大器我用的是同相放大增益 2 倍把 TC78B043FNG 输出的 0-1V 信号放大到 0-2V再叠加 1.65V 偏置最终落在 0.65V 到 3.65V 之间。等等3.65V 超过 3.3V 了所以增益得改成 1.5 倍或者偏置改成 1.5V。我最后用的是增益 1.5 倍偏置 1.5V输出范围 0.75V 到 3.0V安全。3. 固件实现与核心算法落地3.1 六步换相固件的实现细节六步换相的逻辑不复杂但细节决定成败。核心是一个换相状态机六个状态对应六种 PWM 输出组合。每个状态持续 60 电角度换相点由反电动势过零点决定。过零检测的方法是在 PWM 关断期间采样未导通相的电压和母线中点电压比较。具体实现上我用 TIM1 的通道 4 做 ADC 触发在 PWM 中心点采样。采样到三相电压后找出未导通相判断它和虚拟中点的大小关系。虚拟中点可以用三相电压的平均值来算也可以用一个独立的电阻网络生成。我用的是软件计算平均值省三个电阻。换相延迟的处理是个经验活。理论上过零点之后再过 30 电角度换相但实际因为滤波延迟和采样延迟需要提前或者延后。我的做法是先按理论值 30 度换相然后用示波器看相电流波形如果电流波形不对称就微调延迟角度。实测在 3000rpm 以下30 度延迟基本不用调超过 5000rpm需要提前 5 到 10 度。启动是个难点。静止时反电动势为零没法检测过零点。我的启动策略是先强制换相按预设的加速曲线从 0 加速到一定转速等反电动势足够大了再切换到自同步模式。强制换相的频率从 10Hz 开始每 100ms 增加 5Hz直到检测到稳定的过零信号。这个参数需要根据电机惯量调整惯量大的电机加速要慢一些否则会失步。3.2 FOC 固件的核心环节FOC 的数学基础是 Clarke 变换和 Park 变换。Clarke 变换把三相电流变成两相静止坐标系下的 Iα 和 IβPark 变换再把它旋转到转子坐标系下的 Id 和 Iq。Id 控制励磁Iq 控制转矩。对于表贴式永磁电机Id 参考值设为零只控制 Iq。电流环是 FOC 的核心。我用的 PI 控制器比例增益和积分增益通过试凑法确定。具体步骤是先把积分增益设为零逐渐增大比例增益直到电流出现轻微振荡然后取这个值的 60% 作为最终比例增益。再逐渐增大积分增益直到电流阶跃响应没有稳态误差同时超调不超过 10%。实测在 20kHz 电流环频率下比例增益约 0.5积分增益约 0.01具体值跟电机参数有关。转子位置获取有两种方式有传感器和无传感器。有传感器用霍尔或者编码器简单可靠。无传感器用滑模观测器或者龙伯格观测器省掉传感器但算法复杂。我这个项目两种都支持机器人关节用编码器AGV 驱动轮用无传感器。无传感器模式下低速时反电动势太小观测器精度不够所以低速用开环高速切换到闭环。切换点设在额定转速的 10% 左右。SVPWM 的实现比 SPWM 复杂一些但母线电压利用率高 15%。具体做法是根据 Iα 和 Iβ 判断扇区计算相邻两个基本矢量的作用时间再分配给三个桥臂。STM32F303VE 的 TIM1 支持互补输出和死区插入SVPWM 的六路信号直接写 CCR 寄存器就行。这里要注意SVPWM 的载波是三角波中心对齐模式下CCR 值在 0 到 ARR 之间变化。3.3 电流采样时机与噪声抑制电流采样最怕开关噪声。MOSFET 开关瞬间di/dt 很大采样电阻上的电压会有尖峰。如果在开关瞬间采样采到的全是噪声。正确的做法是在 PWM 中心点采样这时候三相下桥臂都导通或者都关断取决于调制方式电流波形最干净。我用的调制方式是下桥臂常通、上桥臂 PWM这样在 PWM 中心点时三个下桥臂都导通采样电阻上的电压就是相电流。但这样有个问题上桥臂 PWM 时下桥臂是常通的那上桥臂关断时电流通过下桥臂续流采样电阻上还是有电流信号。所以中心点采样是可行的。采样窗口要足够宽。STM32F303VE 的 ADC 采样时间设 181.5 周期加上转换时间总共约 3.5μs。三个通道轮流采样总时间约 10.5μs。在 20kHz 下PWM 周期 50μs中心点前后各 25μs 都是安全的。但如果 PWM 频率提高到 40kHz周期只有 25μs采样窗口就紧张了。这时候要么减少采样通道比如只采两相第三相用计算得出要么换更快的 ADC。硬件滤波也要加。采样电阻两端并联一个 RC 低通截止频率设在开关频率的 1/10 左右。20kHz 开关频率截止频率设 2kHzR 取 100ΩC 取 0.8μF。这个滤波电容不能太大否则电流环带宽受限。我实测 0.8μF 在 20kHz 下电流环带宽可以做到 2kHz对于大多数应用够了。4. 调试过程与常见问题实录4.1 上电就炸管是什么原因第一次上电我用的是一颗 30V 的管子母线 24V理论上耐压够。结果一上电PWM 还没输出管子就炸了。排查了半天发现是自举电容的问题。TC78B043FNG 的上桥臂驱动需要自举电容但如果初始状态下上桥臂 MOSFET 的栅极被悬空而母线电压通过 MOSFET 的米勒电容耦合到栅极就可能造成上下桥臂直通。解决办法是在上桥臂 MOSFET 的栅极和源极之间加一个下拉电阻10kΩ 就行。这个电阻保证在驱动信号没来之前栅极被拉到源极电位MOSFET 可靠关断。另外TC78B043FNG 的使能引脚要先拉低等电源稳定后再拉高避免上电瞬间的误动作。还有一个坑是死区时间。TC78B043FNG 内部有死区但外部 MOSFET 的开关时间如果比死区还长那死区就形同虚设。我用的管子开关时间约 50nsTC78B043FNG 的死区 200ns理论上够。但实际因为栅极电阻选大了我一开始用了 10Ω开关时间被拉长到 200ns 以上死区就不够了。后来把栅极电阻改成 2.2Ω开关时间降到 80ns问题解决。4.2 电流采样值跳动大怎么排查电流采样值跳动大首先看硬件。示波器直接测采样电阻两端的电压如果波形上全是毛刺那就是开关噪声耦合进来了。解决办法采样电阻的走线要短最好用开尔文连接把功率地和信号地分开。我一开始没注意采样电阻的走线绕了一大圈结果噪声大得没法看。重新画板后走线长度控制在 5mm 以内噪声立刻降下来了。如果硬件没问题那就是采样时机不对。用示波器同时看 PWM 信号和 ADC 触发信号确认采样点是不是在 PWM 中心。STM32F303VE 的 ADC 触发源可以选 TIM1 的更新事件或者比较事件。我一开始选的是更新事件但更新事件发生在计数器溢出时不是中心点。后来改成比较事件把比较值设成 ARR/2采样点就对准中心了。软件滤波也能帮忙。我加了一个简单的滑动平均滤波窗口大小 4。这个滤波对随机噪声有效但对周期性噪声效果一般。如果噪声是周期性的比如和 PWM 同步那滑动平均反而会把噪声放大。这时候要用同步采样让采样时刻和 PWM 严格对齐。4.3 电机启动抖动甚至失步启动抖动通常是换相时机不对。六步换相下如果换相太早电流波形会畸变转矩脉动大换相太晚电机可能失步。我的调试方法是先用示波器看霍尔信号如果有和相电流波形调整换相延迟角度直到相电流波形接近方波。如果没有霍尔就看反电动势过零点和换相点的关系理论上换相点应该在过零点之后 30 度。FOC 下启动抖动可能是电流环参数不对。比例增益太大电流会振荡太小响应慢。我一般先用一个很小的比例增益让电机能转起来然后逐渐增大直到电流波形出现轻微振荡再回调到 60%。积分增益也是类似先小后大直到稳态误差消失。还有一个常见原因是转子初始位置检测不准。FOC 需要知道转子位置才能正确施加电压矢量。如果初始位置错了启动时转矩方向可能反了电机就会抖动。我的做法是启动前先施加一个固定的电压矢量让转子对齐到已知位置然后再开始闭环控制。这个对齐时间一般 100ms 到 500ms取决于电机惯量。4.4 常见问题速查表现象可能原因排查方法解决措施上电炸管上下桥臂直通测栅极波形看是否有交叠加栅极下拉电阻减小栅极电阻检查死区电流采样跳动开关噪声耦合示波器看采样电阻波形缩短走线开尔文连接调整采样时机电机启动抖动换相时机不对看相电流波形调整换相延迟检查转子初始位置高速失步换相滞后看反电动势和换相点关系提前换相角度减小滤波电容电流环振荡PI 参数不当看电流阶跃响应减小比例增益调整积分增益过流保护误触发采样电阻太大测采样电阻电压减小采样电阻调整放大器增益上桥臂驱动不足自举电容太小测上桥臂栅极电压增大自举电容降低 PWM 频率ADC 采样值偏低源阻抗太大测 ADC 输入电压减小分压电阻增加采样时间5. 实操心得与进阶建议5.1 从零搭建的推荐步骤如果你也想复现这套方案我建议按这个顺序来先画一块最小系统板只焊 STM32F303VE 和 TC78B043FNG不接功率级。用示波器确认六路 PWM 输出正常死区时间正确。然后接上功率级但母线电压先给 5V用限流电源确认没有短路。再给 12V空载跑六步换相看相电压波形。最后给 24V带载跑 FOC。每一步都要用示波器确认波形。我见过太多人跳过验证步骤直接上 24V 带载结果一炸就是一片。限流电源是必须的我用的是一台 30V/5A 的可调电源限流设在 1A。这样即使有短路也不会炸管电源会自动限流。固件开发上先用 CubeMX 生成初始化代码把 TIM1、ADC、运放、比较器都配好。然后写一个最简单的六步换相让电机能转起来。再逐步加入过零检测、速度闭环、电流闭环。FOC 最后做因为 FOC 依赖的环节最多前面都调通了FOC 就是水到渠成的事。5.2 参数整定的经验值电流环 PI 参数和电机电感、电阻有关。理论计算太复杂我一般用试凑法。先设比例增益为 0.1积分增益为 0给一个电流阶跃看响应。如果响应太慢增大比例增益如果振荡减小。找到临界振荡点后取 60% 作为最终值。积分增益从 0.001 开始逐渐增大直到稳态误差消失。速度环 PI 参数和转动惯量有关。我一般先设比例增益为 0.01积分增益为 0给一个速度阶跃看响应。速度环的带宽一般设成电流环的 1/5 到 1/10。比如电流环 2kHz速度环就设 200Hz 到 400Hz。这样内外环不会互相干扰。过零检测的滤波电容我试过 100nF、10nF、1nF。100nF 延迟太大高速时换相严重滞后1nF 噪声有点大但配合软件滤波能用。最后我选了 2.2nF兼顾噪声和延迟。这个值跟电机电感有关电感大的电机反电动势变化慢可以用大一点的电容。5.3 这套方案的扩展方向这套硬件平台还可以扩展。比如加一个 CAN 接口用 STM32F303VE 的 CAN 外设就能接入工业现场总线。或者加一个编码器接口用 TIM2 或 TIM3 的编码器模式做全闭环位置控制。TC78B043FNG 还支持刹车功能可以通过引脚控制实现快速制动。软件上可以加入参数自整定功能。电机参数电感、电阻、反电动势常数可以通过注入高频信号测量出来然后自动计算 PI 参数。这个功能对于批量生产很有用因为每台电机的参数都有差异手动整定太费时间。如果要做功能安全STM32F303VE 有硬件看门狗和时钟安全系统TC78B043FNG 有故障输出引脚。可以把故障输出接到 STM32 的刹车输入一旦预驱报故障MCU 立刻封锁 PWM电机自由停车。这个响应时间在微秒级比软件轮询快得多。5.4 几个容易忽略的细节第一个是电源去耦。TC78B043FNG 的电源引脚旁边一定要放 100nF 和 10μF 的电容越近越好。我一开始只放了 100nF结果 PWM 输出有振铃后来加了 10μF 才好。STM32F303VE 的每个电源引脚也要放 100nFVDDA 还要加一个 1μF 的钽电容。第二个是散热。TC78B043FNG 本身功耗不大但外部 MOSFET 的开关损耗和导通损耗会发热。10A 相电流下8mΩ 的导通电阻每个管子导通损耗约 0.8W六个管子就是 4.8W。加上开关损耗总功耗可能到 6W 以上。所以 MOSFET 要加散热片或者选导通电阻更小的管子。第三个是 PCB 布局。功率地和信号地要分开最后单点接地。采样电阻的地要接到功率地ADC 的地要接到信号地。如果混在一起开关噪声会串到 ADC 里。我一般用两层板功率走线在顶层信号走线在底层中间用地平面隔开。第四个是连接线。电机三相线要尽量短而且三根线要绞在一起减少辐射。如果线太长分布电感会导致电压尖峰可能超过 MOSFET 的耐压。我一般建议线长不超过 30cm超过的话要加吸收电容。这套方案我前后调了大概两个月从最开始的炸管到后来稳定运行踩了不少坑。现在这套硬件已经用在几个小批量项目上跑了半年多没出过问题。如果你也在做类似的东西希望这些经验能帮你少走点弯路。