ARTICLE DETAIL

资讯详情

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

STM32与DRV8818驱动双极步进电机:从选型到固件调试全记录

STM32与DRV8818驱动双极步进电机:从选型到固件调试全记录 前阵子给一台桌面级机械臂换驱动方案电机用的是两个NEMA 23双极步进电机控制端是一颗STM32F100ZE。原方案是外购的整机步进驱动器体积大、接线多而且批量装设备时成本压不下来。于是我把功率驱动部分换成了德州仪器的DRV8818PWPR这颗芯片把两个H桥和微步进索引器集成在一起配合STM32F100ZE的定时器资源只靠STEP/DIR两根信号就能让电机顺畅转起来。这篇文章就把这套方案的选型逻辑、原理图设计、固件实现和调试踩坑完整整理一遍适合正在做工业控制器、机器人关节或自动化设备的嵌入式工程师参考。如果你是刚接触双极步进电机控制也能从中摸清这类带索引器驱动芯片的工作套路。1. 选型逻辑为什么是DRV8818加STM32F100ZE而不是现成驱动模块1.1 成品驱动器的问题很多人在实验室里做样机第一反应是买A4988或者TB6600这类现成驱动模块接上单片机和电机就能转。这个思路在验证原理时没问题但真的要把设备批量装出去问题就来了模块要占安装空间、线束要额外转接、供电和信号接口五花八门最麻烦的是现场可靠性——接插件松动、散热条件差、电流保护阈值不可调任何一个环节出问题都够你排查半天。在工业项目和机器人应用里我更愿意把驱动部分直接设计到主控板上。一方面减少了中间连接另一方面可以把电源滤波、采样电阻、保护电路都按实际工况设计到位。DRV8818PWPR这种带索引器的驱动芯片正好适合这种板载化改造。1.2 DRV8818PWPR的定位DRV8818是TI的双极步进电机驱动器内部集成两个独立的H桥可以直接驱动双极步进电机的两个绕组。它的关键特征是内置了微步进索引器你不需要用MCU去模拟正弦/余弦电流序列只需要给STEP引脚发脉冲芯片自己会把每一步对应的电流曲线输出到电机绕组上。引脚后缀里的PWPR对应HTSSOP-16带PowerPAD封装属于带散热焊盘的小封装。这个封装的好处是驱动芯片可以直接把热量传导到PCB铜皮上不需要额外加散热器在工业控制器里非常实用。工作电压方面VM的范围可以覆盖12V/24V这类常见工业母线的需求峰值输出电流可以到2.5A级别驱动NEMA 17、NEMA 23双极步进电机足够了。1.3 STM32F100ZE在这套方案里的分工STM32F100ZE是ST的Value line芯片Cortex-M3核主频24MHz。说实话这个主频在电机控制里不算高但步进电机控制恰恰不需要跑浮点运算它需要的是稳定的定时器输出和足够多的GPIO。F100ZE是144引脚封装最高512KB Flash片上有多个通用定时器完全能同时管两三路电机。我在这套方案里让F100ZE做三件事一是用定时器产生稳定的STEP脉冲二是用普通GPIO控制方向、使能、微步进模式选择这些逻辑信号三是跑加减速规划和多轴协调。功率部分全部交给DRV8818这样MCU的负载很轻不需要频繁进中断做多轴扩展也方便。1.4 客户要的是可靠性不是炫技可能在很多人眼里STM32F100ZE有点老主频也低为什么不换F103或者G4系列我的回答是设计一个产品芯片选型要看整体系统需求。这套方案里电机运动控制最核心的实时性由定时器硬件保证DRV8818承担了电流闭环和微步进细节F100ZE的资源和性能在这个分工下完全够用而且F100系列在工业环境里的供货和成本稳定性更好。选型不是追求参数天花板而是把每一颗料的作用发挥到位。2. DRV8818如何把步进脉冲变成绕组电流2.1 双极电机为什么需要两个H桥双极步进电机和单极步进电机最大的区别在于绕组电流需要双向流动。单极电机绕组中间有抽头一个方向一个绕组双极电机每相只有两根线要让A到A-和A-到A都能产生磁场就得靠H桥来切换电流方向。DRV8818内部的两个H桥就是干这个事的。每个桥的输出端OUT1/OUT2连接A相绕组OUT3/OUT4连接B相绕组。整步模式下一个STEP脉冲就切换一次桥臂的导通组合电机转过一个基本步距角——最常见的是1.8度也就是200步一圈。如果你只是想让电机转起来知道这一步就够了。但真正让电机转得稳、转得安静还得看后面的电流控制和细分。2.2 电流斩波为什么不能直接给绕组上电压步进电机的绕组电感不大如果直接把母线电压加上去电流会很快冲到危险值把绕组烧掉。所以这类驱动器内部都采用电流斩波方式先把功率管全部打开让电流上升等电流到达设定值就切换成衰减状态让电流缓慢下降然后再次打开往复循环。这就是常见的PWM恒流控制。电流设定值由两部分决定一是芯片的VREF引脚电压二是ISEN引脚上的采样电阻。VREF越高电流限制值越大采样电阻越小同样VREF下允许的电流越大。具体公式需要查你手里那颗DRV8818的数据手册每一家的系数不尽相同但工程上的做法是先把VREF通过一个电位器引到芯片然后根据电机的额定电流去调节实测电流波形确认后再固定成电阻分压。这里有一个很重要的经验不要把电机的额定电流当成驱动器的设定电流用满。工业现场温度高电机散热条件差如果你的目标电流是1.5A采样电阻和VREF就按1.2A来设定留20%余量。转速提不上来可以靠提高母线电压解决电流余量不足现场烧的往往不只是驱动芯片连电机一起废。2.3 微步进索引器让MCU轻松一点在没有索引器的方案里做16细分需要MCU实时输出两路正弦PWM还要同步切换方向对定时器资源和中断开销都很大。DRV8818把这一步省掉了芯片内部有一套微步进电流表根据M1/M2/M3引脚的电平组合确定是整步、半拍还是更高的细分模式。你给一个STEP脉冲它就前进一个微步输出端的电流按照预设的阶梯曲线逼近正弦波。从系统的角度看这意味着电机运动的粒度由芯片决定MCU只需要关心自己发出的脉冲频率不用关心每一拍里面电流到底是怎么变化的。我做机械臂关节时用1/16细分3200个脉冲转一圈低速平稳性完全够用。如果你对分辨率要求更高可以切换更高的细分代价是同样的运动速度下STEP脉冲频率也要等比提高MCU定时器的负担会增加。2.4 衰减模式不要一直放着默认值电流斩波过程中绕组电流需要泄放路径衰减模式影响的是电流下降的速度。慢衰减时电流下降慢电流纹波小但容易产生电机低频啸叫快衰减时电流下降快动态响应好但发热和噪声会明显上升。DRV8818的DECAY引脚可以切换衰减模式具体支持哪几种组合看数据手册。我的经验是如果电机在某个速度段出现尖锐的啸叫先别急着换电机把衰减模式从快衰减切到混合衰减或者慢衰减试试。很多噪声问题不是机械共振而是电流纹波激励出来的。衰减模式属于那种不调不知道、一调吓一跳的参数调试阶段最好留一个拨码开关或者用MCU引脚去控制。3. 原理图设计要点从DRV8818引脚到STM32F100ZE的每一根线3.1 电源树设计这套方案的电源分两部分电机电源VM和逻辑电源。电机电源我建议直接用稳定的直流母线12V或24V都行前提是电压纹波不要太大。有些工业设备母线是从开关电源出来的纹波几百毫伏对逻辑电路可能没事但步进电机运动时电流变化剧烈母线电压会跟着抖动容易导致斩波电流设定漂移。所以VM引脚旁边至少要有两个去耦电容一个100nF陶瓷电容放在芯片附近滤高频一个47uF到100uF的电解电容放在稍远一点缓冲母线电压的跌落。逻辑电源VDD接3.3V和F100ZE的IO电平匹配。如果你的系统里有其他5V逻辑器件一定要确认DRV8818逻辑引脚的输入阈值范围最好用3.3V单电源这样电平转换的问题最少。这里要特别留意一个坑逻辑地和功率地不要在芯片底下汇合。功率地会流过很大的PWM电流如果逻辑地回路经过这段铜皮MCU的参考地就会抖动严重时STEP脉冲都可能被干扰。我一般会把功率地单独走一层或者一段铜皮然后在电源输入端单点汇合。具体做法可以看芯片数据手册的Layout指南里面画得很清楚。3.2 引脚分配哪里接STEP哪里接DIR我第一次画板子时随手把STEP接到一个JTAG复用脚上结果调试时一接仿真器电机就乱跳浪费了半天。STM32F100ZE的PA13/PA14是SWD调试脚PB3/PB4又跟JTAG复用这些脚能不碰尽量别碰。我最终的引脚分配是这样的STM32F100ZE引脚功能连接对象PA0STEP脉冲输入DRV8818 STEPPC0方向控制DRV8818 DIRPC1驱动使能低有效DRV8818 ENABLEPC2微步进模式选择DRV8818 M1PC3微步进模式选择DRV8818 M2PC4微步进模式选择DRV8818 M3PC5衰减模式选择DRV8818 DECAYPB0故障输入下拉DRV8818 nFAULTPA0既能做定时器PWM输出又能复用为TIM2_CH1用来产生STEP脉冲很顺手。如果你做多轴TIM3、TIM4这些也能干同样的事选引脚时把定时器通道映射先查清楚能省很多事。3.3 采样电阻与电流设定采样电阻的选取直接影响电流控制的精度和发热。电阻要用低电感、低温度系数的合金电阻阻值通常在0.1到0.5欧姆之间功率要按实际电流的平方乘阻值计算。别小看这两个电阻在1A电流下0.2欧姆的采样电阻就要消耗0.2W功率选个0805封装很容易烫得变色。VREF电压如果是从电位器分压出来的注意电位器本身的温漂和调节噪声。批量生产时我建议用精密电阻分压固定不做现场可调样机阶段电位器绝对是好东西方便你扫一遍电流值摸清电机在不同电流下的出力表现和温升情况然后再回过头来定固定阻值。3.4 PowerPAD散热焊盘不能省DRV8818PWPR的PowerPAD焊盘是散热的关键。如果只是把它当成一个普通引脚补上焊锡芯片在大电流下会迅速过温保护然后出现那种时而能转时而不能转的诡异故障。正确做法是PCB底层对应位置开一个大铜皮区域用密集过孔把顶层焊盘与底层铜皮连接起来形成足够大的散热面积。我在一块80mm乘100mm的板子上给每颗DRV8818都配了大约10平方厘米的底层铜皮散热区。实测在24V供电、相电流1.5A、连续运行半小时后芯片壳温稳定在65度左右热保护从来没触发过。如果环境温度更高或者电流更大可以加一小块铝散热片贴在芯片正面。3.5 保险丝和TVS管是工业应用的基本盘工业现场最怕的是电机线被撞断或者电源接反。我在VM输入端加一个自恢复保险丝再接一个TVS管到地能扛住大部分瞬态浪涌。如果设备经常在电磁干扰强的环境里工作DRV8818的nFAULT脚一定要连到MCU的中断输入一旦发生过流、过温MCU要能立刻停止发脉冲而不是等电机冒烟。4. 固件实现用F100ZE生成可靠的STEP脉冲和加减速4.1 定时器初始化STEP脉冲的本质是方波信号频率决定了电机转速。最容易想到的方式是用GPIO翻转加延时但这种方式在中断被其他任务抢占时脉冲间隔会抖电机就会出现一顿一顿的现象。工业应用里我推荐直接用定时器PWM输出。STM32F100ZE的定时器在PWM模式下由硬件自动翻转引脚不需要进中断脉冲频率完全稳定。初始化代码大概是这样void Motor_StepTim_Init(void) { GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tb; TIM_OCInitTypeDef oc; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); gpio.GPIO_Pin GPIO_Pin_0; gpio.GPIO_Mode GPIO_Mode_AF_PP; gpio.GPIO_Speed GPIO_Speed_2MHz; GPIO_Init(GPIOA, gpio); tb.TIM_Period 999; // 初始频率 tb.TIM_Prescaler 24 - 1; // 24MHz分频后1MHz tb.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, tb); oc.TIM_OCMode TIM_OCMode_PWM1; oc.TIM_Pulse 500; // 50%占空比 oc.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM2, oc); TIM_Cmd(TIM2, DISABLE); }这里把TIM2预分频成1MHzARR为999时PWM频率为1kHz对应的就是每秒1000个STEP脉冲。占空比固定50%就好DRV8818检测的是STEP信号边沿不需要特殊占空比但50%能保证高电平和低电平的宽度都足够。4.2 脉冲频率与运动速度的换算关系做运动控制最基础的是把每秒多少个脉冲和机械上走多快对应起来。对于一个1.8度步距角电机整步模式是200步一圈如果用1/16细分就是3200个STEP脉冲一圈。假设你通过一个5mm导程的丝杠驱动滑台移动目标速度是50mm/s那么每秒需要的STEP脉冲频率是脉冲频率 速度 / 导程 × 每圈步数 50 / 5 × 3200 32000个脉冲每秒这个32000Hz就是定时器ARR应该对应的PWM频率。ARR值就是1MHz除以32000约等于31。速度要求越高ARR越小但ARR太小的时候要注意定时器输出在高频下要保证信号上升沿干净GPIO的翻转速度也要够快。F100ZE的GPIO输出速度配置在2MHz档在几十千赫兹的STEP信号下完全够用但如果拉到几百千赫兹就得把GPIO速度档位调高。4.3 梯形加减速别让电机一步到位步进电机的毛病是启动频率过高必丢步停止时频率骤降必过冲。所以任何带负载的步进应用都要做加减速。最经典也最好调的就是梯形加减速速度先线性上升匀速运行然后线性下降停在目标位置。我在F100ZE上用的是定时器中断加变速的方式。每次定时器中断代表发了一个STEP脉冲同时更新下一步的定时器重载值。核心逻辑是维护一个当前速度变量按照加速度值逐步逼近目标速度static int32_t current_speed; // 当前步频 static int32_t target_speed; // 目标步频 static int32_t accel; // 每走一步速度的增量 void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update)) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 步数计数 step_count; // 加减速处理 if (current_speed target_speed) { current_speed accel; if (current_speed target_speed) current_speed target_speed; } else if (current_speed target_speed) { current_speed - accel; if (current_speed target_speed) current_speed target_speed; } // 根据当前速度重新设置ARR uint16_t arr 1000000 / current_speed; TIM_SetAutoreload(TIM2, arr - 1); TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Regular); TIM_SetCounter(TIM2, 0); } }这里每一步都要重新设置ARR逻辑简单缺点是中断频繁。如果到了几千赫兹以上的步频中断开销会比较可观。更高效的做法是利用PWM模式加外部计数让MCU只在速度变化的关键节点介入但调试复杂度也上升。对F100ZE这种主频不高的芯片我的建议是先把中断方案跑通减少复杂度的优先级比极限性能高。4.4 方向切换与使能控制方向引脚DIR的电平状态在STEP脉冲到来时被采样所以最安全的做法是先把DIR设置到位并保持几个微秒再发STEP脉冲。我通常在代码里先写DRV8818的DIR寄存器然后延时2到5微秒再用定时器启动PWM输出。如果反过来STEP和DIR同时变化芯片可能会采样到不确定的方向电机就偶尔多走一步或者少走一步。使能引脚ENABLE低电平有效。电机在不上电运动时最好把ENABLE拉高让驱动芯片输出级关闭电机处于自由状态。这样既能省电也能避免人工盘动机器时被电机的保持力矩拖住。很多机器人关节在调试阶段需要手动对零如果使能逻辑没做好每次对零都要先断电非常痛苦。4.5 微步进模式的运行时切换微步进模式M1/M2/M3引脚在大多数情况下建议上电前就固定好。因为切换微步进模式会导致电流表跳变处理不好容易产生抖动甚至丢步。如果你的应用需要在运行中调整细分我建议设计成停止运动、切换模式、重新校准步数计数的流程。不过反过来讲如果只是固定用一种细分比如我在机械臂上固定用1/16M1/M2/M3直接接固定电平就行不用占用MCU的GPIO。GPIO资源在这种应用里其实很宝贵能省则省。5. 实测中的几个坑失步、啸叫、发热与干扰排查记录5.1 电机绕组接反现象是抖动而不是不转双极步进电机的线序搞错最典型的症状是电机上电后锁死发脉冲时只会来回抖动就是不肯转圈。这是因为两个绕组的磁场方向配合错了电机在每拍里要么被拉向一个方向要么被推到相反位置。排查方法很简单先手动把电机调到一个齿槽对齐的位置然后发固定数量的脉冲每次发完脉冲都看一下电机是否转了预期角度。如果方向不对把A相的两根线交换就行。注意B相的两根线交换和A相交换对转向的影响不同——交换A相会导致电机反转同时交换A相和B相则保持原有转向。这个细节很容易搞混我建议每次改线后都重新做一次转向验证。5.2 失步加速过快和电流不足是两大根源失步是最恼人的问题因为它在运动过程中毫无预警位置偏差直到运动结束才暴露。我在这套方案实验室阶段就遇到过两次比较典型的失步。第一次是空载时梯形加减速的加速度设置过大。电机的输出力矩是有限的尤其在高频段力矩会明显下降如果加速过程要求的力矩超过电机当前转速下的最大力矩转子就会跟不上磁场旋转速度。解决办法是把加速度调小或者提高电流设定值。这里有一个粗线条判断在1/16细分、3200步一圈的情况下24V母线驱动的NEMA 23电机起步频率不高于1000Hz加速到目标频率的斜率不要超过每毫秒200Hz基本能覆盖大多数场景。第二次是负载变大后电机发热明显但程序里的目标速度没变电机在某个速度点附近开始丢步。检查后发现是电流设定偏低电机输出力矩不够。把VREF从1.0V调到1.2V之后问题消失。这是一个经验教训如果你加了负载电机变得容易丢步第一时间不是去调加减速而是确认驱动电流有没有跟着负载重设。5.3 电机啸叫和振动衰减模式与细分之间的权衡低速运行时电机发出明显的啸叫很多时候不是机械问题而是电流斩波频率和电机结构的共振。DRV8818的斩波频率相对固定但你可以修改衰减模式来改变电流纹波的形态。我在用1/8细分、慢衰减模式下电机在60到120rpm区间有明显的振动噪声切到混合衰减后啸叫基本消失电流波形也更干净。当然衰减模式不是万能的如果电机在高细分低速时还抖得厉害可以检查机械安装是否让电机过载或者换更低细分的运行方式试试。5.4 工业现场的干扰STEP脉冲被强电污染把板子装到有变频器、伺服驱动器或者接触器的工业柜里之后偶尔会出现电机突然多走几步或者干脆卡住不响应的情况。用示波器看STEP引脚发现高电平上叠加了不少毛刺有些毛刺的幅度甚至超过了逻辑阈值被DRV8818误识别成了STEP边沿。处理方案有三步第一STEP信号线走线尽量短远离功率线第二在F100ZE的输出引脚和DRV8818的STEP输入之间串联一个100欧姆电阻限制毛刺电流第三在STEP引脚对地加一个100pF的小电容滤除高频毛刺。这样处理后再到同样的工业现场测试干扰问题基本消失。5.5 ISEN探针波形判断电流是否达标的直观方法我在调试时最喜欢看的就是ISEN引脚上的电压波形。这个引脚的电压等于采样电阻上的电流乘以电阻值示波器探头接上去能看到明显的三角波——这就是电流斩波在工作的证据。如果波形包络稳定、纹波幅度正常说明电流环工作正常如果波形宽窄不一甚至断续说明电流设定不稳或者斩波频率受干扰。判断特定电流设定是否正确可以用万用表串联在电机绕组回路里测有效值电流和采样电阻上的峰值电流对应起来。这两个数值对不上那就要检查采样电阻质量或者PCB走线是不是引入了额外电阻。6. 从能转到能用工业/机器人场景的闭环与可靠性扩展6.1 闭环如果丢步是不可接受的开环步进控制在大部分定位场景下够用但机器人关节如果遇到碰撞或者负载突变开环系统根本不知道自己已经错了多少。STM32F100ZE自带正交编码器接口用三个定时器通道就能直接读取增量编码器的AB相输出硬件自动计数CPU只需要读寄存器就能知道电机的实际位置偏差。我的建议是在机械臂这类应用中即使你不打算做高精度的闭环伺服也建议在输出端加一个编码器做软闭环——运行过程中持续比较指令位置和实际位置偏差超过阈值就报警停机。这样可以用很小的成本把开环失步问题转化成可控的异常上报不至于让设备在错误位置上继续工作。6.2 故障保护链路DRV8818的nFAULT引脚会在过流、过温等异常时拉低。这个信号接到F100ZE的外部中断上中断处理函数里要做的第一件事是停止STEP脉冲、锁存故障标志、点亮故障灯而不是第一时间去清除故障源。故障原因排查清楚后手动复位才能恢复运行。如果一检测到故障就自动清除并恢复运动在工业现场可能会造成更严重的二次事故。6.3 多轴联动的同步问题做三轴或四轴设备时各轴的STEP脉冲最好由同一个时基驱动这样才能保证轴与轴之间的运动保持同步。F100ZE有多个通用定时器但它们的时钟源来自同一个APB总线本质上已经共享了时基。更进一步可以用定时器的主从模式让主定时器输出触发信号从定时器同步启动PWM输出这样各轴的启动时刻一致性会更好。如果你不追求严格同步只是顺序执行各轴运动那用一个定时器PWM输出加一个软件状态机调度就行。我在桌面机械臂的初期版本就是这么干的代码简单、逻辑清晰后续需要同步再升级为主从定时器方案。6.4 长期稳定运行的最后一道工序整套方案做完之后别忘了做两件事。一是老化测试让电机在最大连续工作电流和典型循环运动模式下跑48到72小时记录驱动芯片温度和母线电压变化确认没有热累积导致的故障。二是接线端子的锁紧工业应用中振动是常态电机线端子一定要用带防松结构的或者直接点胶固定。这些看起来不起眼但实际售后数据里这类连接性问题占比比芯片故障高得多。最后说一个实际操作中的体会DRV8818PWPR和STM32F100ZE这套组合表面上看是老芯片组合但正因为它们都不需要复杂的驱动配置反而让固件层非常简洁。我后来在别的项目里用过带SPI接口的高端步进驱动功能确实多但调试SPI占用的时间和换来的一点性能提升在普通工业定位场景里未必划算。如果你的设备对步进电机的需求是中低速、中等精度、可靠优先这套脉冲/方向加索引器的方案仍然是很稳妥的选择。一个建议做板子的时候务必把衰减模式和VREF调节做成可调试的哪怕只是焊盘上留几个可选电阻调试阶段能让你省非常多的时间。
返回列表