经过几天对PID的学习,以及各种的查阅资料,今天自己动手写了一个闭环小车的PID调速程序。网上关于PID原理的资料文献都有很多,这里我就不多说了,直接给出自己写的程序,希望对那些看了很多资料不敢动手写程序的学者有一些帮助。(我自己也是一个PID的初学者,写这篇博客也是为了加深自己的理解,写的不好的地方,请大家多多提意见)
下面是.c文件的程序
#include<pid.h>
#include<intrins.h>
typedef unsigned char u8;
u8 PWM1,PWM2;
typedef struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed;//定义实际值
float err; //定义偏差值
float err_next; //定义上一个偏差值
float err_last; //定义最上前的偏差值
float err_sum; //定义偏差和
float Kp,Ki,Kd; //定义比例、积分、微分系数
}PID_Value;
PID_Value pid;
void PIDInit()
{
pid.SetSpeed=0.0;
pid.ActualSpeed=0.0;
pid.err=0.0;
pid.err_next=0.0;
pid.err_last=0.0;
pid.err_sum=0.0;
pid.Kp=1;
pid.Ki=0;
pid.Kd=0;
}
/*PID运算函数*/
float SetSpeed_PID(float speed1,float speed2)
{
float PIDIncSpeed;
pid.SetSpeed=speed1;
pid.ActualSpeed=speed2;
pid.err=pid.SetSpeed-pid.ActualSpeed;
pid.err_sum+=pid.err;
PIDIncSpeed=pid.Kp*(pid.err)+pid.Ki*pid.err_sum+pid.Kd*(pid.err_next-pid.err_last);
pid.ActualSpeed+=PIDIncSpeed;
pid.err_last=pid.err_next;
pid.err_next=pid.err;
return pid.ActualSpeed;
}
void forward()
{
left_motor_1=1;
left_motor_2=0;
right_motor_1=1;
right_motor_1=0;
PWM1=SetSpeed_PID(20.0,Speed);
PWM2=20;
}
.c文件采用的是增量型PID的调节
这里是.h文件的程序
#ifndef __PID_H
#define __PID_H
#include<reg52.h>
#include<intrins.h>
sbit ENB=P2^0; //右轮电机转动使能控制位
sbit right_motor_1=P2^2;//右电机控制位1
sbit right_motor_2=P2^1;//右电机控制位2
sbit left_motor_1=P2^3; //左电机控制位1
sbit left_motor_2=P2^4; //左电机控制位2
sbit ENA=P2^5; //左轮电机转动使能控制位
extern u16 PWM1,PWM2;
void forward();
float SetSpeed_PID(float speed1,float speed2);
#endif
程序就写到这里了,希望对我自己和初学者的你们都有帮助。
对于三个参数的确定,一般的也是大都数人都在使用的方法就是:将Ki、Kd先赋值为零,确定Kp,之后是第二个参数Ki,最后才是微分参数Kd。(三个系数的确定需要不断的仿真,找到比较适合的值)