基于PID控制参数法改变PWM的占空比的STM32F4温控实例

本文介绍了如何使用PID算法在STM32F4上实现温度控制,详细步骤包括建立闭环系统、确定PID参数以及通过自适应算法优化参数。作者分享了代码实现,并展示了达到理想温控曲线的实测结果。适合初学者了解PID算法与STM32结合应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  最近的工程要用到PID算法,在这里与大家分享一下。本文章适合直接上手PID,直接将PID与STM32结合运用起来,比较适合没有接触过PID的新人或者是算法与STM32结合不熟悉的新同学,如果要详细了解PID算法与调整算法还是需要深入了解一下PID算法。这里介绍一个讲PID算法很详细的博主         PID参数调整,个人经验(配输出曲线图)建议可以先看一下这篇文章再看我下文的内容。

首先我的工程是要STM32F4作为主控系统去实现温度控制在37℃,加热装置是一个很普通的通过大小不同的电流驱动的加热片,所以首先第一步是先搭建一个闭环的系统,即是一个封闭的系统(包括有加热模块,采集温度模块和处理模块)。接着我是通过控制不同占空比的PWM波驱动加热片进行加热,经过不断测试记录下来大概37℃的占空比,即记录自己的目标温度的驱动能力大概是多少。第二步就是确定三个参数:比例系数(P),微分系数(I),积分系数(D),笼统的来说PID算法就是设定一个温度,让系统可以最快速度的去升温到预定的温度,但是在即将到达预设温度通过PID算法就行缓冲和修正,防止温度过冲(专业的说法是防止超调量过大),让温度降下来,之后再快速修正并保持稳定在预设温度。我是通过一个自适应算法去获取三个参数的,自适应算法就是让温度达到一个稳定的震荡,接着采集当前的幅值,并通过公式计算出比例系数Kp,同时以计数作为微分时间。。。代码注释后面就是我获取的三个原参数,但是原来的参数的温度变化曲线并不理想,根据PID经典调整口诀调整参数直到温度曲线达到理想。第三步就是将计算出来的PID结果与单片机结合起来,比如我的是控制PWM波,就将PID算法结果与PWM修正结合起来。PID_out()函数就是将PID计算结果与占空比相结合,随着不断的误差更新不断调整占空比控制电流直到达到自己设定的预设温度。

void PID_Calc()  //pid计算
{
	float DelEk;	
	float out;                                             //PID输出
	pid.Kp              = 100;		                      //比例系数  38
	pid.Ki              = 0.10;                           //积分系数   0.3048
	pid.Kd              = 2;                              //微分系数  1.984375
	PID_Deal            = 1;                              //PID_Deal为1时表示进行PID计算
	if (PID_Deal == 1)
	{
		pid.Ek=pid.Sv-pid.Pv;                             //得到当前的偏差值
		pid.SEk+=pid.Ek;                                  //历史偏差总和
		DelEk=pid.Ek-pid.Ek_1;                             //最近两次偏差之差

		pid.Pout=pid.Kp*pid.Ek;                            //比例输出
		pid.Iout=pid.Ki*pid.SEk;  			               //积分输出
		pid.Dout=pid.Kd*DelEk;    			               //微分输出
		out= pid.Pout+ pid.Iout+ pid.Dout;
		kkk++;                                             //计数
		if(out>255)
		{
			kkk=0;
			pid.SEk=0;
		}
		if(out>255)
		{
			pid.OUT=255;
		}
		else if(out<0)
		{
			pid.OUT=0; 
		}
		else 
		{
			pid.OUT=out;
		}
		pid.Ek_1=pid.Ek;  //更新偏差
		PID_out();		
	}
}

这个是我将每一秒采集的温度打印到串口并输出出来拿到matlab画了个图,这属于比较合格的PID温控曲线。

 如果我表示的还不清楚,或者有什么讲错了讲得不好欢迎大家评论区指正。

非无偿开源,有需要可以私信。有自适应的PID算法与控制参数的PID算法。

 

STM32中,设计一个PID (Proportional-Integral-Derivative) 控制系统用于温度控制,涉及到以下几个步骤。这里我会给出一个简化的例子,假设我们有一个PID类来处理PID,以及两个PWM驱动器,一个用于加热器,一个用于制冷器。首先,我们需要定义一些关键函数: ```c #include "stm32f4xx_hal.h" #include "pid.h" typedef enum {HEATER, REFRIGERATOR} Actuator; // PID 控制结构体实例 PID pid_controller; // PWM 宽度占空比数组 float pwm_duty[2]; void PID_Update(float target_temperature, float current_temperature) { // 更新PID得到输出 float output = pid_controller.Compute(target_temperature, current_temperature); // 判断输出是否需要切换加热器和制冷器 if (output > 0) { Actuator actuator = HEATER; // 输出正,开启加热器 } else { actuator = REFRIGERATOR; // 输出负,开启制冷器 } // 调整PWM占空比 switch (actuator) { case HEATER: pwm_duty[actuator] = MAX_OUTPUT - abs(output); // 加热器输出, duty cycle = max_output - |output| break; case REFRIGERATOR: pwm_duty[actuator] = abs(output); // 制冷器输出, duty cycle = |output| break; } // 设置PWM输出 set_pwm(actuator, pwm_duty[actuator]); } void set_pwm(Actuator actuator, float duty_cycle) { // 使用HAL库函数更新对应PWM通道的DutyCycle if (actuator == HEATER) { HAL_TIM_PWM_ChangeDutyCycle(&htimHeater, PWM_CHANNEL, duty_cycle); } else if (actuator == REFRIGERATOR) { HAL_TIM_PWM_ChangeDutyCycle(&htimRefrigerator, PWM_CHANNEL, duty_cycle); } } ``` 在这个示例中,`set_pwm()` 函数会根据PID输出调整加热器和制冷器的PWM值。`PID_Update()` 方接收目标温度和当前测量温度,然后计算PID输出,决定何时打开哪个设备,并调节占空比。 注意:这只是一个基本框架,实际项目中还需要考虑误差限幅、积分饱和处理、死区策略等高级PID设置,以及更复杂的输入/输出数据获取和反馈机制。同时,`set_pwm()` 需要替换为实际的硬件驱动函数,比如HAL库提供的TIM PWM API。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值