ARTICLE DETAIL

资讯详情

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

STM32定时器PWM驱动步进电机:TB6600控制实战指南

STM32定时器PWM驱动步进电机:TB6600控制实战指南 1. 方案选型与整体原理1.1 为什么把脉冲交给定时器而不是Delay做嵌入式迟早要碰电机而步进电机配合 TB6600 驱动器是入门性价比很高的一条路线。先别急着写代码你得先搞清楚一个关键问题步进电机本质上是个“脉冲计数器”你给它一个脉冲它就转一个固定角度比如 1.8°脉冲频率决定转速脉冲数量决定转角。所以控制步进电机的核心就是产生一串精确、稳定、数量可控的脉冲信号。很多新手第一反应是在主循环里用 Delay 翻转 GPIO 来产生脉冲while(1) { HAL_GPIO_WritePin(STEP_GPIO_Port, STEP_Pin, GPIO_PIN_SET); delay_us(500); HAL_GPIO_WritePin(STEP_GPIO_Port, STEP_Pin, GPIO_PIN_RESET); delay_us(500); }这种写法有很明显的隐患。第一delay_us本身依赖主频和编译器优化精度有限第二只要中断一进来脉冲时序就被打断电机就会出现肉眼可见的抖动第三CPU 被脉冲生成占死其他逻辑基本没法跑。所以我在实际项目里很少用这种“软件翻转”方式尤其是需要多轴联动、加减速或者高频率输出时。正确做法是把脉冲生成交给硬件定时器。STM32 的定时器自带 PWM 输出功能你只要配好预分频和自动重载值它就能独立输出频率精确的方波完全不占用 CPU 时间。用定时器 PWM 驱动步进电机不仅省心而且稳定这也就是这套方案的核心逻辑。1.2 F103C8T6、TB6600、42电机这套组合怎么分工选 STM32F103C8T6 这颗芯片最大的理由是它便宜、资料多、定时器资源够用。F103C8T6 主频跑到 72MHz内部有 TIM1、TIM2、TIM3、TIM4 四个定时器其中 TIM1 还是高级定时器有互补输出、刹车输入等功能。对步进电机控制来说哪怕只用一个通用定时器输出 PWM也完全绰绰有余。TB6600 是市面上非常常见的步进电机驱动器耐压范围宽常见支持 9-42V最大驱动电流 4A 左右支持 1、2/A、2、4、8、16 细分。它的优势在于外围电路简单给上电源、接好电机、控制端给脉冲就能跑起来。相比用 A4988 或者 DRV8825 这类模块TB6600 的抗干扰能力和驱动电流都强一截特别适合带 42 步进电机或者小型的 57 电机。三个角色的分工是这样的STM32 负责“决策”——输出脉冲频率、脉冲数量、方向信号和使能信号TB6600 负责“放大”——把控制端的脉冲信号隔离后转换成电机绕组需要的电流42 步进电机负责“干活”——把电脉冲变成真实的角位移。你不需要在代码里直接控制电机绕组的导通时序那是 TB6600 内部的事。1.3 控制链路全貌整套系统的控制链路可以用一句话概括STM32 通过定时器 PWM 产生方波接到 TB6600 的 PUL 端方向信号接到 DIR 端使能/脱机信号接到 ENA 端TB6600 输出驱动 42 步进电机。其中PUL 端是核心。它接收的 PWM 频率直接决定电机当前转速PWM 脉冲的累计个数决定电机最终转动角度。DIR 端电平决定正反转通常高电平一个方向低电平另一个方向你可以在软件里随时切换。ENA 端则需要单独说很多 TB6600 模块上 ENA 默认是悬空状态此时电机处于使能锁轴状态一旦 ENA 被拉低驱动器会切断电机电流电机进入脱机自由状态。你如果想让电机保持锁止力就不要随便拉低 ENA。这套链路里最容易出问题的环节有两个一个是 PWM 频率算错导致电机转速和预期对不上另一个是 ENA 接法理解反导致电机“嗡嗡响但不转”。后面我会分别展开讲。2. 硬件接线、拨码与电源2.1 引脚分配表与共阳极接法F103C8T6 上能输出 PWM 的引脚很多比如 PA0TIM2_CH1、PA6TIM3_CH1、PA8TIM1_CH1、PB6TIM4_CH1等。我习惯把脉冲信号放在 PA6也就是 TIM3 的通道 1方向信号放在 PA5使能信号放在 PA4。这三个引脚都是普通 GPIO不涉及 JTAG 复用板子一上电就能直接用。STM32F103C8T6 引脚功能TB6600 端子PA6脉冲输出TIM3_CH1PUL-PA5方向控制GPIODIR-PA4使能控制GPIOENA-3.3V/5V公共正极PUL3.3V/5V公共正极DIR3.3V/5V公共正极ENAGND参考地GND驱动器电源地这里有个很多新手容易踩的坑TB6600 控制信号采用光耦隔离输入常见接法有两种共阳极和共阴极。推荐用共阳极接法把 PUL、DIR、ENA 三个正极统一接到同一个公共正极然后用 STM32 的引脚去控制对应的负极端子。当 PA6 输出低电平时光耦导通驱动器收到一个有效脉冲信号当 PA6 输出高电平时光耦截止没有脉冲。所以这种方式下脉冲信号实际上是“低电平有效”。公共正极到底接 3.3V 还是 5V我试过 TB6600 用 3.3V 逻辑也能工作但为了留足驱动电流余量建议公共正极接 5V。如果你板子上没有独立 5V可以从 USB 的 5V 取或者用外部电源给控制端供电。注意千万不要把公共正极直接接到 24V 电源上再让 STM32 去拉低——F103 普通 IO 引脚耐压不高这样做有烧引脚的风险。如果你非要使用 24V 控制电压必须在中间加三极管或者光耦隔离而不是把 24V 直接怼到单片机 IO 上。2.2 两步确认TB6600的拨码设置TB6600 板子上一般有两个拨码区域一个管细分一个管输出电流。不同厂家丝印不一样有的叫 S1-S3 是细分S4-S6 是电流有的反过来。所以拿到板子第一件事是看丝印不要想当然。以常见的 6 位拨码为例细分部分通常通过 S1、S2、S3 的组合来设置 1、2/A、2、4、8、16、32 细分电流部分通过 S4、S5、S6 设置档位常见范围是 0.5A 到 4A。对 42 步进电机来说额定电流一般在 1.2A 到 1.7A 之间我通常把电流档位设置在 1.5A 到 2A 附近。电流设小了电机力矩不够容易丢步电流设大了电机会发烫。细分方面8 细分是个比较均衡的选择每转脉冲数 200×81600既能让低速运行比整步方式平稳很多又不会让脉冲频率过高对控制器的压力也小。如果你要求更高的位置分辨率可以考虑 16 细分甚至 32 细分但那时同样的转速下脉冲频率要成倍提高对 STM32 来说完全没问题只是接线和软件上要更注意干扰。2.3 电源和电机线的接法TB6600 的电源端子一般标 VCC 和 GND支持电压范围比较宽。我实测过 12V、24V 都能正常工作不过更推荐 24V 电源。原因很简单步进电机在高速阶段主要靠电源电压来克服反电动势电压越高高速时的力矩越足。当然24V 下电机的发热也会更明显如果你做的是低速往复运动12V 也可以接受。电机线这块42 步进电机通常引出四根线A、A-、B、B-对应线圈两组。不同厂家线的颜色不一样常见的是红绿黄蓝四色红色接 A绿色接 A-黄色接 B蓝色接 B-。接线时要注意别把 A 组和 B 组搞混否则电机会出现异响或者无法正常转动。如果接反了一组一般不会烧东西但电机会有“卡顿”或者反转的奇怪表现排查起来很费时间所以接线时一定先对着驱动器端子看仔细。2.4 ENA引脚的正确打开方式关于 ENA网上问“步进电机 ena”的人特别多这里专门说一下。TB6600 的 ENA 端如果悬空驱动器默认输出使能电机处于锁定状态你用手拧电机轴会感觉到明显的阻力。如果你把 ENA 有效电平加上去驱动器会切断输出电流电机轴完全松开也就是脱机状态。在共阳极接法里ENA 接公共正极ENA- 接 STM32 的 PA4。PA4 输出高电平时光耦不导通驱动器保持使能PA4 输出低电平时光耦导通电机脱机。所以如果你想正常运行PA4 要置高或者干脆把 ENA 悬空不接。很多新手把 ENA 接上后又无意中让单片机默认把 PA4 拉低结果电机怎么调都不转然后开始怀疑 PWM 配错了实际上问题就出在脱机信号上。3. 定时器PWM配置与脉冲频率计算3.1 定时器时钟从哪来在配置之前你得先搞清楚 F103 的时钟树。F103C8T6 最高主频 72MHz这个 72MHz 经过 APB1 总线分频后给到 TIM2/TIM3/TIM4/TIM5 等通用定时器。有个容易忽略的细节APB1 外设时钟如果做了 2 分频挂在它上面的定时器时钟会自动恢复到原来的高频。CubeMX 默认配置下APB1 外设时钟是 36MHz但定时器时钟却是 72MHz。这意味着 TIM3 的计数时钟就是 72MHz。如果你在 CubeMX 的时钟树里看到 APB1 显示 36MHz而 TIM3 的时钟显示 72MHz这是正常的不要觉得自己配错了。TIM1 挂在 APB2 上如果 APB2 不分频它的时钟也是 72MHz。统一记住这套方案里定时器计数时钟就是 72MHz。接下来的所有频率计算都基于这个数。3.2 PWM频率、占空比怎么算定时器 PWM 的输出频率取决于两个寄存器预分频器 PSC 和自动重载值 ARR。计算公式是PWM频率 72MHz / ((PSC 1) * (ARR 1))为什么公式里都要加 1因为这俩寄存器都是从 0 开始计数的。PSC 用来把 72MHz 降到一个适合你调整的中间频率ARR 则决定了最终输出周期。我一般把 PSC 设为 71这样计数时钟变成72MHz / (71 1) 1MHz也就是每 1 微秒计数一次好算好记。这时 PWM 频率就简化为PWM频率 1MHz / (ARR 1)举个例子如果 ARR 设置为 999PWM 频率就是 1MHz / 1000 1000Hz也就是每秒输出 1000 个脉冲如果 ARR 设置为 499PWM 频率就是 2000Hz。你在调试时只要关心 ARR 一个参数就能很直观地控制速度。占空比由比较值 CCR 决定。PWM1 模式下计数器从 0 向上计数当计数值小于 CCR 时输出有效电平大于等于 CCR 时输出无效电平。占空比计算公式是占空比 CCR / (ARR 1)对步进电机控制来说占空比不需要太精确你给个 50% 左右就行。所以 CCR 直接取 (ARR 1) / 2。TB6600 的光耦输入只关心脉冲边沿只要高低电平持续时间别太短就可以。我实测下来哪怕占空比偏到 30% 或 70%驱动器也能正常识别。真正要紧的是频率和脉冲个数。3.3 细分数和转速的换算公式步进电机的步距角通常是 1.8°也就是整步状态下每圈要 200 个脉冲。接了 TB6600 并且设置了 N 细分之后每圈的脉冲数就变成每转脉冲数 200 * N转速和 PWM 频率的关系很好推导转速转/秒 PWM频率 / 每转脉冲数 转速转/分 PWM频率 / 每转脉冲数 * 60举个例子假设细分设为 8PWM 输出 2000Hz每转脉冲数 200 * 8 1600 转速 2000 / 1600 * 60 75 RPM也就是说2000Hz 的脉冲频率下电机每分钟转 75 圈。反过来如果你希望电机以 30RPM 转目标 PWM 频率就是PWM频率 30 / 60 * 1600 800Hz然后再拿 800Hz 去反推 ARRARR 1MHz / 800 - 1 1249这个换算过程我建议你在写代码前用计算器算一遍心里有谱后面调试就不慌。3.4 “高级功能”用在哪几个点标题里说的“定时器PWM高级功能”可能有人第一反应是必须用 TIM1、TIM8 这种带刹车和互补输出的高级定时器。其实对普通步进电机控制来说TIM1 的刹车功能并不是必需项。真正让这套方案显得“高级”的是通用定时器本身提供的几个能力第一预分频和自动重载的独立配置。这让你能在一个很宽的频率范围内灵活选择脉冲速率从每秒几个脉冲到每秒几万个脉冲都能做到。第二PWM 模式和输出比较模式。你不需要在主循环里干预定时器硬件会自动输出稳定波形。第三更新中断。每次计数器从 ARR 值溢出回零时会产生一次更新事件。利用这个中断你可以精确统计“已经输出了多少个脉冲”到目标数量后立刻停掉 PWM从而做到定角度运动。第四运行中修改 ARR 实现动态调速。加减速控制不是靠 PWM 模式本身而是利用定时器允许在运行中修改自动重载值这一特性让脉冲频率按你设定的曲线逐步变化。这些能力组合起来才构成了真正实用的步进电机控制方案。用不好这些功能代码也能让电机转但转速和定位都经不起细看。4. CubeMX配置与代码实现4.1 CubeMX里的定时器配置用 CubeMX 配置这套方案很快。时钟部分我建议直接用外部晶振在 Clock Configuration 里把 PLL 倍频到 72MHz。如果你板子上没有外部晶振也可以选 HSI 内部时钟不过精度会差一点对步进电机这种应用其实影响不大。然后是 TIM3 的配置。在 Timers 里选中 TIM3Clock Source 选择 Internal ClockChannel1 选择 PWM Generation CH1。参数部分Prescaler 填 71Counter Period也就是 ARR随便先填一个 999Pulse 填 500。这是最基础的 1kHz、50% 占空比配置。Mode 选择 PWM 1Pulse 填 500 后CH Polarity 选 High 或者 Low 都可以影响的是空闲电平对光耦输入来说差别不大。如果想实现脉冲计数还要在 NVIC Settings 里勾选 TIM3 global interrupt。这样每次定时器溢出时中断回调都会被执行我们就能在里面做脉冲计数。生成代码后记得检查一下main.c里的MX_TIM3_Init实际配置值应该类似下面这样void MX_TIM3_Init(void) { TIM_OC_InitTypeDef sConfigOC {0}; htim3.Instance TIM3; htim3.Init.Prescaler 71; htim3.Init.CounterMode TIM_COUNTERMODE_UP; htim3.Init.Period 999; htim3.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_PWM_Init(htim3); sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 500; sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(htim3, sConfigOC, TIM_CHANNEL_1); }注意 AutoReloadPreload 我建议打开。它的作用是让 ARR 的修改在下一个周期才生效而不是立即生效这样可以避免在运行中修改频率时产生不完整的脉冲。4.2 让定时器输出指定数量的脉冲配置好 PWM 之后如果只是HAL_TIM_PWM_Start(htim3, TIM_CHANNEL_1)那么脉冲会一直输出电机就一直转。实际项目里通常要求“转固定步数”所以需要在更新中断里数脉冲到达目标后停掉 PWM。先定义几个全局变量volatile uint32_t pulse_count 0; volatile uint32_t pulse_target 0; volatile uint8_t motor_busy 0;然后在中断回调里实现计数和停机逻辑。注意这里用的是HAL_TIM_PeriodElapsedCallback也就是更新事件回调void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM3) { if (motor_busy) { pulse_count; if (pulse_count pulse_target) { motor_busy 0; HAL_TIM_PWM_Stop(htim3, TIM_CHANNEL_1); HAL_GPIO_WritePin(ENA_GPIO_Port, ENA_Pin, GPIO_PIN_RESET); } } } }这里有一个容易误解的地方PWM 模式下一个 PWM 周期就是计数器从 0 数到 ARR 再溢出回 0 的过程所以一次更新事件正好对应一个完整的脉冲周期。如果你把 CCR 设为 50% 占空比那么输出波形上确实是一个一个的方波每次溢出就是一个脉冲的结束所以用更新中断去计数是完全准确的。启动函数可以这么写void motor_run(uint32_t steps, uint8_t dir, uint32_t freq_hz) { uint32_t arr; if (motor_busy) return; // PSC 71 时计数时钟为 1MHz arr (1000000 / freq_hz) - 1; __HAL_TIM_SET_AUTORELOAD(htim3, arr); __HAL_TIM_SET_COMPARE(htim3, TIM_CHANNEL_1, (arr 1) / 2); // 设置方向 HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, dir ? GPIO_PIN_SET : GPIO_PIN_RESET); // 使能驱动器 HAL_GPIO_WritePin(ENA_GPIO_Port, ENA_Pin, GPIO_PIN_SET); pulse_count 0; pulse_target steps; motor_busy 1; HAL_TIM_PWM_Start(htim3, TIM_CHANNEL_1); }调用方式很简单比如让电机以 800Hz 频率走 1600 个脉冲8 细分下正好一圈motor_run(1600, 1, 800);4.3 动态调速与简易梯形加减速直接让电机从 0 状态瞬间进入高频运行容易丢步。解决思路是做一个简单的梯形加减速启动时 PWM 频率低一些然后逐步提高接近目标步数时再逐步降低。F103 的定时器允许在运行中修改 ARR修改的生效点由AutoReloadPreload决定。我推荐打开 AutoReloadPreload这样每次修改 ARR都要到下一个更新事件才会真正改变周期不会出现半截脉冲。加减速的最终实现方法很多有查表法、定时器级联法、S 曲线规划等。对简单的 F103C8T6 应用来说我在更新中断里做一个线性加速// 加速过程参数 volatile uint32_t current_arr; volatile uint32_t target_arr; volatile uint32_t accel_step_arr; volatile uint8_t accel_mode 0; volatile uint8_t decel_mode 0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM3) { if (accel_mode) { // 每来一次中断ARR 减小一档也就是频率升高一档 if (current_arr target_arr) { current_arr - 1; __HAL_TIM_SET_AUTORELOAD(htim3, current_arr); __HAL_TIM_SET_COMPARE(htim3, TIM_CHANNEL_1, (current_arr 1) / 2); } else { accel_mode 0; } } if (motor_busy) { pulse_count; if (pulse_count pulse_target) { motor_busy 0; HAL_TIM_PWM_Stop(htim3, TIM_CHANNEL_1); } } } }这个例子是每 1 个更新事件就修改一次 ARR。如果你的频率从 500Hz 加速到 2000Hz那么 ARR 会从 1999 一路减到 499一共需要 1500 次中断加速过程中总脉冲数就有几千个。实际项目里你可以根据需要的加速时间调整“每隔多少次中断修改一次 ARR”并且加上减速逻辑。这里不展开写完整控制算法核心思路你已经掌握了通过动态修改 ARR让脉冲频率沿设定曲线变化电机就能平稳加速和减速。4.4 实测一次完整运行我用这套配置实测过一个典型的 42 步进电机设置 8 细分电源 24VTB6600 电流档位 2A。CubeMX 里 PSC71启动时 ARR1999约 500Hz目标频率 ARR4992000Hz最后让电机走 3200 个脉冲也就是正好 2 圈。实测结果很稳定起步没有抖动运行过程没有明显啸叫停下来后位置也很准。如果不用加减速直接把 PWM 频率给到 2000Hz 再启动电机会有轻微“咯噔”一下这是因为瞬时频率太高转子跟不上脉冲序列。所以只要你不是做极低速的点动建议尽量加一点加减速处理哪怕只是最简单的线性渐变效果都能好很多。5. 常见问题与排查实录5.1 电机嗡嗡叫却不转这是步进电机控制里最常见的问题也是最让人头疼的问题。现象就是电机有电流声也有锁轴力但就是不动或者只在原地震颤。优先排查三个地方。第一检查脉冲信号是否真的进了 TB6600。用逻辑分析仪或者示波器看 PA6 有没有波形如果没有波形检查定时器有没有启动、PWM 通道有没有选对。第二检查公共正极和负极端子是否接反。共阳极接法下PUL 必须接公共正极PUL- 必须接 STM32如果你把 PUL 接到了 GND脉冲极性就反了光耦没法正常触发。第三检查 ENA 状态。如果 ENA 脚被意外拉低驱动器处于脱机状态电机虽然锁轴但有气无力怎么给脉冲都不会正常转动。把 ENA 悬空或者置高再试一次能排除 90% 的问题。还有一个容易被忽略的点如果 A 相和 B 相接反了电机也会出现“想转但转不动”的情况。把 A、A-、B、B- 的线重新对一遍问题通常能解决。5.2 启动丢步和过冲丢步的典型表现是电机走完指令后停止位置不对或者运行中途有明显的“咔咔”声。最常见的两个原因一是启动频率太高二是电流设置不够。解决启动丢步最直接的办法是加加减速。从低速慢慢加到位让转子有足够时间跟上脉冲序列。我实测过频率从 0 直接加到 5000Hz42 电机基本必丢步但如果从 300Hz 起步用 200 个脉冲加速到 5000Hz运行就比较可靠。电流方面TB6600 的电流拨码如果设得太低高速时扭矩不足也会丢步。42 电机一般建议设到额定电流附近不要为了省电而把电流压得太低。另外如果你的目标转速很高优先提高电源电压而不是一味提高电流档位24V 比 12V 在高频段优势明显。5.3 TB6600发热烫手TB6600 在工作时本来就会发热芯片表面烫手并不算异常但如果温度高到人手不能长时间握持那就要注意了。先检查电流档位是不是设太高了。有人为了让电机“力气大”直接设到 4A结果电机和驱动器双双过热。42 电机额定 1.5A 左右设到 2A 已经是上限。其次检查细分设置。相同电流下细分越高绕组电流波形越细腻电机运行更平滑但驱动器损耗也会大一点。还有电机长时间静止锁定时的发热可以通过在软件里让 ENA 脱机来缓解或者选择支持“半流锁定”的驱动器。如果你确认电流和电压都合适还是烫得离谱检查一下 TB6600 的散热片是不是贴得牢有的模块出厂散热片只是卡在上面可以自己加一点导热硅脂。5.4 运行中单片机复位或脉冲错乱这个现象在电机功率稍大时特别明显根源通常是电磁干扰。电机线里流过的是变化很快的电流如果信号线和电机线平行走线脉冲信号很容易被干扰。轻则丢脉冲重则整个单片机复位重启。解决办法有几个方向控制信号线用双绞线或者屏蔽线而且尽量远离电机电源线TB6600 的电机电源线尽量粗一些让电流环路面积尽量小STM32 的电源引脚附近加 100nF 退耦电容如果电机电源和单片机共用一个电源建议用隔离 DC-DC 给单片机单独供电或者在两者之间加共模电感。还有一个容易被忽略的点STM32 的 BOOT0 引脚不要悬空否则恶劣干扰下可能出现奇怪的启动模式。5.5 排查工具与最终检查清单排查电机问题时我每次都按这个顺序来先看电源TB6600 电源指示灯亮不亮电压是不是正常再看驱动状态电机轴有没有锁轴力手能不能拧动然后用示波器或逻辑分析仪测控制端波形PUL 端有没有连续的方波频率和预期是否一致最后再检查 DIR 和 ENA 电平是不是符合预期。这套顺序基本上能快速定位 80% 的问题。如果你手里没有示波器可以用一个小灯泡串电阻接在 PUL- 上电机转的时候灯泡应该持续闪烁不转的时候要么没波要么频率太低肉眼看不出来。写在最后一点经验这套 F103C8T6 TB6600 42 电机的组合我前后做过好几个版本从最早用 Delay 翻转 GPIO到后来全部改成定时器 PWM 加更新中断计数最大的感受是步进电机控制看着简单真正决定成败的往往不是代码而是脉冲的稳定性和现场的抗干扰处理。你花十分钟把接线理清楚、把频率计算公式写在纸上能省下后面一整天的排查时间。另外我强烈建议你在调试阶段给系统加一个简单的逻辑分析仪不用太贵几十块钱的就行。把 PUL、DIR、ENA 三路信号同时抓下来看启动加速、减速停止的整个过程一目了然。很多时候电机抖动不是因为代码逻辑错而是加减速曲线上某个点的频率跳变太剧烈。这种问题眼睛看不到但波形上一眼就能看出来。如果你准备往运动控制方向继续深入下一步可以试试在这套方案上扩展出闭环位置控制加一个编码器反馈用 STM32 的定时器输入捕获功能实时读取电机位置再配合 PWM 输出做 PID 修正。思路和今天这套基础方案是一样的但复杂度会高一档。先把手里的脉冲控制研究明白再往闭环走路会顺很多。
返回列表