当前位置: 首页 > news >正文

3.PID控制中的微分环节:给PI踩刹车的关键

在嵌入式控制领域,PID算法是当之无愧的"万能钥匙"。其中,P负责快速响应,I负责消除余差,但这两个环节配合时,很容易出现"超调"问题——就像水温快速升到38度,等I反应过来往下拉时已经晚了。这时候,第三个环节D(微分控制)就登场了,它的核心作用是给PI踩刹车,预判误差变化趋势,提前抑制超调。

一、微分控制的核心原理

微分环节的本质是误差的变化率,公式为:

$$u_D = K_d \times \frac{de}{dt}$$

其中:

  • $K_d$:微分系数
  • $\frac{de}{dt}$:误差的变化速率

简单来说,微分环节不看当前误差有多大,而是看误差变化有多快。比如水温以每秒2度的速度飙升,这是危险信号,微分项会立刻输出反向力,提前减速,避免超调。

二、微分控制的三个核心特性

1. 看趋势,不看现状

微分环节关注的是误差的变化趋势,而非当前误差值。误差变化越快,D的反向输出越强;误差匀速变化,D保持恒定反向力;误差不变,D完全不出力。

2. 提前刹车,避免超调

就像开车时遇到红灯,不会等车到停止线才踩刹车,而是提前收油减速。D就是这个提前动作,通过预判误差变化趋势,提前抑制超调。

3. 对噪声敏感,需合理设置

微分环节的弱点是怕噪声。传感器采集的温度数据中常有小毛刺,这些毛刺意味着瞬间的剧烈变化,微分环节会把这些噪声放大,误以为是误差在快速变化,输出不该有的反向力。因此,$K_d$不能设置过大。

三、PID三力合体:P+I+D协同工作

当三个环节一起工作时,系统会呈现完美的控制效果:

  • P(比例):系统启动误差大时,P出主力快速拉升
  • I(积分):接近目标误差小时,I慢慢推最后那一点,消除余差
  • D(微分):上升太快要冲过时,D踩刹车往回拉,抑制超调

三力平衡后,系统既快又稳还没有余差,这就是完整的PID控制。

四、STM32 LL库实现PID微分控制

以下是基于STM32 LL库的完整PID控制代码,包含微分环节的实现:

1. PID结构体定义

