用C51实现PID算法

上传人:仙*** 文档编号:130523292 上传时间:2022-08-05 格式:DOC 页数:16 大小:141.50KB
返回 下载 相关 举报
用C51实现PID算法_第1页
第1页 / 共16页
用C51实现PID算法_第2页
第2页 / 共16页
用C51实现PID算法_第3页
第3页 / 共16页
亲,该文档总共16页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-date用C51实现PID算法用C51实现PID算法关于PID的算法实现,很多书上都讲了。但是,最近真正要用PID算法的时候,发现书上的代码在我们51上来实现还不是那么容易的事情。简单的说来,就是不能直接调用。仔细分析你可以发现,教材上的、网上现行的PID实现的C语言代码几乎都是用浮点型的数据来做的,可以想象,如果我们的计算使用浮点数据,那我们的51单片机来运行的话会有多痛苦。所以,本人自己琢磨着弄了一个整型变量来实现了PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了。关于系数和采样电压全部是放大10倍处理的。所以精度不是很高,但是也不是那么低,大部分的场合都够用了。实在觉得精度不够,可以再放大10倍或者100倍处理,但是要注意不超出整个数据类型的范围就可以了。 本人做的是带死区控制的PID算法。具体的参考代码参见下面:typedef struct PIDValue uint32 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; /uint8 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_Uint16UINADCH ADPool.Value_Uint16UFADCH ) /给定大于反馈,则EK为正数 Temp0 = ADPool.Value_Uint16UINADCH - ADPool.Value_Uint16UFADCH; /计算Ek0 if( 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 = 0; /当前EK为正数 Temp0 = (uint32)PID.KP_Uint8 * PID.Ek_Uint320; / KP*EK0 Temp1 = (uint32)PID.KI_Uint8 * PID.Ek_Uint321; / KI*EK1 Temp2 = (uint32)PID.KD_Uint8 * PID.Ek_Uint322; / KD*EK2 else /反馈大于给定 Temp0 = ADPool.Value_Uint16UFADCH - ADPool.Value_Uint16UINADCH; /计算Ek0 if( 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*EK0 Temp1 = (uint32)PID.KI_Uint8 * PID.Ek_Uint321; / KI*EK1 Temp2 = (uint32)PID.KD_Uint8 * PID.Ek_Uint322; / KD*EK2 /*以下部分代码是讲所有的正数项叠加,负数项叠加*/ if(PID.EkFlag_Uint80=0) PostSum += Temp0; /正数和 else NegSum += Temp0; /负数和 / KP*EK0 if(PID.EkFlag_Uint81!=0) PostSum += Temp1; /正数和else NegSum += Temp1; /负数和 / - kI * EK1 if(PID.EkFlag_Uint82=0) PostSum += Temp2; /正数和 else NegSum += Temp2; /负数和 / KD * EK2 PostSum += (uint32)PID.Uk_Uint16; / if( PostSum NegSum ) / 是否控制量为正数 Temp0 = PostSum - NegSum; if( Temp0 (uint32)ADPool.Value_Uint16UMAXADCH ) /小于限幅值则为计算值输出 PID.Uk_Uint16 = (uint16)Temp0; else PID.Uk_Uint16 = ADPool.Value_Uint16UMAXADCH; /否则为限幅值输出 else /控制量输出为负数,则输出0 PID.Uk_Uint16 = 0; -
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!