STM32直流电机PID调速实战:从硬件架构到参数整定全解析

发布时间:2026/9/3 6:27:19
STM32直流电机PID调速实战:从硬件架构到参数整定全解析 简介本资源是一套基于STM32F103C8T6芯片实现直流有刷电机闭环PID调速的完整嵌入式开发工程面向嵌入式初学者、电机控制实践者及自动化专业学生解决直流电机精准稳速控制这一典型控制工程问题。压缩包共220个文件含38个C源码含定时器、ADC、USART等外设驱动与PID核心算法、44个头文件h、39个编译中间文件o/d及调试配置、链接脚本、Hex/AXF可执行镜像等全面覆盖从底层硬件初始化、编码器测速、PWM驱动到PID参数整定的全流程代码支撑包体仅742KB轻量易部署。已有2988人学习下载资源结构清晰含Keil工程配置uvprojx/uvoptx、批处理脚本bat及调试配置dbgconf便于快速编译烧录与参数在线调整是掌握STM32电机闭环控制原理与工程落地的高实用性参考范例。1. 项目概述从压缩包到可运行的直流电机PID调速系统拿到一个名为“stm32f1直流PID调速.7z”的压缩包对于嵌入式开发者尤其是刚接触电机控制的朋友来说这通常意味着一个宝藏。它大概率是一个基于STM32F1系列微控制器的完整项目工程核心目标是实现对直流有刷或直流无刷BLDC电机的转速进行精确的PID闭环控制。这个标题虽然简短但背后涵盖了一个非常经典且实用的嵌入式控制系统应用场景从底层硬件PWM驱动、编码器或霍尔传感器反馈到中层的PID算法实现与参数整定再到可能存在的简单上位机通信调试构成了一个完整的“感知-决策-执行”闭环。我拆解过不少类似的项目发现其核心价值在于提供了一个“从原理到实践”的完整链路。很多教科书和理论文章讲PID讲得头头是道但一到实际动手面对如何初始化定时器产生PWM、如何准确捕获编码器脉冲、如何在中断里安全地计算PID并更新占空比这些具体问题时新手往往无从下手。这个项目压缩包恰恰就是填补这“最后一公里”的实战代码。它不仅仅是一段PID算法的C语言实现更是一个将算法嵌入到真实硬件时序和中断体系中的工程范本。通过研究它你可以快速掌握如何在一个资源有限的单片机如STM32F103上构建一个稳定、响应快速的电机调速系统这是机器人、智能小车、云台、精密传动等众多领域的基础技能。2. 核心硬件架构与信号链解析一个完整的直流电机PID调速系统其硬件架构是算法得以运行的物理基础。理解这个信号链是读懂任何相关代码的前提。2.1 执行机构电机与驱动电路系统末端是直流电机和它的驱动模块。STM32的IO口驱动能力很弱通常仅几十mA无法直接驱动电机因此必须使用驱动电路。最常用的是H桥电路它允许我们通过控制四个开关管通常是MOSFET的通断来改变加载在电机两端的电压方向和大小从而实现电机的正反转和调速。在项目中驱动部分通常由一个集成的电机驱动芯片如TB6612FNG、DRV8833、L298N或分立MOSFET搭建的H桥来完成。STM32通过几个GPIO输出控制信号给驱动芯片例如AIN1/AIN2, BIN1/BIN2控制电机的转向和制动模式。PWMA/PWMB接收来自STM32的PWM信号控制电机的平均电压即调速。这里的关键是PWM的频率选择。频率太低如几十Hz电机会听到明显的啸叫声转动也不连续频率太高如几十kHz虽然听不到声音但开关损耗会增加且对MOSFET的开关速度要求更高。对于普通直流有刷电机一个常用的经验值是10kHz到20kHz。这个频率人耳几乎听不到且大多数驱动芯片和MOSFET都能很好地工作。在代码中这个频率是通过配置STM32的定时器如TIM1, TIM2, TIM3, TIM4的预分频器PSC和自动重装载值ARR来设定的。2.2 感知器官速度反馈传感器闭环控制的前提是能测量被控量——转速。常用方案有光电编码器/霍尔编码器安装在电机轴上。每旋转一圈输出固定数量的脉冲如13线编码器输出13个脉冲。通过测量单位时间内的脉冲数M法测速或测量相邻脉冲的时间间隔T法测速可以计算出转速。这是精度最高的方式。霍尔传感器常见于无刷直流电机BLDC内部用于换相但也可以利用其信号进行低速测速。精度低于编码器。测速发电机输出与转速成正比的模拟电压。需要STM32的ADC模块进行采样成本较高现在较少用。在STM32F1项目中使用编码器接口模式是最为普遍和高效的选择。STM32的定时器如TIM2, TIM3, TIM4硬件上直接支持编码器模式可以自动根据编码器A、B两相的相位关系进行计数无需外部中断抗干扰能力强且不占用CPU时间。代码中需要将对应GPIO配置为编码器模式并初始化定时器。CPU只需定期例如每10ms读取定时器的计数器值CNT将其与上一次的值相减就得到了这段时间内的脉冲数从而计算出速度。2.3 控制大脑STM32F1的资源配置STM32F103系列作为经典的Cortex-M3内核MCU是这类项目的性价比之选。我们需要为其分配好任务一个高级定时器如TIM1或通用定时器如TIM2/3/4用于产生驱动电机所需的PWM波。通常配置为PWM模式1或2输出比较通道。一个通用定时器如另一个TIM2/3/4配置为编码器接口模式用于捕获编码器脉冲。一个基本定时器如TIM6/TIM7或通用定时器配置为定时中断作为整个PID控制系统的“心跳”。在这个中断服务函数里执行速度计算、PID运算和PWM更新。这个中断周期就是PID的控制周期通常取1ms到10ms。太短会加重CPU负担太长则系统响应慢。USART串口用于连接上位机如电脑串口助手、VOFA、匿名上位机等实时发送速度、目标值、PWM占空比等数据或者接收来自上位机的目标速度指令和PID参数便于调试。ADC可选如果系统需要监测电机电流用于过流保护或电流环控制则需要用到ADC采样采样电阻上的电压。在解压的工程里你首先应该在main.c、stm32f10x_it.c中断服务程序以及相应的tim.c、usart.c初始化文件中找到以上资源的配置代码。理解这些初始化流程就等于掌握了系统的骨架。3. PID控制算法的嵌入式实现剖析PID算法是项目的灵魂。理论上的连续PID公式是u(t) Kp * e(t) Ki * ∫e(t)dt Kd * de(t)/dt在数字系统中我们需要将其离散化。常见的两种实现方式是位置式PID和增量式PID。3.1 位置式PID直观但需注意积分饱和位置式PID的输出直接对应执行机构的位置如PWM的占空比。其离散公式为u(k) Kp * e(k) Ki * Σe(j) Kd * [e(k) - e(k-1)]其中e(k) target - measure(k)即当前偏差。在C语言中一个典型的位置式PID结构体和计算函数可能如下所示typedef struct { float Target; // 目标值 float Measure; // 测量值 float Err; // 当前误差 float Err_Last; // 上一次误差 float Kp, Ki, Kd; // PID参数 float Integral; // 积分项累加和 float Output; // 输出值 float OutputMax; // 输出限幅上限 float OutputMin; // 输出限幅下限 float IntegralMax;// 积分限幅上限抗饱和 } PID_TypeDef; float PID_Calculate(PID_TypeDef *pid, float measure) { pid-Measure measure; pid-Err pid-Target - pid-Measure; // 比例项 float p_out pid-Kp * pid-Err; // 积分项带限幅防止饱和 pid-Integral pid-Err; if (pid-Integral pid-IntegralMax) pid-Integral pid-IntegralMax; if (pid-Integral -pid-IntegralMax) pid-Integral -pid-IntegralMax; float i_out pid-Ki * pid-Integral; // 微分项常用不完全微分或测量值微分 float d_out pid-Kd * (pid-Err - pid-Err_Last); // 或者 d_out pid-Kd * (pid-Measure_Last - pid-Measure); (测量值微分对设定值变化不敏感) pid-Err_Last pid-Err; // 更新误差历史 // pid-Measure_Last pid-Measure; // 如果用测量值微分需要更新 // 计算总输出并限幅 pid-Output p_out i_out d_out; if (pid-Output pid-OutputMax) pid-Output pid-OutputMax; if (pid-Output pid-OutputMin) pid-Output pid-OutputMin; return pid-Output; }位置式PID的注意事项积分饱和Integral Windup当误差长期存在如电机卡住积分项会不断累加到一个非常大的值即使误差减小输出仍维持在极限值系统反应迟钝。上述代码中的IntegralMax就是对抗积分饱和的一种简单有效的方法——积分限幅。微分冲击当目标值Target阶跃变化时误差e(k)会突变导致微分项Kd*[e(k)-e(k-1)]瞬间变得很大产生“微分冲击”。解决方法之一是采用“测量值微分”即用(measure(k-1)-measure(k))代替(e(k)-e(k-1))这样微分项只对反馈值的变化敏感对设定值变化不敏感。3.2 增量式PID更适用于执行机构带积分特性的对象增量式PID输出的是控制量的增量Δu(k)。其公式可由位置式推导而来Δu(k) u(k) - u(k-1) Kp*[e(k)-e(k-1)] Ki*e(k) Kd*[e(k)-2e(k-1)e(k-2)]最终执行机构的实际控制量需要累加这个增量u(k) u(k-1) Δu(k)。typedef struct { float Target; float Measure; float Err, Err_Last, Err_LLast; // 当前、上次、上上次误差 float Kp, Ki, Kd; float Output; float OutputMax; float OutputMin; } PID_Increment_TypeDef; float PID_Increment_Calculate(PID_Increment_TypeDef *pid, float measure) { pid-Measure measure; pid-Err pid-Target - pid-Measure; float delta_out pid-Kp * (pid-Err - pid-Err_Last) pid-Ki * pid-Err pid-Kd * (pid-Err - 2*pid-Err_Last pid-Err_LLast); pid-Output delta_out; // 累加增量 // 输出限幅 if (pid-Output pid-OutputMax) pid-Output pid-OutputMax; if (pid-Output pid-OutputMin) pid-Output pid-OutputMin; // 更新误差历史 pid-Err_LLast pid-Err_Last; pid-Err_Last pid-Err; return pid-Output; }增量式PID的特点与选择优点算法本身无需处理积分项不会发生积分饱和。算式中不需要累加误差控制增量只与最近几次采样值有关误动作影响小。缺点存在静态误差需要靠积分项Ki来消除但Ki的作用形式与位置式不同。编程实现时需要对输出进行限幅并且需要保存u(k-1)。适用场景执行机构本身具有积分特性例如步进电机脉冲驱动每个脉冲代表一个位置增量、阀门控制的是阀门的开度变化率等。对于直流电机PWM调速两种方式都可以用但位置式更为直观也更常见。在下载的工程中你需要找到PID计算的核心函数识别它是位置式还是增量式并理解其结构体成员的含义。这直接关系到后续的调参逻辑。4. 系统软件流程与中断设计实战一个稳健的嵌入式控制系统其软件架构必须清晰尤其是中断服务程序ISR的设计要遵循“快进快出”原则。4.1 主循环与中断的分工典型的程序框架如下main()函数初始化系统时钟、GPIO、定时器PWM、编码器、基础定时、串口、ADC等。初始化PID控制器参数Kp, Ki, Kd, 限幅值等。进入while(1)主循环。主循环通常只处理非实时性任务例如检测按键改变目标速度。通过串口接收并解析上位机指令更新目标速度或PID参数。将当前速度、目标值、输出等数据打包通过串口发送给上位机注意频率不要太高以免阻塞。其他状态指示灯控制。定时中断服务程序如TIM6_IRQHandler 这是控制系统的核心节奏发生器。假设我们设置定时器每5ms产生一次中断。清除中断标志位。速度采样读取编码器定时器的计数器值CNT计算与上一次的差值delta_cnt。根据编码器线数和测速方法M法计算当前转速speed (delta_cnt / N) / T。其中N是每转脉冲数T是采样周期5ms。然后将CNT清零或记录当前值。PID计算调用PID_Calculate()函数传入当前测量到的speed得到新的PWM输出值output。PWM更新将output值经过映射写入到PWM定时器的比较寄存器如TIM1-CCR1从而改变占空比驱动电机。可选数据缓存将本次的speed,target,output存入数组供主循环中的串口发送程序使用。关键细节速度计算中的delta_cnt必须处理定时器溢出问题。如果编码器是单向旋转且速度不快可以用int16_t类型的差值。但如果可能反转或高速最好使用int32_t类型并考虑定时器是向上计数还是向下/向上计数以及计数器溢出时的处理STM32的编码器模式通常能自动处理方向但计数值是16位的会从0xFFFF翻到0x0000。4.2 串口通信协议设计为了方便调试串口通信必不可少。一个简单实用的协议可以这样设计上位机下传控制指令例如发送字符串“s1000\n”表示设定目标速度为1000 RPM发送“p1.5 i0.2 d0.01\n”表示更新PID参数。单片机上传数据反馈为了在VOFA、匿名上位机或自己写的Qt上位机中显示波形通常需要以较高的频率如100Hz发送数据。可以采用二进制帧格式以减少数据量例如定义一个结构体帧#pragma pack(1) // 单字节对齐 typedef struct { uint8_t head[2]; // 帧头例如 0xAA, 0x55 int16_t target; // 目标速度 int16_t measure; // 测量速度 int16_t output; // PWM输出 uint8_t check; // 校验和前面所有字节的和取低8位 } DataFrame_t; #pragma pack()在定时中断或主循环中将数据填充到这个结构体计算校验和后通过串口HAL_UART_Transmit或USART_SendData函数发送出去。上位机程序按照同样的格式解析就能实时绘制速度曲线了。一个常见的坑在中断服务程序里调用printf或复杂的字符串格式化函数来发送数据。这会极大地增加中断执行时间可能导致系统定时不准甚至崩溃。正确的做法是在中断里只将数据填入发送缓冲区然后启动DMA传输或在主循环中查询发送。5. PID参数整定从理论到手感调参是PID应用的“玄学”部分但有其内在逻辑。对于电机速度环我常用的手动整定步骤是“先P后I再D最后微调”。5.1 参数整定步骤详解准备工作确保电机空载机械结构稳固。将Ki和Kd设为0。设置一个适中的目标速度例如最大速度的30%。准备好上位机实时观察测量速度的波形。比例系数 Kp从小到大地增加Kp比如从0.1开始。你会发现系统响应变快但Kp太小时电机可能启动缓慢甚至无法达到目标速度静差大。继续增大Kp直到系统出现持续、小幅度的振荡。此时系统处于临界稳定状态。记录下这个Kp值称为Ku。将Kp设置为0.5 * Ku左右。此时系统应该能较快地达到目标值且没有振荡或只有极小的超调。积分系数 Ki引入Ki的目的是消除静差。在只有P控制时由于摩擦等因素稳态速度可能会略低于目标值。非常缓慢地增加Ki比如从0.001开始。Ki的作用是“找后账”偏差持续存在时它会累积并增大输出。观察响应。合适的Ki会使系统最终精确稳定在目标值上。但Ki过大会带来两个问题一是积分饱和启动时积分项累积过大导致启动超调巨大二是使系统响应变“肉”并可能引发低频振荡。技巧如果发现启动超调很大可以尝试使用“积分分离”算法当误差较大时如启动阶段取消积分作用只有当误差进入一个较小范围时才开启积分。这能有效改善启动性能。微分系数 Kd微分项预测未来能抑制超调和振荡。在调好P和I后如果系统稳定但响应有轻微过冲或小振荡可以引入D。从小值开始增加Kd如0.0001。你会发现超调被抑制响应曲线变得更“平滑”。微分项的副作用非常明显它会放大噪声。如果编码器信号有毛刺微分后会形成 spikes导致PWM输出剧烈抖动。因此微分项通常需要配合一个低通滤波器或者直接使用“不完全微分”形式的PID算法。对于很多直流电机调速应用如果P和I调得好不加D也能获得不错的性能。D项要慎用。5.2 整定过程中的现象与对策现象可能原因调整方向响应极其缓慢永远达不到目标Kp太小输出驱动力不足大幅增加 Kp启动时剧烈振荡甚至啸叫Kp太大系统不稳定减小 Kp稳态时始终比目标值慢一点有静差缺少积分作用或Ki太小适当增加 Ki达到目标值后在目标值上下低频摆动Ki太大积分过强减小 Ki启动瞬间有一个很大的尖峰超调Ki太大积分饱和或Kd为负减小Ki或采用积分分离电机运行时伴有高频“震颤”或“吱吱”声Kd太大放大了编码器噪声减小Kd或为微分项加低通滤波对目标值变化的跟踪有延迟系统带宽不足可能需要同时增加P和I但要注意稳定在稳定前提下同比例微增Kp和Ki我的个人心得调参时一次只变动一个参数并观察至少十几秒到一分钟的系统响应。改变目标值看系统的跟踪能力。用手轻轻捏住电机轴施加扰动看系统的抗干扰能力恢复速度。一个好的参数应该兼顾快速性响应快、稳定性无振荡、准确性无静差和鲁棒性抗扰动。永远不要指望一套参数能适应从空载到重载的所有情况对于负载变化大的场合可能需要自适应PID或更复杂的控制策略。6. 工程代码深度解读与优化空间打开“stm32f1直流PID调速.7z”中的工程文件可能是Keil MDK或IAR项目我们逐层剖析。6.1 外设初始化代码分析首先看HAL_TIM_PWM_Init或TIM_TimeBaseInit等相关函数。这里决定了PWM的频率和分辨率。例如TIM_TimeBaseStructure.TIM_Period 999; // ARR值 TIM_TimeBaseStructure.TIM_Prescaler 71; // PSC值假设系统时钟是72MHz那么PWM频率 72MHz / ((711)*(9991)) 1kHz。这个频率对于电机来说偏低建议调整PSC使频率在10kHz以上。接着看编码器初始化。关键代码是设置定时器为编码器模式TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);这行代码将TIM3配置为在TI1和TI2两个边上都计数提高了分辨率。你需要确认编码器的A、B相是否接到了正确的引脚TIM3_CH1和TIM3_CH2。然后是基础定时器中断初始化它设置了PID的控制周期。周期时间T (ARR1)*(PSC1) / Fclk。确保这个周期比如5ms是合理的。6.2 PID核心算法实现检查找到pid.c和pid.h文件。检查以下几点算法类型是位置式还是增量式积分处理是否有积分限幅IntegralMax是否有积分分离逻辑微分处理是误差微分还是测量值微分是否有低通滤波例如d_out Kd * (last_measure - current_measure)就是测量值微分。输出限幅输出是否被限制在合理的范围内如0-1000对应PWM占空比0%-100%参数范围Kp, Ki, Kd的数值是否在合理量级对于速度环Kp可能在0.1~10之间Ki在0.001~0.1之间Kd在0~0.01之间仅供参考具体取决于系统。6.3 中断服务程序逻辑审视打开stm32f10x_it.c找到定时器中断函数如TIM6_IRQHandler。速度计算查看其如何从编码器计数器计算速度。是否正确处理了计数器溢出特别是反转时速度单位是RPM还是脉冲/秒转换公式是否正确调用PID是否传入了正确的测量值和目标值更新PWMPID的输出值如何映射到PWM比较寄存器的映射关系是否线性例如TIM_SetCompare1(TIM1, (uint16_t)(pid.Output))。执行时间整个中断函数执行时间是否远小于中断周期可以在中断入口和出口翻转一个GPIO用示波器测量脉冲宽度来评估。如果中断执行时间过长需要考虑优化代码如将浮点运算改为定点数运算或降低控制频率。6.4 可选的优化与进阶方向如果基础功能已经跑通可以考虑以下优化让系统更专业速度滤波编码器测速值可能含有噪声。在PID计算前对测量速度进行一阶低通滤波speed_filtered alpha * speed_current (1-alpha) * speed_filtered_last。这能有效平滑信号让PID控制更平稳。前馈控制对于目标速度的阶跃变化单纯PID反馈会有延迟。可以加入前馈控制当目标值改变时直接给一个对应的PWM开环输出再让PID去微调。这能极大提升跟踪性能。PWM_output FeedForward(target) PID_output。抗积分饱和改进除了积分限幅还可以用“遇限削弱积分法”或“Clamping方法”。即当输出饱和时只累计那些使输出脱离饱和区的误差否则停止积分。串级PIDCascade PID如果对动态性能要求极高可以考虑电流-速度串级PID。内环是电流环响应快外环是速度环。这需要电流采样硬件如ACS712霍尔电流传感器。内环稳定电流外环稳定速度性能优于单速度环但设计和调参更复杂。代码优化如果控制频率要求很高如1kHz可以考虑将浮点运算全部改为定点数运算Q格式。STM32F1没有硬件FPU浮点计算是软件模拟的速度较慢。使用int32_t类型进行Q15或Q31格式的运算可以大幅提升速度。7. 调试技巧与常见问题排查实录理论终须实践检验。下面是我在调试这类系统时积累的一些“血泪”经验。7.1 调试准备与上电顺序安全第一连接电机驱动板和大功率电源前务必断开电机。先用万用表测量驱动板输出端电压是否正常确保没有短路。分步测试不要一开始就把所有代码都烧进去。应该分模块测试测试PWM写一个简单程序让PWM占空比从0%缓慢增加到100%用示波器或LED接在电机输出端串联一个电阻限流观察波形是否正确频率是否符合预期。测试编码器手动旋转电机轴通过串口打印出编码器计数器的值看正反转计数是否正确增减。测试开环将PID输出固定为一个值如50%占空比让电机空载旋转看是否平稳。同时通过串口打印计算出的速度值观察是否合理。上电顺序建议先给MCU板上电再给电机驱动电源上电。避免驱动板因输入信号不确定而产生瞬间大电流。7.2 典型问题与排查表问题现象可能原因排查方法电机完全不转1. PWM无输出2. 驱动芯片使能端未拉高3. 电机或驱动板电源问题4. 驱动芯片逻辑输入错误1. 示波器测PWM引脚。2. 查驱动芯片手册确认使能引脚电平。3. 万用表测电源电压。4. 检查控制转向的GPIO电平。电机单向转不能反转1. 驱动芯片的转向控制逻辑错误2. 编码器计数方向判断错误导致PID输出反了1. 检查控制电机方向的GPIO输出序列。2. 打印PID输出值看正负是否正确。尝试将目标速度设为负值测试。电机抖动、振动或啸叫1. PWM频率过低人耳可闻2. PID参数不当尤其是Kp、Kd过大3. 电源功率不足或电压跌落4. 机械连接不牢固1. 提高PWM频率至10kHz以上。2. 用上位机看速度波形是否振荡重新调参。3. 监测电源电压使用更大功率电源。4. 紧固联轴器、螺丝等。速度控制不稳波动大1. 编码器信号受干扰2. 速度计算周期与PID周期不匹配3. 微分项引入噪声4. 负载突变1. 编码器线使用双绞线电源加滤波电容。2. 确保每次PID计算前使用的速度是最新采样值。3. 减小Kd或为微分项加低通滤波。4. 检查机械部分是否卡顿。响应慢跟踪延迟大1. PID控制周期太长2. Kp、Ki太小3. 电机或驱动板本身响应慢1. 缩短定时中断周期如从10ms改为5ms。2. 适当增大Kp和Ki注意稳定性。3. 检查驱动板响应频率有些廉价驱动板有延迟。串口数据乱码或收不到1. 波特率不匹配2. 串口引脚接错TX/RX交叉3. 中断与DMA冲突1. 确认上位机和代码中波特率设置一致如115200。2. 检查接线MCU的TX应接上位机的RX。3. 避免在中断中长时间占用串口。改变目标速度时电机“冲”一下积分饱和导致。启动时误差大积分项累积过多。启用积分分离或调小Ki或加入抗积分饱和算法。7.3 利用上位机工具辅助调试“工欲善其事必先利其器”。一个好的上位机能让调试效率提升十倍。VOFA这是我强烈推荐的国产神器。它支持多种协议如RawData justfloat 协议帧可以非常方便地实时绘制多条曲线。你只需要在单片机代码里按照它的格式发送浮点数组即可。匿名上位机、Vofa、SerialPlot都是不错的串口绘图工具。自己用Qt/Python写如果需要更定制化的功能如参数滑条、数据记录、自动调参算法可以自己用Qt或PythonPyQt/PySide, Matplotlib写一个简单的上位机。通过串口发送调节命令实时接收并显示数据。调试时我通常同时观察三条曲线目标速度阶梯波、实际速度响应曲线、PWM输出控制量。从这三条曲线的形态可以非常直观地判断PID参数的好坏以及系统存在的问题。最后嵌入式控制是一个理论与实践紧密结合的领域。这个“stm32f1直流PID调速”项目提供了一个绝佳的起点。不要满足于让电机转起来要多问为什么为什么这个参数效果好那个现象是什么原因引起的尝试去修改代码观察变化甚至“故意”调坏参数看看系统会怎样崩溃。这个过程积累下来的经验和直觉才是你最宝贵的财富。当你能够从容地让电机按照你想要的任何曲线运动时你会发现更多的复杂系统其核心思想依然是这个简单的PID闭环。本文还有配套的精品资源点击获取