typedef struct { float Kp; // 比例系数 float Ki; // 积分系数 float Kd; // 微分系数 float target; // 目标值 float actual; // 实际值 float error; // 当前误差 float last_error; // 上一次误差 float integral; // 积分累积 float output; // 输出值 float output_max; // 输出最大值 float output_min; // 输出最小值 } PID_HandleTypeDef;

2. PID初始化函数

void PID_Init(PID_HandleTypeDef *pid, float kp, float ki, float kd, float target, float output_max, float output_min) { pid->Kp = kp; pid->Ki = ki; pid->Kd = kd; pid->target = target; pid->actual = 0.0f; pid->error = 0.0f; pid->last_error = 0.0f; pid->integral = 0.0f; pid->output = 0.0f; pid->output_max = output_max; pid->output_min = output_min; }

3. PID计算函数(含微分环节)

float PID_Calculate(PID_HandleTypeDef *pid, float actual) { // 更新实际值 pid->actual = actual; // 计算当前误差 pid->error = pid->target - pid->actual; // 比例项 float p_out = pid->Kp * pid->error; // 积分项(带限幅) pid->integral += pid->error; if (pid->integral > pid->output_max / pid->Ki) { pid->integral = pid->output_max / pid->Ki; } else if (pid->integral < pid->output_min / pid->Ki) { pid->integral = pid->output_min / pid->Ki; } float i_out = pid->Ki * pid->integral; // 微分项(核心:误差变化率) float derivative = pid->error - pid->last_error; float d_out = pid->Kd * derivative; // 总输出 pid->output = p_out + i_out + d_out; // 输出限幅 if (pid->output > pid->output_max) { pid->output = pid->output_max; } else if (pid->output < pid->output_min) { pid->output = pid->output_min; } // 更新上一次误差 pid->last_error = pid->error; return pid->output; }

4. 主函数调用示例

#include "stm32f1xx_ll_adc.h" #include "stm32f1xx_ll_tim.h" // 定义PID控制器 PID_HandleTypeDef pid; // 初始化ADC和定时器 void Hardware_Init(void) { // ADC初始化(读取温度传感器数据) LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE); LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B); LL_ADC_SetDataAlignment(ADC1, LL_ADC_DATA_ALIGN_RIGHT); LL_ADC_Enable(ADC1); // 定时器初始化(生成PWM控制加热片) LL_TIM_SetPrescaler(TIM2, __LL_TIM_CALC_PSC(SystemCoreClock, 1000000)); LL_TIM_SetAutoReload(TIM2, 1000); LL_TIM_EnableCounter(TIM2); LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_PWM1); LL_TIM_OC_EnablePreload(TIM2, LL_TIM_CHANNEL_CH1); LL_TIM_EnableAllOutputs(TIM2); } // 读取温度值(模拟) float Read_Temperature(void) { uint32_t adc_value = LL_ADC_REG_ReadConversionData12(ADC1); // 将ADC值转换为温度值(根据实际传感器校准) float temperature = (float)adc_value * 50.0f / 4095.0f; return temperature; } // 主函数 int main(void) { // 硬件初始化 Hardware_Init(); // PID初始化:Kp=2.0, Ki=0.1, Kd=0.5, 目标温度=50℃, 输出范围0-100% PID_Init(&pid, 2.0f, 0.1f, 0.5f, 50.0f, 100.0f, 0.0f); while (1) { // 读取实际温度 float actual_temp = Read_Temperature(); // 计算PID输出 float pwm_duty = PID_Calculate(&pid, actual_temp); // 设置PWM占空比 LL_TIM_OC_SetCompareCH1(TIM2, (uint32_t)pwm_duty); } }

五、微分环节的调参建议

  1. 先调P,再调I,最后调D:按照"先P后I再D"的顺序调参,每次只改一个参数,观察系统响应。
  2. Kd不宜过大:微分环节对噪声敏感,Kd过大容易导致系统震荡,建议从0开始逐步增大。
  3. 配合滤波使用:如果传感器噪声较大,建议在微分环节前加入低通滤波,减少噪声干扰。

六、总结

微分环节是PID控制中最容易被误解的环节,但也是实现"既快又稳"控制效果的关键。通过预判误差变化趋势,提前抑制超调,微分环节让PID控制真正成为工业控制领域的"万能算法"。

在实际应用中,需要根据具体场景合理设置Kd值,配合滤波处理噪声,才能发挥微分环节的最大作用。。


http://www.jsqmd.com/news/1392109/

相关文章:

  • 告别啃生肉:一篇搞定LunaTranslator视觉小说实时翻译的完整指南
  • 电子课本下载工具tchMaterial-parser使用教程:4步把智慧教育平台的课本变成本地PDF
  • 图片转STL一键搞定:把照片变成可3D打印的立体浮雕,新手四步就能出活
  • 华为OD机试 - 智能广播合并台号 - 数组(Java 新系统 100分)
  • 2026外贸CRM软件推荐:AI赋能商机挖掘,业客一体化选型指南 - 优质品牌中立测评推荐
  • 让 Java 直连 Windows 共享:jcifs-ng 从零到一实战指南
  • 樊嘉院士Science|时空多组学
  • 从奇点大会看技术会议的价值,普通开发者怎么选会省钱
  • 第三十三届北京国际广播电影电视展览会(BIRTV2026)即将启幕,劲捷KINGJOY将携六类重磅产品强势亮相 - 甄选测评馆
  • 10 分钟搭建 Windows 专属文件同步:SyncTrayzor 新手完整指南
  • 燕郊医疗网站建设如何打造既专业又具患者温度的线上服务平台
  • 051、ISP Pipeline的“数据流断点“——RAW域到RGB域转换时位宽截断导致的banding伪影排查与修复
  • Windows系统文件spwmp.dll丢失找不到问题解决
  • WinUtil快速上手指南:一条命令装软件、清臃肿、管更新,重装Windows不再折腾
  • 血浆p-tau217能否揭示阿尔茨海默病的临床前时间密码?
  • C盘爆满别急着重装!Dism++ 清理神器 3 步免费释放 10GB 空间的完整指南
  • 智能运维控制器参考设计:面向视频监控系统的运维管理硬件方案
  • 让 Agent RAG 真正好用,检索质量是关键,多路召回 + 重排序
  • 图像传感器基础知识介绍
  • 华硕笔记本性能控制实测:GHelper 怎么用?轻量开源替代官方控制台
  • 成都宠物医疗助理培训班 零基础学宠物 B 超 X 光实训 怎么报名去哪里学 - 湖北找学校
  • 当AI遭遇算力、能源和落地困境:类脑智能或成为具身智能破局关键
  • 26/8/13下班学习小结
  • 用Python让AWR1843毫米波雷达数据在屏幕上实时跳动,比想象中简单
  • 告别上万行代码的眼花缭乱:notepad-- 代码折叠功能实用手册
  • 智能压枪从入门到实战:PUBG-Logitech鼠标宏自动识别压枪完整调校手册
  • 新电脑装软件装到崩溃?WinUtil 让你半小时搞定安装、优化与修复
  • LDD3--字符设备驱动
  • 魔兽争霸3地图编辑器卡顿救星:HiveWE完整上手指南,大图创作告别等待
  • 如何判断一家 GEO 服务商是否靠谱?