2026/4/13 18:52:29
网站建设
项目流程
小广告的胶怎么清理,漯河做网站优化,一个ip 做2个网站,上海网页制作公司之前收到了一位粉丝朋友的问题#xff0c;是需要了解温度相关的PID控制#xff0c;主要是关于PID根据温度进行风扇转速的调节。针对这个粉丝的问题#xff0c;我觉得也是比较感兴趣的#xff0c;加上自己也是研究PID控制这块#xff0c;所以也花了一些时间去查阅了相关的资…之前收到了一位粉丝朋友的问题是需要了解温度相关的PID控制主要是关于PID根据温度进行风扇转速的调节。针对这个粉丝的问题我觉得也是比较感兴趣的加上自己也是研究PID控制这块所以也花了一些时间去查阅了相关的资料加上自己的思考写了这一篇文章有不正确的地方希望大家可以多理解和进行指正。同样是控温为什么他的风扇又静又能散热在台式机/服务器的风扇调速系统中PID闭环控制的核心是以硬件温度为反馈信号通过算法动态调整风扇PWM占空比最终将硬件温度稳定在目标区间。而温度采样值到风扇电机占空比的映射是连接 “温度检测” 与 “转速控制” 的核心链路分为偏差计算→PID运算→控制量映射→PWM 驱动四个关键步骤。一、 PID闭环控制的核心原理闭环控制的本质是 “检测偏差 - 消除偏差” 的循环反馈过程 相比于开环控制如固定占空比调速它能根据硬件实时温度动态调整兼顾散热效果、静音性和风扇寿命。1. 闭环控制的基本组成一个完整的PID闭环温控系统包含 5 个核心环节形成闭环反馈回路目标温度设定 → 温度采样 → 偏差计算 → PID 算法运算 → PWM 占空比输出 → 风扇转速调整 → 硬件温度变化 → 温度采样循环各环节的具体作用目标温度设定根据硬件安全手册设定阈值如 CPU 目标温度 70℃GPU 目标温度 75℃是控制的 “基准值”。温度采样通过硬件内置传感器如 CPU 的 DTS 数字温度传感器、主板的 NTC 热敏电阻采集实时温度是反馈信号。偏差计算计算实时温度与目标温度的差值即若 e(k)0说明温度低于目标可降低风扇转速若 e(k)0说明温度超标需提高转速。PID算法运算根据偏差的大小、累积趋势、变化速率计算出对应的控制量是闭环控制的 “大脑”。PWM 占空比输出将PID计算的控制量转化为风扇电机的驱动信号最终改变转速。2. PID 三环节的作用比例 P 积分 I 微分 DPID 算法通过三个独立环节的协同实现 “快速响应、消除稳态误差、抑制超调” 的目标离散化后的实用公式为环节核心作用对温控的影响比例环节P按偏差大小即时调整控制量偏差越大输出控制量越大决定系统的响应速度。Kp 越大温度超标时风扇转速提升越快但过大易导致转速频繁波动振荡积分环节I对偏差累积求和消除 “静态误差”如温度长期略高于目标的情况解决 “比例控制无法完全达标的问题”。例如 CPU 长期 72℃目标 70℃积分累积偏差会缓慢提高占空比直至温度达标微分环节D计算偏差的变化速率预判温度趋势提前调整抑制超调。例如 CPU 温度从 60℃ 快速升至 75℃偏差变化率大微分环节会瞬间增大控制量提前拉高转速避免温度持续飙升3. 闭环控制的优势抗干扰性强环境温度变化、硬件负载波动如CPU从空闲到满载时系统能自动调整转速无需人工干预。稳定性高温度不会出现 “忽高忽低” 的情况始终稳定在目标区间。兼顾静音与散热低负载低温时风扇低速静音高负载高温时风扇高速散热避免 “一直满转” 的能源浪费。二、 温度采样到风扇占空比的映射关系映射关系的核心是将 PID 输出的 “抽象控制量 u(k)”转化为风扇电机可识别的 “PWM 占空比”分为3 个关键步骤且每个步骤都需考虑硬件的实际约束。步骤 1PID 控制量的限幅处理PID 计算出的控制量 u(k) 是一个无单位的抽象值可能超出风扇的实际可控范围因此第一步要钳位控制量的上下限Umax对应风扇满转速的最大控制量如占空比 100%。Umin对应风扇最低启动转速的控制量如占空比 15%低于此值风扇可能停转或抖动。举例若PID计算出u(k)120超出最大可控值100则钳位为100若 u(k)5低于最小可控值 15则钳位为15。步骤 2控制量到 PWM 占空比的线性 / 分段映射限幅后的控制量u限幅(k)需与PWM占空比0%~100%建立一一对应的关系常用两种映射方式线性映射适用于中速区间若控制量的有效范围与占空比范围一致如u限幅(k)∈[15,100]对应占空比 D∈[15%,100%]可直接线性对应特点简单易实现适用于温度在目标区间附近的稳态场景。分段映射适用于全温度区间更实用风扇的转速-占空比特性是非线性的低速时占空比变化对转速影响大如 15%→20%转速提升明显高速时占空比变化对转速影响小如 80%→85% 转速提升微弱。因此实际系统会分三段映射步骤 3占空比到风扇转速的最终转换直流风扇电机的转速与 PWM 占空比的关系为占空比决定电机的平均输入电压平均电压越高转速越快近似满足线性关系n风扇实际转速nmax风扇满占空比时的额定转速如 2000 RPMDmin风扇启动的最小占空比如 15%举例某风扇nmax2000RPMDmin15%。当占空比D50%时转速n2000⋅(50-15)/(100-15)≈823RPM当D100%时转速 n2000 RPM。PID 参数整定表硬件类型比例系数 Kp积分系数 Ki微分系数 Kd参数特点说明CPU8~120.2~0.53~5CPU 热惯性小、温度波动快Kp 适中保证响应速度Kd 略高抑制突发负载如跑分、编译的温度超调GPU10~150.3~0.64~6GPU 高负载时功耗波动大如游戏、渲染Kp 和 Kd 略高于 CPU应对瞬时高温冲击内存5~80.1~0.31~2内存发热平缓Kp偏低避免风扇频繁调速Ki小减少积分饱和风险参数调整原则若温度持续超调如 CPU 目标 70℃实际稳定在 75℃→ 增大 Ki每次 0.1。若风扇转速频繁振荡如占空比在 40%~60% 来回跳→ 减小 Kp每次 -1或增大 Kd每次 1。若温度上升时响应慢如 CPU 从 70℃ 升至 85℃ 才开始提速→ 增大 Kp每次 1。参考代码#include stdint.h#include math.h// 硬件温度目标值与安全阈值可根据硬件调整#define TARGET_CPU 70.0f // CPU目标温度(℃)#define TARGET_GPU 75.0f // GPU目标温度(℃)#define TARGET_MEM 45.0f // 内存目标温度(℃)#define MAX_CPU_TEMP 90.0f // CPU安全上限#define MAX_GPU_TEMP 95.0f // GPU安全上限#define MAX_MEM_TEMP 80.0f // 内存安全上限// PID参数对应整定表#define KP_CPU 10.0f // CPU比例系数#define KI_CPU 0.3f // CPU积分系数#define KD_CPU 4.0f // CPU微分系数#define KP_GPU 12.0f // GPU比例系数#define KI_GPU 0.4f // GPU积分系数#define KD_GPU 5.0f // GPU微分系数#define KP_MEM 6.0f // 内存比例系数#define KI_MEM 0.2f // 内存积分系数#define KD_MEM 1.5f // 内存微分系数// 占空比约束#define MIN_DUTY 15.0f // 最小占空比(%)#define MAX_DUTY 95.0f // 最大占空比(%)#define DEAD_ZONE 2.0f // 温度死区(±2℃)// PID控制器结构体typedef struct {float kp, ki, kd; // PID系数float target; // 目标值float error; // 当前偏差float last_error; // 上一次偏差float integral; // 积分项float integral_limit; // 积分限幅防止饱和float output; // PID输出控制量} PID_Controller;// 全局PID控制器实例PID_Controller pid_cpu {KP_CPU, KI_CPU, KD_CPU, TARGET_CPU, 0, 0, 0, 50.0f, 0};PID_Controller pid_gpu {KP_GPU, KI_GPU, KD_GPU, TARGET_GPU, 0, 0, 0, 50.0f, 0};PID_Controller pid_mem {KP_MEM, KI_MEM, KD_MEM, TARGET_MEM, 0, 0, 0, 50.0f, 0};// 函数声明float PID_Calculate(PID_Controller *pid, float current_value);float Map_ControlToDuty_CPU_GPU(float control);float Map_ControlToDuty_MEM(float control);float Get_WeightedDuty(float duty_cpu, float duty_gpu, float duty_mem);float Limit_Value(float value, float min, float max);/*** brief PID计算核心函数* param pid PID控制器实例* param current_value 当前采样温度* return PID输出控制量*/float PID_Calculate(PID_Controller *pid, float current_value) {// 计算偏差目标-当前pid-error pid-target - current_value;// 温度死区偏差在±2℃内输出保持不变if (fabs(pid-error) DEAD_ZONE) {return pid-output;}// 比例项float p_term pid-kp * pid-error;// 积分项限幅防止饱和pid-integral pid-ki * pid-error;pid-integral Limit_Value(pid-integral, -pid-integral_limit, pid-integral_limit);float i_term pid-integral;// 微分项float d_term pid-kd * (pid-error - pid-last_error);pid-last_error pid-error;// 总输出控制量限幅pid-output Limit_Value(p_term i_term d_term, 0, 100);return pid-output;}/*** brief CPU/GPU控制量→占空比分段映射* param control PID输出控制量(0~100)* return 最终占空比(%)*/float Map_ControlToDuty_CPU_GPU(float control) {float duty;if (control 30) {// 低温段低增益映射 D u(k) - 10duty control - 10;} else if (control 80) {// 中温段线性映射 D u(k)duty control;} else {// 高温段高增益映射 D 0.8*u(k) 20duty 0.8 * control 20;}// 占空比最终限幅return Limit_Value(duty, MIN_DUTY, MAX_DUTY);}/*** brief 内存控制量→占空比低增益映射* param control PID输出控制量(0~100)* return 最终占空比(%)*/float Map_ControlToDuty_MEM(float control) {float duty 0.7 * control 4.5;return Limit_Value(duty, MIN_DUTY, MAX_DUTY);}/*** brief 多硬件占空比加权融合* param duty_cpu CPU对应占空比* param duty_gpu GPU对应占空比* param duty_mem 内存对应占空比* return 综合占空比CPU:0.5, GPU:0.35, 内存:0.15*/float Get_WeightedDuty(float duty_cpu, float duty_gpu, float duty_mem) {float weighted 0.5 * duty_cpu 0.35 * duty_gpu 0.15 * duty_mem;return Limit_Value(weighted, MIN_DUTY, MAX_DUTY);}/*** brief 数值限幅辅助函数* param value 输入值* param min 最小值* param max 最大值* return 限幅后的值*/float Limit_Value(float value, float min, float max) {if (value min) return min;if (value max) return max;return value;}/*** brief 主控制流程示例100ms调用一次* param temp_cpu 当前CPU温度* param temp_gpu 当前GPU温度* param temp_mem 当前内存温度* return 最终输出的PWM占空比(%)*/float Fan_Control_Main(float temp_cpu, float temp_gpu, float temp_mem) {// 故障保护任一硬件超温直接输出最大占空比if (temp_cpu MAX_CPU_TEMP || temp_gpu MAX_GPU_TEMP || temp_mem MAX_MEM_TEMP) {return MAX_DUTY;}// 分别计算各硬件PID控制量float ctrl_cpu PID_Calculate(pid_cpu, temp_cpu);float ctrl_gpu PID_Calculate(pid_gpu, temp_gpu);float ctrl_mem PID_Calculate(pid_mem, temp_mem);// 控制量映射为占空比float duty_cpu Map_ControlToDuty_CPU_GPU(ctrl_cpu);float duty_gpu Map_ControlToDuty_CPU_GPU(ctrl_gpu);float duty_mem Map_ControlToDuty_MEM(ctrl_mem);// 加权融合得到最终占空比float final_duty Get_WeightedDuty(duty_cpu, duty_gpu, duty_mem);return final_duty;}// 示例调用模拟传感器数据int main(void) {// 模拟采样温度CPU78℃, GPU80℃, 内存48℃float temp_cpu 78.0f;float temp_gpu 80.0f;float temp_mem 48.0f;// 计算最终PWM占空比float pwm_duty Fan_Control_Main(temp_cpu, temp_gpu, temp_mem);// 输出结果实际应用中需将占空比写入PWM外设寄存器// 例如STM32可通过TIM_SetCompare1(TIM1, pwm_duty/100*ARR); 配置占空比(void)pwm_duty; // 避免编译警告return 0;}代码关键说明PID 核心逻辑包含积分限幅防止积分饱和、温度死区±2℃避免风扇频繁抖动偏差计算为目标温度-实时温度温度越高偏差越负PID输出控制量越大。分段映射实现CPU/GPU分为低温30、中温30~80、高温80三段映射适配不同温度场景的调速需求内存采用全区间低增益映射适配其发热平缓的特性。多硬件加权按CPU(0.5)GPU(0.35)内存(0.15)权重融合占空比可根据场景调整权重如挖矿平台调高 GPU 权重。工程化保护硬件超温时直接输出 95% 占空比强制散热占空比限幅在 15%~95%避免风扇停转或满负载损坏。移植适配要点采样接口需替换main函数中的模拟温度为实际传感器读取逻辑如I2C读取 DS18B20、读取 CPU 内置 DTS 温度PWM 输出根据MCU型号将final_duty写入PWM定时器的比较寄存器如 STM32 的TIM_SetCompare、ESP32 的ledc_set_duty参数微调若实际运行中温度超调/振荡可按整定表的调整原则修改KP/KI/KD宏定义。