简介:面向嵌入式工程师、硬件爱好者与学生的航顺HK32F030C8T6步进电机控制板完整设计资料,硬件采用40×40mm双层板布局,覆盖主控、TB67H450驱动、MT6816编码器与TLP2168光耦隔离电路,可用于步进电机驱动、编码器反馈及控制算法学习与二次开发。压缩包共642个文件,容量29.01MB,包括C语言源码、头文件、汇编启动文件、Keil工程配置(.uvprojx/.uvoptx)、原理图(.schdoc)、PCB(.pcbdoc)、BOM清单及hex烧写文件等,从电路设计到软件工程均有完整呈现。板载两颗最高3.5A的TB67H450驱动芯片,配合MT6816实现小于0.08度的控制精度,支持4/8/16/32倍电子齿轮自由设置,12-30V宽电压输入可适配42/57步进电机。目前已有1281人学习,资料内还包含软件例程源码、编译中间文件与调试配置,可直接用于参考设计、代码移植或开发排错,是一份完整的步进电机控制方案参考资料。
1. 这组“HK32F030C8T6+TB67H450+MT6816”组合为什么值得照抄
前阵子做一款机器人关节用的闭环步进控制器,原本选型是STM32F030C8T6加两颗A4988,结果一算成本超预算两倍,而且编码器走增量式ABZ,上电必须找零位。后来换成航顺HK32F030C8T6做主控,TB67H450做电机驱动,MT6816做磁性角度传感器,整套方案在硬件和软件上都接近“低成本闭环步进”的最终形态。这个方案能解决的实际问题很具体:普通开环步进丢步后无法察觉,而MT6816是14位绝对角度编码器,上电即可得到电机轴绝对角度,配合HK32的定时器输出两路PWM控制TB67H450,就能构成低成本的位置环。适合做3D打印机挤出机、云台、小型AGV舵轮这类对成本敏感又要一定闭环精度的设备的工程师,也适合想把“国产MCU+独立驱动+磁编码器”这套架构吃透的嵌入式开发者。
整个链路里最容易被低估的是HK32F030C8T6和STM32F030之间的寄存器级差异,以及TB67H450的电流斩波设置方式。网上很多例程直接把STM32的HAL库拿来编译,结果定时器重映射引脚不对、ADC采样值偏大,问题都出在细节。下面按原理图、PCB、软件例程源码这条线拆开讲,重点写清楚哪里能平移、哪里必须重写。
2. HK32F030C8T6最小系统与TB67H450驱动电路原理图设计要点
2.1 HK32F030C8T6与STM32F030C8T6的引脚差异和最小系统
HK32F030C8T6是LQFP48封装,引脚排列大体兼容STM32F030C8T6,所以大部分情况下可以直接替换PCB板。但有两处不能简单照抄:一是NRST引脚上拉电容和复位电路的时序参数不同,航顺官方建议复位电容用100nF,有些STM32板卡习惯用1uF,换成HK32后偶尔出现上电复位不彻底;二是PA9/PA10、PB6/PB7这些引脚的复用功能分配有差异,尤其是I2C1和USART1的映射,需要仔细查HK32F030C8T6的数据手册里AFIO复用表。
最小系统的设计我一般这么做:VDDA和VSSA之间串一个10uH磁珠,再加1uF和0.1uF去耦电容,这是国产MCU ADC精度不翻车的常见做法。晶振用8MHz无源晶振,两个22pF负载电容,配合芯片内部的PLL倍频到72MHz。BOOT0接10kΩ下拉电阻到地,避免意外进入Bootloader。烧录口保留SWD四针:SWDIO、SWCLK、GND、3V3,注意HK32F030C8T6的SWDIO和SWCLK默认复用PA13、PA14,和STM32一致。
电源方案上,我建议用一颗LDO把5V降到3.3V给MCU和逻辑电路,LDO前面再加一个SS14二极管防反接。不要用DC-DC给MCU供电,因为TB67H450的PWM斩波噪声会通过DC-DC反馈到模拟电源上,影响MT6816的角度读取稳定性。下面是一段HK32F030C8T6的GPIO和定时器初始化代码,可以看到和STM32标准库非常接近:
// 基于航顺HK32F030C8T6标准库,PB0/PB1输出PWM给TB67H450 #include "hk32f030m_pwm.h" void MotorPwm_Init(void) { GPIO_InitTypeDef gpioInit; TIM_OCInitTypeDef ocInit; TIM_TimeBaseInitTypeDef tbInit; // 使能GPIOB和TIM3时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 复用推挽输出 gpioInit.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; gpioInit.GPIO_Mode = GPIO_Mode_AF_PP; gpioInit.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpioInit); // 72MHz / (71 + 1) / (999 + 1) = 720kHz PWM频率 tbInit.TIM_Period = 999; tbInit.TIM_Prescaler = 71; tbInit.TIM_CounterMode = TIM_CounterMode_Up; tbInit.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3, &tbInit); // PWM模式1,输出比较1、2,初始占空比0 ocInit.TIM_OCMode = TIM_OCMode_PWM1; ocInit.TIM_OutputState = TIM_OutputState_Enable; ocInit.TIM_Pulse = 0; ocInit.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &ocInit); TIM_OC2Init(TIM3, &ocInit); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE); } void Motor_SetDuty(uint8_t ch, uint16_t duty) { if (ch == 1) TIM_SetCompare1(TIM3, duty); else if (ch == 2) TIM_SetCompare2(TIM3, duty); }这段代码里,RCC_APB2Periph_GPIOB和RCC_APB1Periph_TIM3的宏名与STM32F0标准库完全一致,但需要注意HK32库的启动文件里默认开启的时钟源是HSI而不是HSE,如果你在SystemInit里没配置PLL,TIM3的时钟频率可能不是预期的72MHz。排查方法很简单:用Keil调试窗口读SystemCoreClock变量,如果显示8MHz,说明时钟树没切到PLL。
2.2 TB67H450的外围电路和电流斩波设置
TB67H450是一款双全桥电机驱动器,既能驱动一路有刷直流电机,也能桥接成一路步进电机,控制接口是独立的IN1/IN2和PWM1/PWM2,或者用PWM/EN模式。在这个方案里,我使用两路PWM直接控制一个绕组的正反向,另一相类似。驱动器的逻辑供电是3.3V,和HK32F030C8T6共用一个电源域,省去电平转换电路,这是选这颗芯片的一个重要原因。
电流斩波阈值是步进电机控制板最需要调好的一项。TB67H450在外围只需要一个VREF引脚的分压电阻网络和一个VM引脚的大电容,不需要外置采样电阻。斩波电流和VREF的关系在数据手册里给出固定公式,但实际芯片批次差异会带来约±10%的偏差。我一般的做法是先按手册公式算出理论VREF,再用示波器电流探头或采样电阻实测相电流,最后微调VREF分压电阻。
例如,目标是1.2A峰值相电流,手册公式算下来VREF是0.6V,那我会在VREF引脚用10kΩ电位器分压3.3V得到0.6V,并串联一个1kΩ电阻限制电流。同时VM引脚一定加一个100uF电解电容和0.1uF陶瓷电容组合,电容靠近VM引脚放置,否则高速PWM时电压尖峰容易触发VM欠压保护,电机表现为“咯噔”抖动。
TB67H450还有两个关键引脚:TOFF和MODE。TOFF引脚决定固定关断时间,常见做法是接一个47kΩ电阻到地,对应约20us关断时间;MODE引脚选择衰减模式,走步进模式时建议选混合衰减,可以通过串联一个电阻到3.3V来配置。下面是完整的引脚连接参考表:
| 功能 | HK32F030C8T6引脚 | TB67H450引脚 | 参数说明 |
|---|---|---|---|
| PWM_A+ | PB0 (TIM3_CH1) | IN1 | 电机A相正向PWM,20kHz |
| PWM_A- | PB1 (TIM3_CH2) | IN2 | 电机A相反向PWM |
| PWM_B+ | PA6 (TIM1_CH1) | IN3 | 电机B相正向PWM,20kHz |
| PWM_B- | PA7 (TIM1_CH2) | IN4 | 电机B相反向PWM |
| VREF | 3.3V经分压电阻 | VREF | 斩波电流阈值,0.2~2.5V |
| TOFF | 47kΩ到地 | TOFF | 固定关断时间约20us |
| MODE | 10kΩ到3.3V | MODE | 混合衰减模式 |
| 故障输出 | PA4 (外部中断) | MO | 低电平表示过流/过热 |
这里要特别强调,TIM1是高级定时器,输出PWM前必须调用TIM_CtrlPWMOutputs(TIM1, ENABLE),这是和TIM3最大的区别。很多从STM32F0转过来的例程没有这一句,结果PA6和PA7一直输出低电平,电机毫无反应。
2.3 功率电源和逻辑电源的处理顺序
整套板子的电源树建议采用“单点接地”方式:24V输入经过防反接和保险丝后,直接给TB67H450的VM引脚,同时经过一个DC-DC降压到5V,再经LDO到3.3V。DC-DC的开关节点铜皮要远离HK32F030C8T6的晶振引脚,避免耦合噪声导致系统随机重启。
MDI引脚在原理图里容易被漏掉。TB67H450的MDI是空脚,数据手册要求必须接地,不能悬空。上板后如果电机电流明显小于设置值,第一件应检查的事就是MDI是否接地。另一个高频错误是VM和VCC接反,VM是电机电源,通常24V,VCC是逻辑电源,3.3V,两者接反会直接烧毁芯片内部稳压器。我习惯在原理图里把这两类网络用不同颜色标注,并加文字说明“VM=24V”“VCC=3.3V”。
原理图设计完成后,建议把这几个参数输入到AD设计(Altium Designer)的编译检查规则里:所有TB67H450电源引脚附近的去耦电容必须小于5mm走线;VM网络的铜皮最小宽度为1.5mm;MDI网络必须连接到GND网络。AD的“Net Class”功能可以快速检查这些约束,我在实际项目里就把VM、GND、3V3三个网络设为不同的Net Class,每个Class单独设置线宽规则,这样画PCB时不容易出现细线过大电流的情况。
3. MT6816磁性编码器接口与角度解算从SPI时序到软件例程源码
3.1 MT6816的SPI输出格式和硬件连接
MT6816是MagnTek推出的14位磁性角度传感器,内部集成了霍尔阵列和CORDIC算法,直接输出0°~360°的绝对角度,分辨率约0.02°。它支持SPI、I2C和PWM输出,在步进电机控制板的典型接法是SPI从机模式,只需挂到HK32F030C8T6的SPI1上。MT6816放在电机轴的磁铁正下方,气隙建议控制在0.5mm~1.5mm之间,装配时要用非磁性螺钉固定PCB,否则磁铁被螺钉分流后角度非线性会明显变大。
SPI模式下MT6816的关键时序是命令帧和数据帧长度。常见的读取方式是主机发送0x0000命令,从机返回两个字节数据,其中高14位是角度值,低2位是状态和校验位。下面是具体的SPI连接和角度读取代码:
// 基于HK32F030C8T6的SPI1读取MT6816角度 #include "hk32f030m_spi.h" #include "hk32f030m_gpio.h" #define MT6816_CS_GPIO GPIOA #define MT6816_CS_PIN GPIO_Pin_3 void MT6816_SPI_Init(void) { GPIO_InitTypeDef gpioInit; SPI_InitTypeDef spiInit; // PA1=SCK, PA2=MISO, PA3=CS, PA4=MOSI(未用到) RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE); gpioInit.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; gpioInit.GPIO_Mode = GPIO_Mode_AF_PP; gpioInit.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpioInit); gpioInit.GPIO_Pin = MT6816_CS_PIN; gpioInit.GPIO_Mode = GPIO_Mode_Out_PP; gpioInit.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(MT6816_CS_GPIO, &gpioInit); GPIO_SetBits(MT6816_CS_GPIO, MT6816_CS_PIN); // 1MHz SPI,模式0,MSB先行 spiInit.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spiInit.SPI_Mode = SPI_Mode_Master; spiInit.SPI_DataSize = SPI_DataSize_8b; spiInit.SPI_CPOL = SPI_CPOL_Low; spiInit.SPI_CPHA = SPI_CPHA_1Edge; spiInit.SPI_NSS = SPI_NSS_Soft; spiInit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_72; spiInit.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &spiInit); SPI_Cmd(SPI1, ENABLE); } uint16_t MT6816_ReadRawAngle(void) { uint16_t raw = 0; uint8_t hi, lo; GPIO_ResetBits(MT6816_CS_GPIO, MT6816_CS_PIN); // 发送两个字节的0x00命令,同时接收角度数据 SPI_SendData8(SPI1, 0x00); while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET); while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET); hi = SPI_ReceiveData8(SPI1); SPI_SendData8(SPI1, 0x00); while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET); while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET); lo = SPI_ReceiveData8(SPI1); GPIO_SetBits(MT6816_CS_GPIO, MT6816_CS_PIN); raw = ((uint16_t)hi << 8) | lo; // 高14位是角度数据,低2位丢弃 return (raw >> 2) & 0x3FFF; }这段代码有几个细节需要注意。MT6816的SPI速率不需要很高,1MHz足够,因为角度更新率只有几百Hz,提高速率反而容易受电机PWM噪声干扰。注意SPI_SendData8和SPI_ReceiveData8之间的标志位等待顺序,HK32的SPI底层库和STM32F0标准库行为一致,都是先查TXE再查RXNE。如果读回来的数据总是在某几个固定值附近跳变,多半是CS拉低后SCK相位不对,可以把SPI_CPHA改为SPI_CPHA_2Edge再试。
3.2 角度零位校准和方向统一
绝对角度编码器的原始值不能直接用于电机控制,因为安装磁铁时不可能保证0度点与电机A相零位完全对齐。上电后需要做一次零位校准,常见做法是让电机跑一个完整的电气360度开环动作,采集不同位置的角度值,再计算偏移量。更简单的做法是手动把电机轴转到机械零位,读取当前MT6816角度值,保存为offset。当板卡没有外部Flash时,可以把这个offset写到HK32F030C8T6的Flash末页,上电启动时读取。
角度方向也需要统一。步进电机正转时,MT6816角度值可能递增也可能递减,根据磁铁安装决定。统一方向的做法是读取后判断方向标志,如果反向则用0x3FFF - raw得到修正值。完整的角度解算函数如下:
typedef struct { int32_t raw_offset; // 零位偏移量 uint8_t dir; // 0正向,1反向 uint16_t last_angle; // 上次角度,用于多圈计数 int32_t angle_deg; // 输出角度,单位0.1度,范围-1800~1800 int32_t turns; // 累计圈数 } MT6816_t; int32_t MT6816_GetAngleDeg(MT6816_t *enc) { uint16_t raw = MT6816_ReadRawAngle(); uint16_t adjusted; if (enc->dir == 0) { adjusted = (raw + enc->raw_offset) & 0x3FFF; } else { adjusted = (0x3FFF - raw + enc->raw_offset) & 0x3FFF; } // 多圈连续计数,注意跨0度点的跳变 int16_t delta = (int16_t)(adjusted - enc->last_angle); if (delta > 8192) { enc->turns--; // 超过半圈,认为是负向跨越 } else if (delta < -8192) { enc->turns++; // 低于负半圈,认为是正向跨越 } enc->last_angle = adjusted; int32_t total = (int32_t)enc->turns * 16384 + adjusted; return (total * 3600) / 16384; // 输出0.1度 }这里每次跨0度点都可能出现跳变,因为角度值从16383变到0,差值接近-16383,int16_t能正确表示这个负数,所以判断阈值选8192能有效区分正常运动和大跳变。如果不用多圈计数,位置环在连续旋转超过一圈后会出现角度跳变,失步检测也没法做。在实际项目中,我会在每次读取后顺便检查返回的状态位,如果传感器自检出错,直接置一个encoder_fault标志,让控制逻辑立即停止PWM输出。
3.3 软件例程源码里的控制循环结构
完整软件例程源码通常包含三个层次:底层硬件抽象、电机驱动中间层、应用控制层。底层就是上面这些GPIO、SPI、TIM初始化函数;中间层把“角度值”转换成“位置偏差”,应用层再根据偏差计算PWM占空比。一个典型的闭环控制循环如下:
// 位置环控制循环,1kHz周期调用 void Motor_ControlLoop(void) { int32_t current_angle = MT6816_GetAngleDeg(&encoder); int32_t error = target_position - current_angle; // 简单的P控制器,输出限幅为±500 int32_t duty = (error * kp) / 100; if (duty > 500) duty = 500; if (duty < -500) duty = -500; if (duty >= 0) { Motor_SetDuty(1, duty); Motor_SetDuty(2, 0); } else { Motor_SetDuty(1, 0); Motor_SetDuty(2, -duty); } }控制循环的周期用SysTick实现,1kHz中断里刷新占空比。对于步进电机,PWM频率我习惯设在20kHz左右,超出人耳听觉范围。这个循环里的kp是角度差乘以比例系数,比如目标角度和当前角度相差100度(1000个0.1度),kp取2,那么输出占空比是20%,对应电流约0.24A,具体值需要根据电机扭矩系数标定。注意步进电机的矩频特性,PWM占空比和电机扭矩不完全线性,所以位置环后面必须加电流限制,也就是TB67H450的VREF阈值,否则堵转时占空比直接被拉满,芯片温度快速上升。
4. AD设计里的PCB布局与DRC步进电机控制板的主要矛盾
4.1 大电流和敏感信号的物理隔离
PCB设计上,这套控制板的核心矛盾是电机大电流噪声和MT6816微小信号之间的隔离。AD设计(Altium Designer)里我习惯用禁止布线层画一条物理隔离带,把板子分成功率区和逻辑区。功率区包含TB67H450、VM大电容、电机接线端子;逻辑区包含HK32F030C8T6、晶振、MT6816、SWD座。隔离带下方不能有任何走线,如果单面板空间紧张,至少保证MT6816和其他敏感走线在顶层时,底层整块铺地平面,电机走线在顶层短而宽地绕过。
TB67H450的散热焊盘必须打矩阵过孔到底层铺铜,过孔规格0.4mm,间距0.8mm,数量不少于12个。这个散热焊盘同时作为散热和电流回路的一部分,如果过孔不足,满电流运行时芯片温度能到90°C以上,过温保护频繁触发。在AD的Thermal Relief设置里,给焊盘连接铺铜方式选择Direct Connect,而不是菊花瓣连接,否则大电流过孔会被热焊盘缩小电流承载能力。
地平面分割是另一个关键决策。我的做法是不分割地平面,所有GND统一为一个完整铺铜,功率地和逻辑地通过在地平面上的单点过孔相连。因为TB67H450的电流是PWM斩波,分割地平面会造成回流电流绕路,形成更大的电流环路,产生差模辐射。MT6816的GND引脚直接就近打过孔落到底层地平面,不需要单独隔离地。这样在AD的DRC检查里只需增加一条规则:禁止在隔离带区域放置任何铜皮。
4.2 线宽、过孔和滤波参数的量化建议
下表是我在AD设计里实际使用的线宽和过孔规则,可以写到板厂的制板说明里:
| 信号/电源网络 | 最小线宽 | 推荐线宽 | 过孔/电流能力 |
|---|---|---|---|
| VM (24V电机电源) | 1.5mm | 2.0mm | 4个0.6mm过孔/2A |
| GND (功率回路) | 1.5mm | 2.0mm | 铺铜连续回流 |
| 3V3 (逻辑电源) | 0.3mm | 0.5mm | 1个0.4mm过孔 |
| PWM信号 | 0.2mm | 0.3mm | 并联33Ω电阻 |
| MT6816 SPI | 0.2mm | 0.3mm | 串联22Ω电阻 |
PWM信号线上串联33Ω电阻可以抑制振铃,减少对MT6816的数字噪声耦合。MT6816的SCK和MISO线尽量等长,走线长度控制在10mm以内,并且远离VM和电机A/B两相输出线,至少在平面距离上保持5mm以上。如果PCB尺寸允许,在MT6816的电源脚再加一个10uF钽电容和一个0.1uF陶瓷电容,形成π型滤波,能有效降低电机大电流时电源上的毛刺。
4.3 与TB67H450相关的DRC规则和布局检查清单
在AD的Design Rules里,我一般配置三类规则来兜底。第一类线宽规则,Net Class对应表;第二类间距规则,设置VM网络与其他网络间距不小于1.2mm,因为VM上最高电压是30V,虽然不算强电,但电机堵转时反电动势叠加会把VM电压拉到接近35V,间距太小容易击穿;第三类是过孔规则,禁止在HK32F030C8T6晶振下方和MT6816下方打地过孔,避免引入噪声。
布局顺序上,先放TB67H450然后以它为中心展开。TB67H450的VM引脚旁放100uF电解电容和0.1uF陶瓷电容,电解电容负责低频储能,陶瓷电容负责高频噪声。然后放HK32F030C8T6,晶振尽量靠近MCU晶振引脚。最后放MT6816时要注意,MT6816是贴片封装,底部中心有焊盘,需要把传感器小板和主控板用排针连接,或者作为独立模块放置时,MT6816下方不要走电机A/B相线。在AD里可以给MT6816的Room Definition区域设置禁止布线,保证这块区域只有信号线。
5. 联调技巧用示波器和串口验证角度环的边沿参数
5.1 先看PWM和相电流波形
板卡焊接完成后,先用示波器量HK32F030C8T6的PB0/PB1引脚,确认PWM波形存在,频率是设定值。此时TB67H450的VM先不接24V,只接3.3V逻辑电源,观察驱动器输出引脚是否有电压,正常应为0V。接上24V后,再量TB67H450的OUT1和OUT2对GND波形。空载下两个输出应互为反相,占空比等于HK32输出的占空比。如果输出端始终为高而不翻转,检查MODE引脚的配置电阻;如果输出有缺失窄脉冲,检查TOFF电阻值是否过大。
相电流波形需要串入一个小阻值采样电阻或者用电流探头。我一般是把示波器探头套在电机的某根引线上,观察电流波形是否符合“梯形”或“正弦”形状。如果电流波形出现严重的毛刺,说明PCB上的VM去耦电容不够;如果电流上升沿很缓,说明VREF设置过低或电机电感太大。这里要记下一个关键边沿参数:闭环位置环的PWM周期一般是50us(20kHz),超过这个时间后若电流还未上升到目标值,说明VREF不够或CS电流检测异常。
5.2 用串口打印角度值验证MT6816
先跑一个最简单的例程:只开MT6816 SPI读取,电机关闭。用串口工具打印原始角度值和换算后的0.1度值,手动转电机轴,观察数据是否连续变化。如果数据从16383跳到0,这是正常的,配合多圈处理函数就没问题;如果数据卡在某个范围或跳变无规律,先用示波器看SPI时序,重点检查CS低电平时SCK是否有漏脉冲,以及MISO上是否有反射振铃。
确认角度数据稳定后,可以切换到闭环模式。把目标角度设为当前角度,然后人为拉住电机轴,观察串口打印的角度误差。再把目标角度设为当前加360度(即0.1度单位下加3600),电机应自动走到目标位置停止,停止后角度误差在±3个LSB以内。如果电机振荡,减小位置环kp;如果电机缓慢爬行且最终停不准,增大kp并检查是不是MT6816的角度读取速率太低,导致控制周期内误差变化过快。
5.3 失步检测的最终验证方法
整套控制板的终极验证是做堵转失步测试。用上位机发送一个较大的位置阶跃,在电机运动途中用手堵住电机轴,串口监控当前角度和目标角度的误差。如果失步发生后误差超过设定阈值(例如20度),程序应触发错误状态,立即禁用TIM1的PWM输出,并点亮故障LED。这一步能证明MT6816作为绝对角度编码器的价值:它不仅能做闭环,还能在开环模式下起到“状态观测”的作用。
联调时最值得调的一组参数是VREF和TOFF。VREF决定最大电流,TOFF决定斩波频率,两者联合影响电机运行时的发热和噪声。我的最终验证标准是:位置命令为连续正弦运动,频率2Hz,幅值180度,电机连续运行30分钟,TB67H450表面温度不超过70°C,MT6816角度数据无丢失,串口打印的误差均方根小于0.5度。满足这个标准后,这套硬件和软件例程源码就算达到可交付状态了。
本文还有配套的精品资源,点击获取