基于stm32的PID算法粗略讲解

基于stm32的PID算法粗略讲解


一、PID算法的分类

增量式与位移式的区别

1.输出不同:位置PID控制的输出与整个过去状态有关,并且使用了误差的累加值;而增量PID的输出仅与当前拍和前两拍的误差有关,因此位置PID控制的累积误差相对较大。

2.是否有积分部分:增量PID控制输出为控制量增量,没有积分功能,因此该方法适用于带有积分部分的对象,例如步进电机等。 ,但位置PID适用于执行没有积分部件的对象,例如电动液压伺服阀。

3.是否具有记忆功能:由于增量PID输出是控制量增量,因此,如果计算机出现故障,则故障影响较小,执行器本身具有记忆功能,该功能仍可保留且不会严重影响系统的工作,而位置输出直接对应于对象的输出,因此对系统影响较大。

但通常情况下使用增量式

二、PID的三个参数

1. kP比例

成比例地反映控制系统的偏差信号e(t),偏差一旦产生,控制器立即产生控制作用,以减小偏差。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。
P参数越小比例作用越强,动态响应越快,消除误差的能力越强。通常将P参数由大向小调,以能达到最快响应又无超调(或无大的超调)为最佳参数。

2. kI积分

为消除静差,提高系统的无差度。积分作用的强弱取决于积分时间常数T,T越大,积分作用越弱,反之则越强。

3. KD微分

反映偏差信号的变化趋势,并能在偏差信号变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作速度,减少调节时间。在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。
D越大,微分作用越强,D越小,微分作用越弱。系统调试时通常把D从小往大调,具体参数由试验决定。

在这里插入图片描述

在这里插入图片描述

三.增量式程序


/************************** .h文件******************************/


#ifndef _pid_H
#define _pid_H

#define     MODEL_P       1
#define     MODEL_PI      2
#define     MODEL_PID     3

typedef struct
{
    u8 choose_model;    		//使用哪个模式调节,以方便分布调试
    
    float curr;                   //当前值
    float set;                    //设定值
    
    float En;                     //当前时刻误差值
    float En_1;                   //前一时刻误差值
    float En_2;                   //前二时刻误差值
        
    float Kp;                     //比例系数
    float T;                      //每隔T控制器输出一次PID运算结果

    u16   Tdata;                  //判断PID周期到没到
    float Ti;                     //积分时间常数
    float Td;                     //微分时间常数
    
    float Dout;                   //增量PID计算本次应该输出的增量值-本次计算的结果

    float OUT0;                   //一个维持的输出,防止失控
    
    short currpwm;                //当前的pwm宽度
    u16 pwmcycle;                 //pwm周期

}PID;

extern u8 STATUS;
extern PID pid;
void PID_Init(void);      //增量式PID初始化
void pid_calc(void);              //pid计算 并输出


/************************** .c文件******************************/


#endif
#include "pid.h"
#include "PWM_Config.h"
#include "USART_Config.h"   		//USART设置

PID pid;

void PID_Init()  		//
{
    pid.choose_model = MODEL_PID;
    pid.T=330;                		//采样周期,定时器使用1ms,则最小执行PID的周期为330ms
    
    pid.set =280;            		//用户设定值
    pid.Kp=0.5;                	//比例系数
    pid.Ti=40;               		//微分系数常数
    pid.Td=10;                		//积分时间常数
    pid.OUT0=0;                	//一个维持的输出

    pid.pwmcycle = 330;    		//PWM的周期
}
    
void pid_calc()  			
{
 	float dk1;float dk2;
  	float t1,t2,t3;
    
    if(pid.Tdata < (pid.T))  		//最小计算周期未到
     {
            return ;
     }
    pid.Tdata = 0;
    
    pid.En=pid.set-pid.curr;  		//本次误差
    dk1=pid.En-pid.En_1;   		//本次偏差与上次偏差之差
    dk2=pid.En-2*pid.En_1+pid.En_2;
    
  	t1=pid.Kp*dk1;                   	//比例
    
    t2=(pid.Kp*pid.T)/pid.Ti;      	//积分
    t2=t2*pid.En;
    
    t3=(pid.Kp*pid.Td)/pid.T;        	//微分
    t3=t3*dk2;
    
    switch(pid.choose_model)
     {
         case MODEL_P:    		//仅用P
				pid.Dout= t1;                    
				printf("使用P运算\r\n") ;
             	break;
         
         case MODEL_PI:  		//仅用PI
				pid.Dout= t1+t2;                
				printf("使用PI运算\r\n") ;
            	break;
                 
         case MODEL_PID: 		//用PID
				pid.Dout= t1+t2+t3;        
				printf("使用PID运算\r\n") ;
				break;
	 } 
          
    pid.currpwm+=pid.Dout;  		//本次应该输出的PWM
    printf("PID算得的OUT:\t%d\r\n",(int)pid.currpwm) ;
     
    if(pid.currpwm>pid.pwmcycle)       //确保值在0-pid.pwmcycle之间
    {
      pid.currpwm=pid.pwmcycle;
    }
    if(pid.currpwm<0)
    {
     pid.currpwm=0;
    }
    
    printf("实际输出使用的OUT:\t%d\r\n",(int)pid.currpwm) ;
    pid.En_2=pid.En_1;
    pid.En_1=pid.En;    
}


总结

1首先整定比例部分。将比例系数Kp由小变大
2置积分时间Ti为一较大值,并将经第一步整定很到的比例系数略为缩小(如缩小为原值的4/5),观察系统响应的情况
3 比例系数由小到大,然后找出超调小的Kp
4 积分时间常数Ti由大变小,适当调整Kp
5 微分时间常数Td由小变大,适当调整Ti和Kp
6 KP设定,最初使用1,假如控制之后实际值比设定值小不够,那就增大。反之就减少。
7 TI设定,数据先很大。看效果
8 如果TI加进去之后数据很久才变化到目标值就逐渐减小。如果TI减少到执行几次都是比设定值大的时候那就逐渐增大
9如果刚加进去变化很快,并且超调很高,就增大来调节
10 积分就看情况调节

  • 11
    点赞
  • 143
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值