位置型PID的C语言实现
首先,再次给出位置型PID离散化公式:
根据位置型PID离散化公式编写C语言代码程序:
第一步,定义PID变量结构体代码如下:
struct _pid{
float SetSpeed; //定义设定值
float ActualSpeed;//定义实际值
float err; //定义偏差值
float err_last; //定义上一个偏差值
float err_past; //定义前一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float voltage; //定义电压值(控制执行器变量)
float integral; //定义积分值
int index; // 积分分离时的变量
float umax; //积分极限
float umin;
}pid;
第二步,初始化变量:
void PID_init() //pid变量初始化
{
printf("PID_init begin \n");
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.err_past = 0.0;
pid.voltage = 0.0;
pid.integral = 0.0;
pid.Kp = 0.4;
pid.Ki = 0.2;
pid.Kd = 0.2;
pid.umax = 400;
pid.umin = -200;
printf("PID_init end \n");
}
统一初始化变量,尤其是 Kp,Ki,Kd 三个参数,调试过程当中,对于要求的控制效果,可以通过调节这三个量直接进行调节。
第三步,编写控制算法:
/**********************************************************************************/
//PID算法 驱动代码
//对比例、微分、积分进行离散化处理之后
/*********************************************************************************/
//位置型PID算法
//PID算法最基本形式,未考虑死区问题,未定义上下限,对公式的直接实现
float PID_realize1(float speed)
{
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed;
pid.integral += pid.err; //积分
pid.voltage = pid.Kp * pid.err + pid.Ki * pid.integral
+ pid.Kd * (pid.err - pid.err_last); //电压
pid.err_last = pid.err;
pid.ActualSpeed = pid.voltage * 1.0;
return pid.ActualSpeed;
}
注意:这里用了最基本的算法实现形式,没有考虑死区问题,没有设定上下限,只是对公式的一种直接的实现。
第四步,编写测试代码:
int main(void)
{
uart_init(115200); //串口初始化波特率为115200
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
PID_init();
int count = 0;
while(count<1000)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
delay_ms(50); //延时300ms
GPIO_SetBits(GPIOC,GPIO_Pin_13);
delay_ms(50); //延时300ms
float speed = PID_realize1(200.0);
printf("%f\n",speed);
count++;
}
return 0 ;
}
测试说明:测试代码中,初始化串口,奖PID的数据通过串口发送给电脑上位机,同时每传送一次数据,LED等闪烁一次,用以提 示程序运行状况。
第四步,测试结果说明:
经过1000次调节后输出单片机1000个数据,其中一部分如下所示:
83.000001 11.555000 59.559675 28.175408 52.907421 38.944152 51.891699 46.141651
53.339054 51.509998 55.908450 55.944631 58.970680
199.999094 199.999115 199.999123 199.999135 199.999152 199.999161 199.999172
199.999183 199.999201 199.999203 199.999224 199.999232 199.999243 199.999261
199.999263 199.999284 199.999292 199.999304 199.999321 199.999323 199.999344
199.999352 199.999364 199.999381 199.999390 199.999401 199.999412 199.999430
199.999432 199.999453 199.999461 199.999473