ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32F423RH+DRV8818PWPR双极步进电机驱动方案调优

STM32F423RH+DRV8818PWPR双极步进电机驱动方案调优 1. 这一对组合到底解决了什么问题做工业设备和机器人最常打交道的就是双极步进电机开环位置控制、低速大扭矩、结构简单成本低这么多年下来依然没有退役的意思。我最近完成的一套方案就是拿 STM32F423RH 做主控配一颗 DRV8818PWPR 驱动双极步进电机用在一个小型直角坐标机械臂的 X/Y 轴和末端旋转轴上。整套系统工作在 24V 母线、每相额定电流 1A 左右的 42/57 步进电机上跑了大半年启停冲击、低速啸叫、电流峰值这几个老问题都处理得比较干净。这篇文章不打算给你“选型手册式”的罗列而是把我从画原理图、调 PWM、跑加减速度到最后现场排障的全过程拆开讲。内容包括为什么用这颗驱动 IC 而不是成品驱动器STM32F423RH 在运动控制里到底强在哪梯形加减速的步数、脉冲频率怎么算以及我在测试中遇到的那些“看起来像是芯片坏了最后发现是外围问题”的案例。适合正在做步进电机驱动板、一体化运动控制器或者想把机器人轴控板从“能用”做到“稳定”的朋友参考。1.1 DRV8818PWPR驱动级可以少操很多心DRV8818PWPR 是 TI 的一颗双极步进电机驱动芯片PWPR 代表 PowerPAD-HTSSOP 封装底部自带散热焊盘。典型工作范围覆盖 8V 到 60V 的电机母线电压峰值电流能做到 2.5A 左右。芯片内部集成了两个 H 桥、PWM 电流斩波、固定关断时间控制、电荷泵栅极驱动以及过流、过温、欠压保护。这些功能放在十年以前要搭出一套同样的功率级至少需要四路 MOSFET、一路电流采样运放、一路比较器、两个逻辑电平转换电路外加一整套续流保护器件。所以这类驱动 IC 最大的价值是把“功率级”的麻烦收进芯片里。你在 PCB 上不需要处理高压侧浮动驱动不需要手动调电流环的 PI 参数只需要把 MCU 给出的方向、步进/相位信号送到逻辑输入再通过一个采样电阻设置相电流剩下的事情由芯片内部的固定关断时间控制器完成。对工业机器人这种对一致性和可靠性要求高的场合这种集成方案比完全分立的设计更容易复制、更容易排查故障。1.2 STM32F423RH不只是“会点灯”的处理器控制步进电机很多人觉得 MCU 没什么可挑的能输出方波就行。但真到了四轴、六轴或者带编码器闭环的机器人上MCU 的定时器资源和中断响应能力比主频重要得多。STM32F423RH 是 64 引脚 LQFP 封装Cortex-M4F 内核主频可以到 100MHz带 FPU 和 DSP 指令。对我来说FPU 在做轨迹规划、圆弧插补或者加速度滤波的时候很有用但真正关键的是它内部有多个通用定时器既能输出 PWM又能做正交编码器计数。F423 系列还带了硬件加密和真随机数发生器用来做固件加密启动、总线通信签名验证对于需要联网或者差分升级的设备来说很合适。不过在步进电机这个具体任务里它最核心的能力还是“多个定时器之间独立工作”我用一个定时器输出 STEP 脉冲另一个定时器专门读编码器互不打扰。这种并行能力是普通 MCU 用 GPIO 翻转方式很难做到的。1.3 和成品步进驱动器、分立 H 桥方案的取舍开发初期我也想过直接用成品步进驱动器比如市面上常见的“脉冲方向”控制盒。优点是省事、力矩调参旋钮一拧就行缺点也很明显体积大、价格高、内部电流衰减和斩波行为是个黑盒。当成批量做机器人本体时每个轴都要一个驱动器盒子和一堆线缆不仅占地方成本也压不下来。我也不是没考虑过纯分立 H 桥加运放采样。分立方案的电流环可以完全按自己的理念做但在没有专门调试设备和足够工程积累的情况下保护逻辑、栅极驱动、噪声抑制这些环节很容易翻车。集成驱动 IC 正好在中间外围元件不多保护齐全还可以通过 MCU 的 GPIO 动态配置部分行为。下面这张表是我当时做方案对比时的思路方案元件数量电流控制保护机制开发周期量产一致性分立 H 桥 运放比较器很多自己搭闭环通常较弱长一般意图和板级工艺都影响DRV8818PWPR 单芯片少内置固定关断时间过流/过温/欠压齐全短强成品步进驱动器最少黑盒可调范围有限有但不透明最短强但体积和成本高最终选择 DRV8818PWPR是因为它在“可控性”和“开发效率”之间平衡得最好。芯片由 MCU 直接控制可以针对机械结构做加减速和限流策略不再被成品驱动器封闭协议绑住。2. 硬件设计把电源、电流和热量管住2.1 电源架构与驱动 IC 外围电路这部分的工程量不大但最容易因为“少一个电容”而出奇怪问题。我给整个控制板用的是 24V 输入经过一路 DC-DC 转 5V再经过 LDO 给 STM32F423RH 供 3.3V。驱动部分直接使用 24V 母线不经过 5V 中间变换这样电机绕组上有足够的电压余量高速时电流建立速度更快。DRV8818PWPR 的 VM 引脚旁边我放了 10µF 陶瓷电容和 0.1µF 电容并联并且在电源入口加了一颗电解电容和 TVS 管。为什么需要这么组合陶瓷电容擅长滤高频噪声但容量越大直流偏压特性越明显电解电容扛得住母线电压的瞬时跌落但高频特性一般。两者配合才能既应对电机启动瞬间的大电流抽取又能把功率线上的尖峰压住。注意陶瓷电容要放在靠近芯片电源引脚的位置不是“靠近大概位置”而是焊盘旁边几毫米以内。那颗芯片需要外部电荷泵电容用来产生高边栅极驱动需要的电压。我第一次做这类电路的时候以为这个电容随便选个容值就行后来发现它影响高边 MOSFET 的开启能力。严格按数据手册推荐值选材质用 X7R 或者 C0G位置尽量靠近对应的 CP 和 VCP 引脚。如果电荷泵电容虚焊或者容值不对最典型的症状是电机带上负载后力矩明显不足甚至一开始能转、稍微加点阻力就停了。2.2 ISENSE 采样电阻相电流准不准就靠它DRV8818PWPR 这类带电流斩波的驱动芯片需要外接一个电阻把绕组电流变成电压信号再和内部基准比较从而决定每个 PWM 周期何时关断。这个电阻的精度和温漂直接决定了电机相电流的稳定性。以我的 24V/1A 项目为例相电流目标设在 1A 左右采样电阻选用 0.22Ω、1W 的合金电阻1% 精度。估算功耗就是 I²R1A 时大约 0.22W留出 4 到 5 倍余量温度就不会高得离谱。如果目标电流更大比如用到 2A电阻功耗会到 0.88W必须选 1W 以上甚至 2W 的规格否则电阻自身发热会导致阻值漂移进而让斩波电流偏掉轻则力矩不对重则触发过流保护。实际画板的时候这个电阻要尽量靠近 ISENSE 引脚。采样电阻的走线最好用“开尔文接法”的意识功率电流回路和采样电压检测回路分开走避免大电流路径上的铜箔压降叠加到检测信号里。走线一长地弹会把采到的电压抬高芯片可能在更低的电流就关断了表现为电机“没劲”。2.3 MCU 引脚分配与信号完整性我的板子上STM32F423RH 和 DRV8818PWPR 之间的逻辑连接非常朴素STEP、DIR、ENABLE、nFAULT最多再加一两个配置衰减模式或电流基准的 GPIO。引脚分配表如下供参考实际项目可以根据封装改动功能STM32F423RH 引脚说明STEPPA8TIM1_CH1由定时器 PWM 输出每个上升沿走一步DIRPB13方向信号运动前先建立ENABLEPC7使能驱动输出nFAULTPC6故障中断输入接到 EXTI电流/衰减配置PB0、PB1按实际芯片配置需求接这里有个很重要的原则STEP 信号要由定时器通道直接输出不要用 GPIO 在中断里翻转。原因是中断里的软件延迟会产生抖动脉冲间隔忽快忽慢低速时电机就会一顿一顿甚至引起机械共振。而使用 TIM1_CH1只要改变 ARR 或比较值脉冲频率的自然过渡非常平滑不需要 CPU 每次都精确卡点。DIR 信号虽然只是高低电平但在工业现场也要注意建立时间。方向切换的瞬间如果电机还有电流绕组里的磁场方向突然反转容易产生较大的电流冲击。更稳妥的做法是先把脉冲停掉改 DIR等待几微秒到几十微秒再重新发脉冲。2.4 PowerPAD 散热与 PCB 布局细节DRV8818PWPR 的功率部分发热主要在芯片内部的高边和低边 MOSFET 上。PWP 封装的底部有一个 PowerPAD 散热焊盘必须在 PCB 上开对应的露铜区并焊接到地。很多自制板子“芯片一跑起来就过热”不是因为驱动电流太大而是因为散热焊盘没焊好。我的做法是在散热焊盘下方打 6 到 12 个 0.3mm 左右的过孔连接到背面完整的地铜皮。这样做既帮助热传导也能改善接地路径。但过孔不要放在焊盘中心导致锡膏流走最好交错布置或者用盘中孔后填平。电机 AOUT、BOUT 两条输出线要尽量短、尽量并行走线不要绕大圈如果有电机插座输出线最好从芯片的一侧直接引出。逻辑地、功率地、模拟采样地在这类系统里最容易产生争议。我最终用了星形接地ISENSE 电阻的功率地回到驱动芯片电源地附近STM32F423 的数字地单独走一小块区域再在电源输入端单点汇合。这样做的效果是nFAULT 和编码器信号上的毛刺明显减少。3. 运动控制实现从梯形加减速到稳定脉冲3.1 先把“一个脉冲走多少”算清楚很多新手拿到步进电机开口就是“我需要最高速度多少转/秒”但真正控制时要先把脉冲数和机械行程对应起来。以我的直角坐标机械臂 X 轴为例电机步距角 1.8°整步每转 200 步。经过驱动级之后我按 3200 脉冲/转来理解系统的分辨率也就是 16 细分对应的步数。注意这个“细分”是驱动级和 MCU 配合后的表现不同驱动 IC 对细分的实现方式可能不同但从控制端看机械上跑一转需要多少个 STEP 上升沿是确定的。丝杠导程 5mm意味着电机转一圈滑台移动 5mm。那么脉冲当量就是3200 脉冲 / 5mm 640 脉冲/mm如果目标速度是 50mm/s那么对应的脉冲频率是50mm/s × 640 脉冲/mm 32000 脉冲/s这个数就是我们给定时器设置的输出频率。加速度也一样处理。假设加速度是 500mm/s²那么脉冲频率的变化率是500 × 640 320000 脉冲/s²也就是说每个毫秒频率增加 320Hz从 0 加速到 32000Hz 需要 100ms。在 100ms 的加速过程中滑台走过多少距离按速度从 0 到 50mm/s 的匀加速计算位移是 v² / (2a)也就是 2500 / 1000 2.5mm对应 1600 个脉冲。这个 2.5mm 很关键如果行程小于 2.5mm整个运动过程根本不该进入匀速段必须一开始加速就立刻转入减速否则一定会冲过头或者失步。我建议所有做运动控制的人都把这张“脉冲当量表”贴在调试文件里。不同导程、不同细分倍数、不同步距角会直接改变所有定时器参数换算错一个小数点现场就是满屏的偏差。3.2 用定时器 PWM 输出连续可控的步进脉冲STM32F423RH 在使用定时器输出 STEP 脉冲时最直接的做法是配置一通道 PWM 模式让输出频率等于目标脉冲频率占空比固定在 50%。因为步进驱动是按上升沿计数所以 50% 占空比能保证每个周期内高电平时间足够不会出现窄脉冲被驱动芯片忽略的问题。如果定时器时钟是 100MHz要输出 f Hz 的脉冲ARR 初值这样算ARR (100000000 / f) - 1当 f 32000Hz 时ARR 3124这个值在 16 位定时器范围内直接用。但当 f 比较低比如 10HzARR 就变成 9999999超出 65535。解决办法是先分配预设分频系数 PSC让计数频率降下来。例如 PSC 99计数器时钟变成 1MHz此时 ARR (1000000 / 10) - 1 99999还是超。再把 PSC 设到 999计数器时钟变成 100kHzARR 9999就合适了。我的推荐做法是不要每次在中断里临时做除法。加减速曲线所需的频率是预先算好的那么在初始化时就可以生成一组PSC, ARR组合表运动过程中直接查表更新定时器。这样既避免了浮点运算在中断里造成额外延迟也方便以后换不同导程时整体改表。下面是一个简洁的伪代码示例用 HAL 库设置频率static void set_step_freq(TIM_HandleTypeDef *htim, uint32_t freq_hz) { uint32_t psc, arr; if (freq_hz 0) { HAL_TIM_PWM_Stop(htim, TIM_CHANNEL_1); return; } // 选一个合适的分频系数让 arr 落在 16 位以内 for (psc 0; psc 65535; psc) { uint64_t count 100000000ULL / ((psc 1) * (uint64_t)freq_hz); if (count 65535) { arr (uint32_t)count - 1; break; } } __HAL_TIM_SET_PRESCALER(htim, psc); __HAL_TIM_SET_AUTORELOAD(htim, arr); __HAL_TIM_SET_COMPARE(htim, arr 1); // 50% 占空比 if (HAL_TIM_PWM_GetState(htim) ! HAL_TIM_PWM_STATE_READY) { HAL_TIM_PWM_Start(htim, TIM_CHANNEL_1); } }实际代码中不需要每步都做循环找 PSC把这段计算挪到预处理阶段生成表格。而在运动过程中只需要按当前的加速度阶段更新 ARR 值即可。3.3 加减速状态机与方向切换逻辑步进电机的加减速最怕的是“一步到位”式启动。如果目标速度 50mm/s直接给 32000Hz 的脉冲频率电机会因为瞬间转矩不足而丢步甚至发出难听的撞击声。我用的是一个标准的三段式状态机加速段、匀速段、减速段。启动时频率从 1kHz 左右开始而不是从 0 开始。严格来说频率从 0 开始更平滑但极低频率下电机本身振动大反而不好。我从低速开始进入加速段后按设定的加速度每秒增加 320000Hz 的脉冲频率到目标频率后保持匀速。什么时候切到减速段如果知道总步数和加速段消耗的步数可以实时计算剩余步数。当剩余步数小于减速段需要的步数时触发减速。typedef enum { MOTOR_IDLE 0, MOTOR_ACCEL, MOTOR_RUN, MOTOR_DECEL, MOTOR_DONE } motor_state_t; void motor_tick(void) { switch (motor_state) { case MOTOR_ACCEL: if (step_freq max_freq) { motor_state MOTOR_RUN; } else { step_freq freq_accel_per_tick; set_step_freq(htim1, step_freq); } break; case MOTOR_RUN: if (remaining_steps decel_steps) { motor_state MOTOR_DECEL; } break; case MOTOR_DECEL: if (step_freq min_freq) { motor_state MOTOR_DONE; HAL_TIM_PWM_Stop(htim1, TIM_CHANNEL_1); } else { step_freq - freq_decel_per_tick; set_step_freq(htim1, step_freq); } break; } }这个 tick 函数放在定时器中断里调用比如 1ms 中断一次。F423 有 FPU做这些整数和浮点混合运算毫无压力但我还是建议把freq_accel_per_tick这类变量预先算好避免每次中断重新计算。方向切换也是一个容易被忽视的细节。我习惯在每次运动结束之后先把 ENABLE 拉到停止状态再改 DIR 电平延时 5µs 以上最后重新使能并启动脉冲。如果电机带的是丝杠或同步带机械间隙还会导致换向瞬间的位置误差所以我在回原点和往复运动的代码里加了一个“反向消隙”动作到位后继续多走几颗脉冲甚至零点几个毫米把传动间隙吃掉。3.4 失步/堵转检测以及在机器人里的闭环补充纯开环步进系统最怕的其实是失步。没有编码器反馈时你发出去 1000 个脉冲电机实际只走了 998 步控制系统并不知道。DRV8818PWPR 的 nFAULT 是故障输出过流、过热、欠压时会拉低这属于保护性信号不是真正的失步检测信号。在这个机器人项目里我给每个轴加了一个 1000 线增量编码器接到 STM32F423 的定时器正交解码通道上。运动控制里做了一件事把编码器反馈的实际位置和目标位置做差每 10ms 检查一次如果偏差超过设定阈值立刻停止 ENABLE 并报警。这个闭环不是随动伺服而是“开环运行闭环校验”既保留了步进电机调校简单的优点又能及时发现丢步。如果不想加编码器也可以利用驱动 IC 的 ISENSE 电压做一个粗粒度检测运动过程中发现平均电流突然掉到接近 0很可能是因为堵转后绕组电流被切断或者驱动器进入了保护。不过这个方法实时性差而且容易受电源波动影响。在工业设备里编码器校验是最稳妥的方案。4. 调试实录解过的几个疑难问题4.1 STEP 有波形但电机一动不动从供电查起这是我在第一版板子上碰到的问题。示波器明明测到 PA8 上有干净的方波DIR 也正常但电机纹丝不动。我当时怀疑换的海盗芯片有问题后来一步步排查发现是驱动芯片的 nRESET 引脚被一个上拉电阻拉到了 3.3V但板子初始化时 GPIO 把它误配成了输出低电平把整个芯片按在复位状态。这个查了小半天。所以调试这类驱动电路第一步不是怀疑驱动芯片坏了而是先把所有控制引脚状态表过一遍。重点查这几个点VM 是否达到芯片工作电压、nRESET 是否释放、ENABLE 是否处于使能状态、STEP 信号是否稳定、电荷泵引脚电压是否正常。把示波器探头依次放在这些节点上往往比换芯片更解决问题。如果 STEP 和 ENABLE 都正常但还是不转就要看 AOUT 和 BOUT 两个输出端有没有 PWM 波形。如果输出端完全没有电压问题基本在驱动芯片的电源或者逻辑接口如果输出端有波形但电机不转就要检查电机线、相序、以及电机本身的额定电流是不是和采样电阻设置严重不符。4.2 nFAULT 反复触发过流和过热的两类典型nFAULT 一旦周期性拉低整个系统就会走走停停看起来像接触不良。这种问题在我测试 57 步进电机时出现过。当时把相电流目标设到 1.5A电机接上后芯片很快进入保护断开电机负载又恢复正常。这说明问题不在逻辑控制而在功率级的电流路径。用示波器抓 ISENSE 电阻上的电压发现波形一上电就冲得很高说明采样电阻阻值偏大或者电机绕组电感太小导致电流建立太快。重新把采样电阻换成目标电流对应的阻值并适当降低了母线电压问题就消失了。如果 nFAULT 是在板子运行十几分钟后出现用手摸 PowerPAD 对应的 PCB 背面能感到烫手那基本就是散热问题。先看散热焊盘焊接是否饱满再看顶底层铜箔面积是否足够不要一上来就加风扇。这类问题排查表可以这样整理现象可能原因排查手段上电立刻 nFAULT功率管短路或 ISENSE 取值错误断开电机测输出量采样电阻运行一段时间后 nFAULT芯片过温红外测温枪看 PowerPAD 底部温度带上负载后 nFAULT电流设置过高或电源跌落示波器看 VM 波形看峰值是否拉低4.3 低速共振、啸叫与高速失步低速共振是步进电机绕不开的话题。即使有加减速电机在某一小段速度区间里仍然容易因为转子和定子磁场交互产生振动听感就是“嗡嗡”或者“呜呜”的声音。第一版代码里我把输出频率一路从低速扫到高速结果在 200 到 300 脉冲/秒附近机械臂明显抖动。解决思路有两条。一是让加减速过程快速越过共振区间不要让电机长时间停在那个速度段。二是在驱动配置上优化衰减行为。DRV8818PWPR 这类电流斩波驱动斩波关断时的电流衰减模式会影响电流波形的跟踪能力。低速时电流纹波大容易产生振动适当调整衰减路径和斩波电流能明显改善。我没有一直用同一套固定配置而是让 MCU 在高速段和低速段分别设置不同的衰减策略实测啸叫消失电机表面温度也降了 1f、2f 度。高速失步则是另一类问题。它不是“频率输不出去”而是电机转矩不够。步进电机高速时反电动势变大绕组电流建立时间变短实际转矩会快速下降。遇到高速失步先别盲目提高 STM32 的输出频率应该检查母线电压是否足够高、相电流是否被驱动芯片正确限制以及加速度是否设得太大。提高母线电压通常能明显提升高速力矩因为绕组电流能更快建立。4.4 工业现场的干扰问题与线缆处理当我把这套控制板从桌面环境搬到现场后新问题就来了伺服驱动器、变频器、开关电源都挤在同一个电控柜里电机一跑编码器偶尔会出现毛刺串口通信也会偶发乱码。这种问题用万用表很难查要靠示波器加逻辑分析仪。先从源头降低干扰。电机相线是功率回路必须用双绞线并加屏蔽层屏蔽层在控制板一侧单点接地不要在电机端也接地形成地环路。STEP、DIR 这类逻辑信号尽量短不要和电机线走在同一个线槽里不得不交叉时垂直交叉。编码器信号我用的是差分线转单端接收进入 STM32F423 之前加 RC 滤波引脚上再接小电容吸收高频毛刺。电源入口的 TVS 和磁珠也不可省。有一次现场丢步抓了半小时波形才发现是 24V 开关电源在电机启动瞬间电压跌落到了 20V 以下导致驱动芯片内部欠压保护触发。于是我在 24V 进线处加了一个稍大的电解电容再配合 TVS 管母线电压稳下来后丢步问题再没复现。最后说一个我这次最想提醒的细节别小看 DRV8818PWPR 的电荷泵电容和 ISENSE 采样电阻的焊接质量。很多“芯片一上电就冒烟”其实是 PowerPAD 虚焊导致热量散不出去很多“电机电流不对”其实是采样电阻走线太长把地弹采进来了。把这几个基础点做扎实这套 STM32F423RH DRV8818PWPR 的方案放在产线上连续运行一年都不会弹一次 nFAULT。
返回列表