ARTICLE DETAIL

资讯详情

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

基于DRV8818与STM32F373的步进电机驱动设计实践

基于DRV8818与STM32F373的步进电机驱动设计实践 做工业设备和机器人项目这几年我反复被问到“步进电机到底怎么选驱动方案”。市面上方案确实不少从最便宜的ULN2003到带闭环的伺服级驱动器都有但真要卡在“成本适中、可靠性高、开发周期短”这三条线上DRV8818PWPR加STM32F373RC这套组合是我实测下来很稳的选择。先说清楚这套东西是什么DRV8818PWPR是TI的双极步进电机驱动芯片内置电流斩波和微步控制STM32F373RC是意法半导体的Cortex-M4单片机自带16位高精度ADC和12位DAC两者搭配可以直接覆盖工业产线上的传送定位、机器人关节的主动臂、龙门架X/Y轴这类典型应用。这篇文章我会把硬件管脚设计、电流采样计算、步进脉冲软件实现、以及调试中遇到的坑完整梳理一遍适合正在做运动控制板卡、准备从A4988这类老方案升级的工程师也适合想搞清楚驱动芯片和MCU如何分工的学生。1. 方案选型为什么是DRV8818PWPR与STM32F373RC1.1 DRV8818在电机驱动链路里的真实定位DRV8818PWPR在TI产品线里属于“内置电流调节的功率级驱动”这句话听起来官方翻译成大白话就是你不用自己做恒流斩波电路芯片内部已经把功率MOSFET、电流采样放大、续流二极管、过热保护全部封装好了。你只负责告诉它“转不转、往哪转、用多大电流”剩下的事它自己处理。这个定位在工业设备里非常重要。早期很多工程师喜欢用分离器件搭H桥再拿比较器做电流斩波结果就是板子面积大、发热分布散、故障排查困难。DRV8818把功率级和逻辑控制分开了逻辑侧由单片机给脉冲功率侧直接接电机线圈这种“弱电控制强电”的边界非常清晰对做整机的人来说意味着维修和调试都能快速定位问题。DRV8818另一个值得一提的地方是它的微步支持。它通过若干引脚的高低电平组合可以切换全步、半步和多种细分模式。细分不光是让电机转得更平滑更重要的是降低低频共振和噪声。这一点对于放在办公室或实验室的机器人设备尤其关键——你总不希望设备一启动就像老式针式打印机一样尖叫。实际用下来在1/8细分以上时噪音和振动下降非常明显。当然DRV8818不是万能的。它内部没有位置闭环也不带编码器接口所以它解决的是“开环驱动”这一层问题。如果你要做的设备对丢步零容忍比如高速高负载的桁架机械手那还是要考虑加编码器或者直接上伺服。但如果是常规的速度可控、负载相对稳定的场合这套开环方案已经足够。1.2 STM32F373RC看中的不只是内核很多人选单片机第一个看主频第二个看Flash但做电机控制时我认为外设比内核更重要。STM32F373RC的主频是72MHz在Cortex-M4阵营里不算突出但它的外设组合在电机控制这个场景里出奇地好用。首先是定时器资源。F373有多个高级定时器和通用定时器可以在硬件上直接生成PWM脉冲不需要CPU一条条指令去翻转IO。步进电机控制本质上就是“数脉冲”如果每个脉冲都要中断处理一次脉冲频率一高CPU就被吃掉了。用定时器PWM模式CPU只需要设定周期和占空比剩下的波形生成全部交给硬件这对稳定性是本质的提升。其次是16位ADC。普通MCU的12位ADC在采集电流时分辨率有时候会不太够尤其在电流很小的时候量化噪声会让电流环参数很难调。F373内置的16位ADC是Sigma-Delta架构采电流反馈时精度优势非常明显。哪怕是简单做欠压保护或堵转检测精度高了以后阈值可以设得很准不会出现“明明是堵转了但ADC采到的电流没超过阈值”这种尴尬。然后是DAC。F373带12位DAC虽然电机控制里DAC用得不多但它可以用来输出VREF参考电压给驱动器。DRV8818的电流设定需要一路模拟电压如果MCU能直接DAC输出就不需要额外加数字电位器或可调电阻生产一致性比手工调电位器好太多。我后面会专门讲这个用法。1.3 和其他驱动方案的横向对比我经常被问到为什么不直接选A4988、DRV8825或者TMC2209。这里不是踩谁而是要说明“选型要看场景”。方案电流能力微步能力适合场景主要短板A49881A左右1/16桌面级3D打印机电流偏小散热一般DRV88252.5A1/32小型CNC、桌面设备内部保护逻辑相对简单TMC22092A左右1/256静音要求高的消费设备价格偏高配置复杂DRV88182.5A多种常用分度工业设备、机器人轴微步档位需引脚配置伺服驱动器数A到数十A全闭环高速高精场合价格高、调试门槛高DRV8818的定位很微妙的比桌面级驱动芯片电流大、保护全比伺服便宜一个量级。在工业设备里很多时候不需要伺服那么夸张的动态响应只需要“转矩够、转得准、别烧管”DRV8818正好落在这一档。再加上TI的芯片资料和封装都适合做量产板卡不会像某些模块那样“实验室能用、一上产线就飘”。单片机这边也一样。现在很多人推荐用ESP32或树莓派做控制但工业现场对实时性和温度范围有硬要求ESP32的WiFi/蓝牙在这种场合基本用不上树莓派的系统实时性又不太够。STM32F373RC是标准的工业级温度范围外设确定性高Cortex-M4带FPU哪怕是以后想加一些简单的滤波算法或前馈补偿算力也够用。2. 硬件设计从原理图到PCB的几个关键细节2.1 DRV8818周边电路的合理接法DRV8818的外围电路看起来简单但每个引脚都有讲究。我按功能分成三块来讲功率输入、逻辑输入、电流设定。功率输入主要是VM和GND。VM接电机电源我见过的工业设备多用24V或36VDRV8818支持到45V左右所以24V是非常舒服的工作点。VM引脚旁边一定要放一个至少100uF的电解电容再加一个0.1uF的陶瓷电容。这个组合不是为了好看而是因为步进电机在换相瞬间会产生很强的反电动势和电流尖峰如果电容放得不够电源电压会被拉高轻则触发芯片过压保护重则打坏驱动管。逻辑输入这块主要是STEP、DIR、nSLEEP、微步配置引脚。单片机给STEP发脉冲时脉冲宽度不能太窄我一般保证高电平至少2us以上。DRV8818内部有输入滤波脉冲太窄会被滤掉这个在高速时尤其致命——你以为发了1000个脉冲实际电机只吃了800个位置就直接偏了。DIR电平要在STEP上升沿之前稳定我习惯在切换方向后延时几微秒再发第一个脉冲。电流设定是很多人会忽略的部分。DRV8818通过VREF引脚和外部采样电阻共同决定线圈电流。VREF可以来自单片机的DAC也可以用电阻分压。配合ISENSE引脚外部接的采样电阻芯片内部会用VREF和采样电阻实时比较超过阈值就斩波。这个电流设定值必须根据电机额定电流来算算小了力矩不够算大了电机会发热严重时间长了还可能退磁。2.2 电流采样电阻和VREF的计算实例先说清楚DRV8818的电流公式。不同的档位对应不同的满量程电流但整体逻辑是输出电流等于VREF电压除以某个系数再除以采样电阻阻值。我习惯这样算先查数据手册确认电流放大倍数假设手册给的有效值是I VREF / (k * R_sense)然后代入实际数值。举个例子。我们常用的一款42步进电机额定电流1.7A额定电压2.8V左右。选采样电阻R_sense为0.22欧姆。如果手册的k值是0.5具体以数据手册为准要达到1.5A的峰值电流VREF就应该设定为VREF I * k * R_sense 1.5 * 0.5 * 0.22 0.165V这个电压如果用F373的DAC来给12位分辨率在3.3V参考下每个LSB大概0.8mV完全够用。但要注意DAC输出要加一个RC滤波至少一个1k电阻加100nF电容把DAC的毛刺和开关噪声滤掉否则电流环会跟着抖。这里一定要提醒电机的额定电流是相电流有效值而驱动芯片设定的通常是峰值电流。实际使用中我一般把峰值电流设定在额定电流的1.2到1.5倍之间但前提是散热条件要跟得上。如果电机表面温度长期超过80度说明设定值偏高要往回调。测温枪在这个环节是必备工具不能只靠手感。2.3 STM32F373与DRV8818的接口电路单片机这边接口组织起来其实很简洁。我是这样接的PA0或PA1输出STEP脉冲用TIM2的PWM通道这样硬件定时器直接出波。一个普通GPIO接DIR方向引脚方向不需要高频率翻转普通推挽输出就行。两个或三个GPIO接微步配置引脚根据系统需求在初始化时设定档位。nSLEEP引脚可以接MCU的GPIO也可以直接上拉但建议还是用GPIO控制这样可以在系统空闲时让驱动器睡下去降低功耗和发热。nFAULT开漏输出接MCU的输入引脚并加上拉。一旦芯片检测到过流或过热nFAULT拉低MCU可以立即停止发脉冲。还需要注意逻辑电平匹配问题。DRV8818的逻辑输入一般是3.3V兼容但最好确认一下VIH阈值。STM32F373的GPIO输出高电平在3.3V供电下大概3.0V以上只要芯片VIH低于这个值就行。我见过有人盲目用5V单片机结果逻辑高电平太高把芯片的输入钳位二极管搞到导通长期运行就有隐患。PCB布局方面我提出几个原则。功率地和逻辑地要单点连接避免大电流回流干扰弱信号DRV8818的底部焊盘必须接地并打足够多的散热过孔这颗芯片带2.5A电流时发热不小散热没做好会频繁触发热保护采样电阻要靠近ISENSE引脚走线要宽因为采样电阻上的压降就是电流反馈信号走线长了容易引入噪声。3. 软件实现驱动脉冲、微步与电流控制的落地代码3.1 基于定时器PWM的步进脉冲生成步进电机的控制核心是脉冲计数。不管上方跑什么算法最终执行层一定是“产生多少个精准的脉冲”。用延时函数去翻转IO是最容易写的方式但也是最不推荐的方式因为延时函数会阻塞CPU而且在中断里容易被高优先级任务打断脉冲间隔抖动会直接表现为电机噪声增大和振动。我用STM32定时器的PWM模式来产生脉冲。思路是选一个定时器比如TIM2配置一个PWM通道输出引脚接到DRV8818的STEP。定时器的时钟经过分频后决定脉冲频率。假设定时器时钟72MHz要输出10kHz的脉冲也就是每个脉冲周期100us那ARR寄存器的值就是7200-1。占空比设成50%也就是CCR设为3600。这样PWM波形的高电平时间刚好满足DRV8818对STEP最小脉宽的要求。配置代码大致是void step_timer_init(uint32_t freq_hz) { TIM_TimeBaseInitTypeDef tb; TIM_OCInitTypeDef oc; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); tb.TIM_Prescaler 72 - 1; // 72MHz / 72 1MHz tb.TIM_CounterMode TIM_CounterMode_Up; tb.TIM_Period 1000000 / freq_hz - 1; tb.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, tb); oc.TIM_OCMode TIM_OCMode_PWM1; oc.TIM_OutputState TIM_OutputState_Enable; oc.TIM_Pulse tb.TIM_Period / 2; // 50% 占空比 oc.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM2, oc); TIM_Cmd(TIM2, ENABLE); }需要多少个脉冲可以配合外部计数或者简单的中断计数。实际产品里我一般在定时器更新中断里做脉冲数递减到零就关闭PWM输出。这种方式CPU负担很小还能同时做加减速规划。这里有一个容易犯的错误修改频率时如果直接改ARR正在输出的PWM周期会乱一下电机就会抖。正确的做法是先用影子寄存器做缓冲在更新事件里同步修改或者干脆停掉定时器、修改、再启动虽然有一个极短的停顿但对低速场合的影响可以忽略。高动态响应的场合建议用DMA或硬件比较功能来平滑调速。3.2 微步配置与方向控制微步的配置是纯数字逻辑初始化时设一次就行。假设DRV8818对应用三个配置脚M0、M1、M2具体以数据手册为准不同组合对应全步、1/2、1/4、1/8、1/16、1/32等模式。我通常默认设置在1/8以上因为在这个档位下电机运行噪音和低频共振都能得到明显抑制。需要特别注意的是微步模式下每个STEP脉冲只走一个分步所以同样转一圈需要的脉冲数是整步的N倍。做运动控制换算时要把“每圈脉冲数”当成一个全局常量来定义。微步模式变化应该只在电机停止状态下切换。不要在运行中动态切换微步档位因为档位切换瞬间电流波形相位会突变可能导致电机失步或剧烈抖动。我见过有人想在高低速之间动态改细分数来提高“精度”结果就是现场频繁报警后来改成固定细分加软件加减速曲线问题才解决。方向控制的逻辑也很直接。DIR引脚电平决定旋转方向你可以在每次定位前设置GPIO。这里要留意的是不同批次或不同厂家电机相线颜色定义可能不一样同样的DIR电平转的方向可能完全相反。我建议在系统初始化时做一个“方向校准”流程用光电限位或机械原点确认一下正方向而不是在代码里写死。3.3 用F373的DAC做VREF电流控制前面提到F373自带12位DAC这里说说具体怎么在工程里用起来。思路是把DAC输出电压当作DRV8818的VREF基准从而实现“软件调电流”。我实际应用的场景是这样的设备启动时电机需要较大的保持力矩锁住轴但运动过程中如果持续这么大电流电机和驱动芯片都会严重发热。于是我在待机状态把DAC电压降低让电流降到额定值的50%需要动作时再把DAC电压拉高到额定值定位完成后再次降低。整个切换过程只需要修改DAC输出寄存器配合定时器做缓变还能实现电流斜坡避免电流突变带来的机械冲击。void dac_init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); DAC_InitTypeDef dac_conf; dac_conf.DAC_Trigger DAC_Trigger_None; dac_conf.DAC_WaveGeneration DAC_WaveGeneration_None; dac_conf.DAC_OutputBuffer DAC_OutputBuffer_Enable; dac_conf.DAC_LFSRUnmask_TriangleAmplitude DAC_LFSRUnmask_Bit0; DAC_Init(DAC_Channel_1, dac_conf); DAC_Cmd(DAC_Channel_1, ENABLE); } void vref_set(uint16_t output) { DAC_SetChannel1Data(DAC_Align_12b_R, output); }DAC输出要经过一级RC低通滤波再接DRV8818的VREF。我通常用1k电阻加100nF电容截止频率大概1.6kHz用来滤除DAC的量化噪声。如果你的系统对电流响应速度要求特别高可以适当减小RC值但滤波太浅会让电流波形变差需要平衡。3.4 加减速曲线与丢步防治很多初学者做步进控制就是直接发一个固定的高频脉冲结果电机要么起不来要么高速失步。原因很简单步进电机的输出力矩是随转速升高而下降的从静止直接跳到高速电机根本带不动负载自然就丢步了。加减速曲线我推荐最常用的梯形方案先以较低的启动频率发脉冲例如500Hz然后按照设定的加速度逐步提高频率直到目标速度接近目标位置时再逐步减速防止冲过头。S型曲线更平滑但对大多数工业场景不一定必要梯形曲线加合适的加速度就能解决。加速度的值怎么定我习惯这样估算先查电机在目标转速附近还能输出多少力矩再根据负载惯量算出最大角加速度。但工程上更简单的做法是实测法——把加速度设一个初值比如每秒500Hz增量让设备跑起来如果听到明显的丢步声或者电机闷响就把加速度减半直到稳定。这个方法虽然土但在不确定负载惯量的情况下很有效。软件里实现梯形加减速我推荐在定时器更新中断里逐级修改ARR值比如每1ms加一次频率。这样频率变化是阶梯式的但只要频率增量足够小实际听起来就是平滑的。要注意的是频率不能每步加太多否则相当于又在瞬间跳频不仅噪声大也可能再次丢步。4. 调试验证与常见水位实录4.1 上电后电机不转或啸叫的排查顺序我遇到的第一个高频问题是“程序明明在发脉冲电机就是不动或者只在原地嗡嗡叫”。排查顺序很重要按照这个顺序可以省掉大量时间。第一看电源。用示波器探头放在VM引脚上看看带载时电压有没有明显跌落。工业现场线缆长接触电阻大电机启动瞬间电流一拉VM电压可能从24V掉到18VDRV8818的欠压保护就会拦截脉冲。这个问题在原型机上经常被忽略因为你桌面上的电源是稳压电源接线短压降很小一旦装到设备上就露馅。第二看nFAULT。芯片只要进入故障状态就会拉低nFAULT。你用逻辑分析仪或示波器抓一下看它是不是在脉冲发给芯片后立刻被拉低。如果是说明电流过大或供电不足触发保护了。记住“nFAULT拉低”不是告诉你芯片坏了而是告诉你它为了保护自己主动切断了输出。第三看电流设定。很多人把一个1.5A的电机接到按2.5A设定电流的驱动器上结果电机动一下就热得烫手反复触发保护。这个纯粹是设定问题把VREF降下来就行。4.2 电机异常发热的根本原因分析发热是步进电机驱动里最容易被低估的问题。有位老工程师跟我说过一句话步进电机就是个电阻加热器电流越大发热越狠。确实步进电机线圈里的电流不管电机转不转只要通电就一直在发热而且热量的主要来源就是线圈的铜损。如果在正常负载下电机表面温度远超预期我优先怀疑的不是散热风扇而是电流设定值偏大。要知道步进电机的额定电流指的是它能长期承受的电流而不是“必须给这么大电流”。实际使用中如果负载只需要60%的力矩把电流设定到额定的70%到80%发热量会小很多。我建议在满足力矩的前提下尽量降低电流设定这样对电机和驱动器都有好处。另一个被忽视的点是微步模式影响发热。理论上在较高微步模式下电流波形更接近正弦有效发热比全步模式下要低一些。但在某些芯片实现里微步模式下为了保持力矩恒定峰值电流反而会略高于设定值。所以如果你改了微步模式后发现温度明显变化不要惊讶这是正常现象只需要重新校准VREF就好。4.3 高速失步时如何区分机械问题和电气问题高速丢步是最难查的故障之一因为它可能是机械的也可能是电气的。我总结了一个判断准则在同样速度下空载跑一下。如果空载也丢步问题基本在电气侧如果空载正常、带载丢步那大概率是力矩不够或加减速曲线太激进。电气侧还有一个常见原因脉冲频率太高DRV8818的STEP输入来不及响应。如前所述STEP最小脉宽有两三微秒如果你发的脉冲占空比或者周期接近这个极限芯片内部滤波会直接吞掉一部分脉冲。用示波器看STEP引脚波形时要看实际高电平和低电平时间不要只看频率。很多时候程序算出来的频率没问题但GPIO翻转速度受IO口驱动能力影响边沿太缓芯片误判了。机械侧也要检查联轴器和丝杆预紧。我遇到过一次很奇怪的现象高速往一个方向走丢步往另一个方向却正常。排查到最后发现是丝杆的轴向间隙在特定方向导致阻力突变跟电机和驱动芯片没有半毛钱关系。所以在排查高速丢步时一定要先手动盘一下轴感受阻力是否均匀。4.4 常见问题速查表调试阶段我把碰到的问题整理成一张表方便现场快速定位。现象可能原因处理建议上电电机锁死但有异响电流设定过大降低VREF电压或调低DAC输出电机完全不动STEP脉冲未到/被滤波检查脉冲宽度确认大于芯片要求的最小值电机运行时啸叫严重微步档位过低提高微步数比如从1/2改到1/8运行一段时间后停转热保护触发加强散热或降低电流设定值高速时丢步加减速曲线太陡降低加速度提高启动频率阈值方向反了电机相线接反或DIR逻辑反交换A A-或改软件方向标志VM电压跌落电源容量不足或线缆太长加大电源功率换粗线或加就近储能电容4.5 工业现场的电磁干扰与走线建议步进电机电缆是典型的噪声源。电机的PWM斩波电流在线缆上形成高频辐射如果和编码器信号线、CAN总线绑在一起走线很容易导致通信误码或传感器读数跳动。我在机器人项目里吃过这个亏伺服驱动器一启动旁边的RS485读回来的距离值就开始跳排查了两天才发现是电机线跟通信线走了同一个线槽。解决办法归结起来就几条。电机线用屏蔽双绞线屏蔽层单端接地信号线和功率线分开走中间至少留几厘米间距控制器外壳接地要可靠减少共模干扰。对STM32F373这边我还建议在STEP、DIR等信号线上串联22到33欧姆的小电阻这个电阻能抑制振铃降低对芯片引脚的高频冲击。DRV8818的输出端到电机之间我习惯加一个共模电感或者至少一个小磁珠能有效抑制高频辐射。如果对成本敏感也可以只在VM输入侧加效果稍差但比没有强。总的来说工业现场的设计必须把EMC问题当成一个正经需求来做而不是等到现场测试不通过再回头补。5. 应用落地与后续扩展的思考5.1 从代码到整机标定与生产一致性实验室里跑通和量产稳定之间还有很长一段路其中最容易出问题的就是一致性。同一批DRV8818和STM32F373在实验室里都正常一装上整机就有的正常有的丢步很多时候是电流设定不准导致的。VREF如果靠电位器手调每一台设备的力矩特性都会不同改成MCU的DAC输出之后至少控制逻辑是一致的只需要在出厂时对每台设备做一次电流校准。校准方法不复杂。在设备空载状态下设定一个标准VREF电压用钳形电流表测量电机线圈的实际电流记录偏差。如果偏差在合理范围内说明硬件一致性没问题如果偏差很大需要检查采样电阻的阻值精度和PCB焊接质量。我建议采样电阻选1%精度的合金电阻温飘要低因为电流采样电阻直接影响力矩精度这个钱不能省。5.2 增加编码器反馈的升级路径虽然DRV8818是开环驱动但STM32F373RC的资源完全可以支持加一路编码器反馈做成半闭环。做法是电机尾部加一个磁性编码器SPI或正交编码器接口接到F373的定时器编码器模式MCU实时读取实际位置与期望位置比较一旦发现偏差超过设定阈值就判定为丢步触发报警或自动补偿。这种“开环驱动加位置反馈”的方案成本远低于伺服但对很多设备来说已经够用。特别是机器人的关节轴不需要太高的动态性能但对位置准确性有硬性要求半闭环是非常有性价比的中间态。F373的编码器接口只需要一个定时器配置成Encoder Mode硬件自动计数MCU开销很小。如果以后想更近一步可以直接换带电流环的驱动芯片比如DRV8711这类外置MOSFET控制器或者干脆用F373的ADC采集相电流做FOC。但那样软件复杂度就上来了整个控制周期、PI参数、坐标变换都要重新搞适合确实有需要的项目不建议为了“高级”而盲目上。5.3 时序优化与多轴联动的一个小经验最后分享一个多轴项目中的经验。如果一个设备里有多个步进轴比如X/Y两轴龙门两个MCU或者两路驱动各自独立发脉冲容易出现“起步时间不同步”的问题导致画出来的轨迹是斜的。解决办法是把脉冲生成放到同一个定时器中断里一个Tick处理X轴一个Tick处理Y轴保证两轴的脉冲在时间上是严格对齐的。用STM32F373做双轴时你可以用两个定时器通道分别输出X和Y的脉冲然后在同一个时基中断里维护各自的速度变量。这样做好处是轨迹规划变成了纯软件问题跟外部硬件延迟无关。我在实际项目中用这个方案跑过1m/s的龙门轴重复精度在开环里表现已经很让人满意。个人在这套方案上踩过不少坑最大的体会是步进电机控制看起来只差“给脉冲”但真正决定设备能不能稳定跑的是电流设定、时序规划和工程细节的一致性。DRV8818PWPR和STM32F373RC这套组合的价值就是把功率部分和控制部分都收敛到足够简单的硬件接口上让你有精力去打磨软件算法和系统调试。如果你正准备新的运动控制项目可以照着这个思路先搭一套原型很快就能摸到门道。
返回列表