ARTICLE DETAIL

资讯详情

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

基于PIC18F4458与DRV8818的双极步进电机控制实践

基于PIC18F4458与DRV8818的双极步进电机控制实践 做工业设备或者机器人绕不开步进电机。我最近把一个运动控制板从原型验证一直跑到现场装机主控用的PIC18F4458驱动片用的DRV8818PWPR目标对象是双极步进电机。说实话这不是什么花哨的新方案但它在工业现场“能打”的程度是我把另一块板子烧了两次之后才真正体会到的。这篇文章就从头梳理一下为什么选这套组合、硬件怎么搭、固件怎么写、实测会遇到哪些坑。想自己做运动轴、机器人底盘、转台这类项目的朋友可以直接照抄省得再趟一遍。1. 方案拆解这套组合到底在解决什么问题1.1 双极步进电机控制为什么不是“接两根线”的事先把基础概念对齐。双极步进电机有四根线内部两个绕组分别命名为A、A-和B、B-。要让电机转起来不像直流电机那样给电就转需要两个H桥按特定顺序换相轮流给两个绕组通电。换相顺序错了电机不是正常旋转而是在原地抖动或者发出刺耳的“嗡嗡”声。另一个麻烦在于绕组额定电流通常从几百毫安到两三安普通MCU引脚那点驱动能力根本带不动所以MCU和电机线圈之间必须有一级功率驱动电路。这还没完。绕组电流在工作时是感性电流如果一直硬灌电电流会不断上升直到烧毁所以驱动必须带电流斩波功能把电流限制在目标值。运动控制还希望低速时振动小一点这需要微步细分。DRV8818PWPR就是一颗把两个H桥、电流斩波逻辑、细分译码全部集成在一起的专用步进驱动芯片MCU只需要给它一个步进脉冲信号STP和一个方向信号DIR剩下换相、斩波、衰减这些脏活累活芯片自己全干了。1.2 为什么是DRV8818而不是A4988、DRV8825或者TMC2209市面上步进驱动芯片很多我做项目时也对比过几款热门型号核心差异在电压范围、电流能力、细分方式和电流设定机制上。DRV8818的账面参数不算最亮眼但它有几个很适合工业场景的特点驱动芯片持续电流最大电压细分衰减控制电流设定典型场景DRV8818PWPR最高2.5A45V1/8步外部可控混合衰减外置检流电阻VREF工业设备、机器人关节A4988约1A35V1/16步固定衰减板载电位器3D打印、桌面DIYDRV8825约2.2A45V1/32步固定衰减板载电位器3D打印、小型CNCTMC2209约2A29V1/256步内置自整定UART配置静音需求的桌面设备DRV8818首先胜在电源电压可以到45V意味着可以吃24V或者36V的工业标准母线而不是像很多桌面级驱动那样只能工作在12V或者勉强到24V。其次它的电流斩波阈值由外部检流电阻和VREF电压决定设计者能精确控制电流这一点在批量产品里非常重要。TMC系列有静音优势但在现场震动和发热环境下DRV8818的混合衰减方式反而更皮实。提示选型时不要只看“最大电流”这个数字还要看工作时散热条件。DRV8818的2.5A是在足够散热前提下才能达到的实际量产我会按70%~80%降额使用。1.3 PIC18F4458为什么主控选一颗8位单片机现在做运动控制很多人脱口而出就是STM32甚至是更高端的处理器。但对于“控制几个步进电机”这个任务PIC18F4458这种8位MCU反而更省心。首先是定时器资源够用。PIC18F4458有四个定时器还有多个CCP/ECCP模块产生步进脉冲、方向信号、使能控制都绰绰有余。其次是引脚电平直接匹配驱动芯片的逻辑接口不需要额外的电平转换电路。更重要的是在工业现场“稳定”优先于“性能”一颗运行频率不是最高、外设却非常直白的MCU出问题的可能性反而小。开发工具链也完全免费MPLAB X IDE加XC8编译器就能干活学习成本和维护成本都很低。另外PIC18F4458本身自带USB、CAN总线和多个串口这就给后续扩展留了很大的余地。我之前有一个项目最开始只做了单轴步进控制后来客户要求把多台设备用CAN总线连起来主控直接换用PIC18F4458的CAN模块固件改动量很小。选型的时候把未来两年的扩展需求考虑进去能省掉一次改版的痛苦。1.4 为什么不自己搭分立H桥有人会说两个MOSFET加一个比较器也能搭出步进驱动成本更低为什么不自己搭我确实自己搭过然后就不想再来第二次了。分立方案需要解决栅极驱动、死区时间、电流检测放大、故障保护、PCB寄生参数处理每个环节都要单独验证。这些工作量加起来远远超过一片DRV8818的芯片差价。尤其在工业EMC测试里自己搭的桥很容易在某些瞬态干扰下误触发或振铃而专用驱动芯片已经把栅极驱动死区、滤波去毛刺这些细节内部优化好了外围只需要摆几个电容电阻。2. 硬件设计细节从引脚到散热一步都不能省2.1 DRV8818PWPR 引脚与关键外围元件DRV8818PWPR采用HTSSOP-16封装底部有一个大散热焊盘。HTSSOP的引脚间距不算大手工焊接有点考验但用热风枪或者回流焊就没什么问题。用到的核心引脚如下引脚名称功能设计要点VM电机电源输入范围8.2V~45V就近放47µF电解和0.1µF陶瓷电容GND功率地单点汇流至电源输入端避免与逻辑地串扰STP步进脉冲输入上升沿触发一步建议串联小电阻作缓冲DIR方向输入高低电平控制正反转EN使能输入低电平使能不用时可串联电阻连接MS1、MS2细分模式选择可接MCU GPIO也可直接接高/低电平固定模式DA0衰减模式控制控制快速/慢速/混合衰减直接决定运行噪音OUT1、OUT1-A相绕组输出接电机红蓝线注意不要和B相互换OUT2、OUT2-B相绕组输出接电机绿黑线SENSE1、SENSE2检流电阻接口外接检流电阻到GND电阻精度要高VREG内部稳压器输出外接电容可作逻辑参考注意负载能力有限VREF电流参考电压通过分压电阻设定决定电机斩波电流外围电路里最容易出错的是检流电阻和VREF分压。检流电阻的功率要按电流平方乘以电阻值去估算比如1.5A电流、0.1Ω电阻理论上功耗是0.225W实际选择1W或更大的电阻比较稳妥留出余量。VREF部分我习惯用精密可调电阻加固定电阻的组合这样调试时可以微调电流值不需要反复换焊电阻。VREG输出端的电容也不要省这个引脚内部稳压器工作如果不稳定会直接影响电流参考电压的精度。2.2 MCU与驱动板的接线方案我的控制端口分配是这样设计的RB0 - STP步进脉冲输出RB1 - DIR方向输出RB2 - EN使能输出初始化为低有效RC4、RC5 - MS1、MS2细分选择由程序动态换挡普通开发板上MCU和驱动芯片可以直接连线但如果现场有变频器、接触器、伺服驱动器这类大干扰源我强烈建议在STP/DIR/EN这几根信号线上加高速光耦隔离。工业环境里的“莫名其妙丢步”和“单片机偶发复位”很大一部分是电机功率线或者外部干扰耦合到逻辑信号上造成的。光耦用6N137或者TLP2366都能跑几十kHz的步进脉冲延迟在微秒级完全够用。隔离之后MCU的地和电机驱动的地就可以彻底分开只在电源输入端做一个单点连接。2.3 电源容量怎么算以24V直流母线为例假设电机额定电流2A/相两相同时通电时理论最大功率是24V乘以2A等于48W这是最坏情况。实际运行时因为斩波平均功耗会低一些但选电源还是要按这个最坏值再加30%余量所以我会选24V、5A左右的开关电源。特别提醒电机加速瞬间电流会冲得很高电源如果输出能力不足母线电压会被拉低驱动芯片进入欠压保护表现就是电机一动就停。电源进来的位置要在VM引脚旁边放一个大容量电解电容再加一个小陶瓷电容。电解电容负责低频能量陶瓷电容负责吸收高频开关噪声。我曾经因为偷懒只放了一个电解电容结果电机高速运行时驱动芯片的表面温度明显比加了陶瓷电容时高就是因为开关毛刺太大增加了损耗。2.4 散热处理HTSSOP底部焊盘不能浪费DRV8818PWPR的散热路径主要在底部焊盘PCB上必须设计对应的散热焊盘阵列用多个过孔把热量引到背面大铜箔区。第一次做板子时我图省事只在顶层铺了一块铜1.5A电流连续跑两个小时芯片表面温度直冲80°C手摸都不敢摸。后来按照数据手册建议在焊盘下方打了9个过孔背面铺了整块铜皮同样条件下温度降到了65°C左右。注意如果PCB批量生产过孔建议用塞孔处理防止回流焊时焊锡从过孔漏走。手工样板的过孔可以简单点但数量和孔径尽量按手册来。3. 固件实现从空转抖动到平滑加减速3.1 开发环境和配置位我用的是MPLAB X IDE搭配XC8编译器芯片选择PIC18F4458。新建工程后第一件事是处理配置位#pragma config FOSC HS // 外部高速晶振 #pragma config WDT OFF // 关闭看门狗 #pragma config LVP OFF // 关闭低电压编程 #pragma config BOR ON // 开启欠压复位 #pragma config MCLRE ON // 保留MCLR复位引脚外部晶振我选择16MHz这个频率下Timer0做步进脉冲的精度足够而且不会因为主频太高导致中断响应太紧张。配置位里看门狗如果忘记关闭程序跑着跑着突然复位多半就是它惹的祸。3.2 I/O初始化与定时器配置步进控制的核心是“STP引脚上要有一个频率可变的脉冲信号”。实现方式有几种一种是固定频率用CCP模块直接输出方波但速度调节不灵活另一种是用定时器溢出中断每次中断翻转一次STP引脚速度变化只需改定时器初值加减速非常方便。我选择后者。#define STEP_PIN PORTBbits.RB0 #define DIR_PIN PORTBits.RB1 #define EN_PIN PORTBbits.RB2 void GPIO_Init(void) { TRISBbits.TRISB0 0; // STP 输出 TRISBbits.TRISB1 0; // DIR 输出 TRISBbits.TRISB2 0; // EN 输出 STEP_PIN 0; DIR_PIN 0; EN_PIN 0; // 默认使能 } void Timer0_Init(void) { T0CON 0b00000110; // Timer0开启16位模式1:64预分频 TMR0H 0xFF; TMR0L 0x83; // 初值决定脉冲频率这里按需要调整 INTCONbits.TMR0IE 1; INTCONbits.TMR0IF 0; INTCONbits.GIE 1; }定时器溢出周期决定STEP信号翻转频率。16MHz晶振、1:64预分频下计数器每计数一次需要4µs溢出一次需要的总时间是65536-初值乘以4µs。初值设成0xFF83那么溢出周期大约是300µsSTEP每300µs翻转一次也就是每600µs产生一个完整的脉冲步进频率约1.67kHz。这个频率在大多数42步进电机全步模式下是可以稳定启动的。实际调速度时我就是反复改TMR0H和TMR0L的初值从启动到高速慢慢摸出一组合适的数据。3.3 中断里的脉冲翻转与步数计数中断服务函数是整个程序最不能卡壳的地方里面不能做浮点运算不能调用延时函数。我的写法是维护一个全局的步数计数器每两次翻转算一个步进脉冲方向切换前要等当前目标步数走完。unsigned long g_step_target 0; unsigned long g_step_count 0; unsigned char g_pulse_state 0; void __interrupt() isr(void) { if (INTCONbits.TMR0IF) { // 每次溢出翻转STEP形成方波 STEP_PIN ~STEP_PIN; g_pulse_state ~g_pulse_state; // 只在STEP上升沿时计数 if (g_pulse_state) { if (g_step_count g_step_target) g_step_count; else STEP_PIN 0; // 实际应用中目标到了可以拉低STP } TMR0H TMR0_RELOAD_HIGH; TMR0L TMR0_RELOAD_LOW; INTCONbits.TMR0IF 0; } }这段代码看起来简单但有一个细节值得注意重新装载TMR0H和TMR0L时最好采用16位一次性写入方式也就是把TMR0H写在前面、TMR0L写在后面这样两个字节的装载间隔极小不会发生“写到一半溢出”的偏差。如果对这个时序精度要求更高可以在中断一开始就暂停Timer0装载完再启动。不过实测下来用先写高字节再写低字节的方式误差可以接受脉冲间隔非常稳定。3.4 方向切换的正确姿势方向切换时最怕的是上一步还没走完就改变DIR这样驱动芯片会立刻改变换相顺序电机实际会少走一步或者多走半步。我通常写一个方向切换函数先检查是否还有未完成的步数把剩余步数清零并等待最后一个脉冲下降沿结束后再翻转DIR。void Set_Direction(unsigned char dir) { // 等待脉冲队列排空 while (g_step_count g_step_target); DIR_PIN dir ? 1 : 0; // 加上一个短延时让驱动芯片稳定 __delay_us(20); }20µs的延时虽然短但足以保证DRV8818内部的电平判断稳定下来。如果省掉这一步在高频运行时偶尔会听到电机“咔”一声那就是方向切换瞬间丢了半步。3.5 细分真值表和电流参考电压计算DRV8818通过MS1和MS2两个引脚组合选择细分模式MS1MS2细分模式00全步10半步011/4步111/8步电流整定我通常按电机额定电流的80%到90%来设。比如42步进电机额定1.5A那斩波电流目标就是1.2A到1.35A。DRV8818的VREF和检流电阻关系工程上可以按 VREF Itrip × 8 × Rsense 来粗算。如果Rsense取0.1Ω目标1.2A那VREF就是1.2×8×0.10.96V。实际电路里我习惯用VREG引脚的7V分别通过两个电阻做一个分压得到0.96V左右。需要注意的是这只是估算上电后要用电流探头或者带扭矩测试来微调不同的电机、不同负载适配的电流值可能差不少。提示如果电机表面温度有点烫手但手还能放上去三秒电流再往回调10%通常问题不大。如果连碰都不能碰多半是电流设太高了要考虑调低或者加强散热。3.6 梯形加减速从计算公式到中断里的实现步进电机最忌讳频率突变。直接从零跳到1kHz以上很多电机都会啸叫或者丢步所以启动和停止要有一个斜坡过程。梯形加减速是工业上最常用的曲线实现在定时器中断里并不复杂。思路是这样的把速度档位分成三个阶段加速阶段每隔一定步数把定时器初值向高速方向缩小匀速阶段初值不变减速阶段每隔一定步数把初值放大。因为定时器初值越小溢出频率越高所以加速是“初值递减”减速是“初值递增”。unsigned int g_reload_value; // 当前定时器重装初值 unsigned int g_reload_max; // 最低速度对应的初值 unsigned int g_reload_min; // 最高速度对应的初值 unsigned char g_accel_step; // 每隔多少步调整一次初值 void Accel_Update(void) { if (g_step_count g_accel_threshold) { if (g_reload_value g_reload_min) g_reload_value - (g_reload_value 6); } else if (g_step_count g_step_target - g_accel_threshold) { if (g_reload_value g_reload_max) g_reload_value (g_reload_value 6); } }我这里用的是按比例递减不是固定减一个数。原因很简单低频时周期长固定减几个数变化率不明显高频时周期短固定减几个数又太猛容易冲过头。按百分比变化整个加速过程更均匀。这个“右移6位”相当于每次减少约1.5%实际调试时可以从这个比例起步根据丢步情况再调整。4. 实测调试记录波形、电流和温度都要看4.1 上电前的检查清单每次改完电路我都不会急着上电先做一整套检查这套清单救过我很多次万用表量VM引脚对地电阻确认没有短路。量VREG输出电压正常应该在6.5V到7V之间。量STP和DIR引脚对逻辑地的电平确认不是悬空。确认电机四根线没有接反A相和B相之间电阻应该一样。确认检流电阻两个引脚之间阻值等于标称值。如果VM和GND之间短路问题基本在检流电阻或者输出引脚的焊锡上。如果VREG电压不对先查VREG引脚外接电容是否装反电容极性接反会导致内部稳压器工作异常。4.2 用示波器看三处关键波形上电后第一件事不是直接转电机而是看波形。第一个要看的是STP引脚应该是一串干净、边沿陡峭的方波高低电平不超过3.3V或者5V晶振频率抖动肉眼看不出来。第二个要看的是检流电阻两端的电压波形。正常斩波状态下电阻两端的电压会有规律的锯齿状脉冲峰值对应斩波电流。如果这里的波形是一条平的直线说明电流根本没有建立起来多半是供电没到位或者检流电阻虚焊。第三个要看的是OUT1和OUT1-之间的差分波形。双极驱动的输出电压随着换相会呈现阶梯状变化细分模式下这个阶梯会非常平滑。如果阶梯形状不对称说明A相绕组的某一边MOSFET工作不正常或者电机某根线接触不良。调试时我习惯把示波器时间轴设为每格1ms到5ms先看低频再逐渐提高到高速每个速度段波形都应该保持干净的边沿。4.3 空载测试与带载测试的区别空载测试时电机轴不接负载加速电流很小即使电流整定得低一点也能转。所以空载转得顺不代表带负载就没有问题。我的测试顺序是空载全步模式从最低频率逐步往上推记录失步临界频率。空载1/8细分模式再推一遍频率范围。接上负载我用的是铝板加配重块重复上面的频率扫描。记录带载时的丢步频率和扭矩表现确定安全运行范围。实测下来同一块板子全步模式空载可以跑到12kHz1/8细分模式空载反而只有7kHz左右。这是因为细分模式下电流切换更频繁同样电流下驱动芯片的开关损耗更大反而限制了高频性能。所以如果项目需要高速运转不要盲目追求高细分高速段用全步或者半步低速段用1/8细分是一个现实可行的妥协方案。4.4 电流调整和发热平衡把电流从1A调到1.5A发热量变化非常明显。在室温25°C环境下1A时电机表面大概40°C1.5A时直接到60°C。芯片表面温度也从50°C升至70°C。如果工业设备是连续八小时运行这个温度在很多应用里已经逼近上限了所以我会在满足扭矩的前提下尽量压低电流。测试时手里拿一个小红外测温枪很方便地扫几个关键点芯片表面、电机外壳、检流电阻各看一遍。实操心得不要只看“能不能转”更要看“转了两小时之后还稳不稳”。有些板子刚上电一切正常跑半小时后芯片热了电流性能下降电机就开始丢步。这种热态问题在调试阶段最容易忽略。5. 常见问题排查与工业、机器人应用扩展5.1 典型故障速查表我把调试中遇到的常见问题和解决方案整理成了速查表方便现场排查现象可能原因排查与处理电机完全不动使能引脚为高、VM没上电、STP无脉冲先测EN是否为低再量STP波形最后查VM电压电机“嗡嗡”响但不动缺相、绕组断线、MOS驱动异常量电机四根线间电阻确认A相B相都有电阻电机抖动严重细分设置不稳定、MS1/MS2悬空把MS1/MS2直接用导线接高/低电平排除干扰高速段失步加速太猛、母线电压不足降低加速斜率提高电源电流余量温度过高电流设置偏大、散热不良降低VREF或者电流设定检查底部焊盘过孔单片机偶发复位功率地干扰、电源毛刺加光耦隔离地线单点汇流电源加TVS低速段振动大细分不够或者共振切到1/8细分或者让速度避开共振区间这个表里最容易被忽略的是MS1/MS2悬空。因为CMOS输入在高阻抗状态下容易受环境噪声影响细分模式会随机跳变。工业现场如果有伺服电机在旁边电磁辐射足以让悬空引脚的状态乱跳。所以不用的逻辑引脚要么接上拉/下拉电阻要么直接焊到固定电平不要偷懒。5.2 长线缆和EMC工业现场的必修课现场布线经常是几十米长电缆步进电机线本身就是一根巨大的天线。如果不做处理驱动芯片受干扰丢步、上位机通信出错都是常事。我在这方面的经验有几点电机线使用屏蔽双绞线屏蔽层单端接地。驱动输出端串联磁环或者至少绕两圈在磁环上抑制高频共模噪声。24V输入位置加EMI滤波器比在芯片旁边加一大堆电容管用得多。STP、DIR这些逻辑信号用光耦隔离把功率地噪声彻底隔离出去。端子排附近加TVS管静电打上去不会伤到芯片。有一次设备调试时PLC一吸合继电器步进轴就丢步几十步查了半天最后发现是继电器线圈的续流二极管选型不对反向电动势通过24V母线窜进驱动板。后来在电机电源输入线上加了一个33V的TVS管这个问题彻底消失。5.3 从单轴到多轴机器人应用的扩展路径单个轴控制跑通之后做机器人或多轴设备就是“数量叠加”的问题。PIC18F4458的定时器资源足够支撑两三个轴的脉冲产生如果轴数更多我建议按“一板一轴”的组织方式每块板用一个PIC18F4458加一片DRV8818轴与轴之间通过CAN总线通信。PIC18F4458自带CAN模块省掉外部CAN控制器组网非常方便。上层系统如果是ROS 2或者其他机器人软件栈底层步进轴可以直接抽象成“关节执行器”。视觉引导系统计算出坐标偏差之后换算成每个轴的脉冲增量和速度档位通过串口或者CAN发给控制板。这时候你会发现底层MCU要做的其实就是可靠地执行“从A点走N步到B点”真正复杂的轨迹规划和插补不需要在这颗8位单片机里做放在上位机里完成可靠性会高很多。我实际做过的机器人转台项目里视觉相机识别目标位置上位机算出角度差发给底层的PIC18F4458MCU负责梯形加减速把转台转到目标角度整个周期稳定在几十毫秒以内。这种分层结构非常清晰调试时哪一段出了问题很好定位。5.4 长期运行阶段的维护建议设备装到现场并不代表工作结束工业设备最重要的是长期稳定。电机端子处的螺丝在震动环境下容易松动最好使用带弹簧垫圈的端子或者加螺纹胶。散热区域的粉尘积累会严重影响散热效果建议每隔一段时间检查一次PCB表面温度。对于连续长时间运行的设备我会把驱动电流设定值留到额定值的80%左右宁可在加速时间上稍作让步也不让热问题在运行半年后爆发。6. 最后的几点体会这套DRV8818PWPR加PIC18F4458的方案我前后做了好几个版本最大的感受是步进控制这种底层执行器稳定、可控、成本低比单纯追新方案重要得多。前期调试时不要急着写花哨的运动算法先把单轴全步模式跑通再上细分和加减速最后再考虑多轴协同。每一步都验证充分后面出问题的概率会小很多。再分享一个小技巧如果现场出现电机偶发抖动或者莫名丢步先别急着怀疑芯片和代码拿一根导线把电机金属外壳与驱动器GND短接一下或者检查机箱的接地弹簧是否接触良好。很多看似复杂的电气问题最后都是接地处理不到位引起的。这个动作不用花一分钱但能省下整整一个下午的排查时间。
返回列表