欢迎来到天天文库
浏览记录
ID:43546463
大小:32.50 KB
页数:4页
时间:2019-10-10
《用C51实现PID算法》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、关于PID的算法实现,很多书上都讲了。 但是,最近真正要用PID算法的时候,发现书上的代码在我们51上来实现还不是那么容易的事情。简单的说来,就是不能直接调用。仔细分析你可以发现,教材上的、网上现行的PID实现的C语言代码几乎都是用浮点型的数据来做的,可以想象,如果我们的计算使用浮点数据,那我们的51单片机来运行的话会有多痛苦。 所以,本人自己琢磨着弄了一个整型变量来实现了PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了。关于系数和采样电压全部是放大10倍处理的。所以精度不是很高,但是也不是那么低,大部分的场合都够用了。实在
2、觉得精度不够,可以再放大10倍或者100倍处理,但是要注意不超出整个数据类型的范围就可以了。 本人做的是带死区控制的PID算法。 具体的参考代码参见下面: typedefstructPIDValue{ uint32Ek_Uint32[3]; //差值保存,给定和反馈的差值 uint8 EkFlag_Uint8[3]; //符号,1则对应的Ek[i]为负数,0为对应的Ek[i]为正数 uint8 KP_Uint8; uint8 KI_Uint8; uint8 KD_Uint8; uint8 B_Uint8; //死区
3、电压 uint8 KP; //显示修改的时候用 uint8 KI; // uint8 KD; // uint8 B; // uint16 Uk_Uint16; //上一时刻的控制电压}PIDValueStr; PIDValueStrxdataPID;/*********************************PID=Uk+(KP*E(k)-KI*E(k-1)+KD*E(k-2));********************************/void PIDProcess(void){ uint32id
4、ataTemp[3]; // uint32idataPostSum; //正数和 uint32idataNegSum; //负数和 Temp[0]=0; Temp[1]=0; Temp[2]=0; PostSum=0; NegSum=0; if(ADPool.Value_Uint16[UINADCH]>ADPool.Value_Uint16[UFADCH]) //给定大于反馈,则EK为正数 { Temp[0]=ADPool.Value_Uint16[UINADCH]-ADPool.Value_Uint16[UFADCH]; //计算Ek[0]
5、 if(Temp[0]>PID.B_Uint8) { //数值移位 PID.Ek_Uint32[2]=PID.Ek_Uint32[1]; PID.Ek_Uint32[1]=PID.Ek_Uint32[0]; PID.Ek_Uint32[0]=Temp[0]; //符号移位 PID.EkFlag_Uint8[2]=PID.EkFlag_Uint8[1]; PID.EkFlag_Uint8[1]=PID.EkFlag_Uint8[0]; PID.EkFlag_
6、Uint8[0]=0; //当前EK为正数 Temp[0]=(uint32)PID.KP_Uint8*PID.Ek_Uint32[0]; //KP*EK0 Temp[1]=(uint32)PID.KI_Uint8*PID.Ek_Uint32[1]; //KI*EK1 Temp[2]=(uint32)PID.KD_Uint8*PID.Ek_Uint32[2]; //KD*EK2 } } else //反馈大于给定 { Temp[0]=A
7、DPool.Value_Uint16[UFADCH]-ADPool.Value_Uint16[UINADCH]; //计算Ek[0] if(Temp[0]>PID.B_Uint8) { //数值移位 PID.Ek_Uint32[2]=PID.Ek_Uint32[1]; PID.Ek_Uint32[1]=PID.Ek_Uint32[0]; PID.Ek_Uint32[0]=Temp[0]; //符号移位 PID.EkFlag_Uint8[2]=PID
此文档下载收益归作者所有