收藏 分享(赏)

关于PID的算法51实现.doc

上传人:hyngb9260 文档编号:7486902 上传时间:2019-05-19 格式:DOC 页数:4 大小:31KB
下载 相关 举报
关于PID的算法51实现.doc_第1页
第1页 / 共4页
关于PID的算法51实现.doc_第2页
第2页 / 共4页
关于PID的算法51实现.doc_第3页
第3页 / 共4页
关于PID的算法51实现.doc_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

1、PID 的算法 51 实现关于 PID 的算法实现,很多书上都讲了。但是,最近真正要用 PID 算法的时候,发现书上的代码在我们 51 上来实现还不是那么容易的事情。简单的说来,就是不能直接调用。仔细分析你可以发现,教材上的、网上现行的 PID 实现的 C 语言代码几乎都是用浮点型的数据来做的,可以想象,如果我们的计算使用浮点数据,那我们的 51 单片机来运行的话会有多痛苦。所以,本人自己琢磨着弄了一个整型变量来实现了 PID 算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了。关于系数和采样电压全部是放大 10 倍处理的。所以精度不是很高,但是也不是那么低,

2、大部分的场合都够用了。实在觉得精度不够,可以再放大 10 倍或者 100 倍处理,但是要注意不超出整个数据类型的范围就可以了。本人做的是带死区控制的 PID 算法。具体的参考代码参见下面:typedef struct PIDValueuint32 Ek_Uint323; /差值保存,给定和反馈的差值uint8 EkFlag_Uint83; /符号,1 则对应的 Eki为负数,0 为对应的Eki为正数uint8 KP_Uint8;uint8 KI_Uint8;uint8 KD_Uint8;uint8 B_Uint8; /死区电压uint8 KP; /显示修改的时候用uint8 KI; /uint

3、8 KD; /uint8 B; /uint16 Uk_Uint16; /上一时刻的控制电压PIDValueStr;PIDValueStr xdata PID;/*PID = Uk + (KP*E(k) - KI*E(k-1) + KD*E(k-2);*/void PIDProcess(void)uint32 idata Temp3; /uint32 idata PostSum; /正数和uint32 idata NegSum; /负数和Temp0 = 0;Temp1 = 0;Temp2 = 0;PostSum = 0;NegSum = 0;if( ADPool.Value_Uint16UINA

4、DCH ADPool.Value_Uint16UFADCH ) /给定大于反馈,则 EK 为正数Temp0 = ADPool.Value_Uint16UINADCH - ADPool.Value_Uint16UFADCH; /计算 Ek0if( Temp0 PID.B_Uint8 )/数值移位PID.Ek_Uint322 = PID.Ek_Uint321;PID.Ek_Uint321 = PID.Ek_Uint320;PID.Ek_Uint320 = Temp0;/符号移位PID.EkFlag_Uint82 = PID.EkFlag_Uint81;PID.EkFlag_Uint81 = PID

5、.EkFlag_Uint80;PID.EkFlag_Uint80 = 0; /当前 EK 为正数Temp0 = (uint32)PID.KP_Uint8 * PID.Ek_Uint320; / KP*EK0Temp1 = (uint32)PID.KI_Uint8 * PID.Ek_Uint321; / KI*EK1Temp2 = (uint32)PID.KD_Uint8 * PID.Ek_Uint322; / KD*EK2else /反馈大于给定Temp0 = ADPool.Value_Uint16UFADCH - ADPool.Value_Uint16UINADCH; /计算 Ek0if(

6、Temp0 PID.B_Uint8 )/数值移位PID.Ek_Uint322 = PID.Ek_Uint321;PID.Ek_Uint321 = PID.Ek_Uint320;PID.Ek_Uint320 = Temp0;/符号移位PID.EkFlag_Uint82 = PID.EkFlag_Uint81;PID.EkFlag_Uint81 = PID.EkFlag_Uint80;PID.EkFlag_Uint80 = 1; /当前 EK 为负数Temp0 = (uint32)PID.KP_Uint8 * PID.Ek_Uint320; / KP*EK0Temp1 = (uint32)PID.

7、KI_Uint8 * PID.Ek_Uint321; / KI*EK1Temp2 = (uint32)PID.KD_Uint8 * PID.Ek_Uint322; / KD*EK2/*以下部分代码是讲所有的正数项叠加,负数项叠加 */if(PID.EkFlag_Uint80=0)PostSum += Temp0; /正数和elseNegSum += Temp0; /负数和 / KP*EK0if(PID.EkFlag_Uint81!=0) PostSum += Temp1; /正数和elseNegSum += Temp1; /负数和 / - kI * EK1if(PID.EkFlag_Uint8

8、2=0)PostSum += Temp2; /正数和elseNegSum += Temp2; /负数和 / KD * EK2PostSum += (uint32)PID.Uk_Uint16; / if( PostSum NegSum ) / 是否控制量为正数Temp0 = PostSum - NegSum;if( Temp0 (uint32)ADPool.Value_Uint16UMAXADCH ) /小于限幅值则为计算值输出PID.Uk_Uint16 = (uint16)Temp0;elsePID.Uk_Uint16 = ADPool.Value_Uint16UMAXADCH; /否则为限幅值输出else /控制量输出为负数,则输出 0PID.Uk_Uint16 = 0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报