51单片机PID的算法实现程序

合集下载

基于51单片机的PID调温(热得快)资料

基于51单片机的PID调温(热得快)资料

《自动控制原理》课程设计指导老师:邹恩年级专业:13 自动化 4 班姓名学号(分工) 韩锦澎 201330280107(电路设计) 韦伊玲 201330280219 (程序编写) 徐敏芳 201330280723 (焊接调试) 王可欣 201330280102 (论文)2015年1月7 日1目录1. 系统设计方案......................................................3 1.1 方案一........................................................3 1.2 方案二 .......................................................3 1.3 方案三........................................................3 1.4 方案的比较和确定..............................................3 2.系统硬件部分设计...................................................3 2.1 系统硬件电路图 ...............................................3 2.1.1 单片机 AT89C52 ..........................................4 2.1.2 单片机与 LCD 通信连接 ....................................4 2.1.3 其他电路模块及总电路 .......................................5 3 系统软件部分 .......................................................5 3.1 系统的主流程图如下............................................5 4.温度控制系统 PID 调节...............................................6 4.1 PID 控制传递函数..............................................6 4.2 PID 参数调节方法..............................................6 4.3 PID 参数设定..................................................6 5.实验与调试.........................................................7 6.总论...............................................................8 附 录.............................................................8参 考 文 献.........................................................2421. 系统设计方案1.1 方案一 选用铂电阻温度传感器。

51单片机pid算法程序

51单片机pid算法程序

51单片机pid算法程序51单片机是一种广泛应用于嵌入式系统开发的微控制器。

PID算法是一种常用的控制算法,用于实现系统的闭环控制。

本文将介绍如何在51单片机上实现PID算法。

PID算法是一种经典的控制算法,它能够根据系统的反馈信息,自动调整控制量,使系统的输出接近期望值。

PID算法由比例项(P 项)、积分项(I项)和微分项(D项)组成。

比例项用来根据当前误差大小调整控制量,积分项用来根据过去误差的累积值调整控制量,微分项用来根据误差的变化速度调整控制量。

在51单片机上实现PID算法,首先需要编写程序来读取系统的反馈信息和期望值。

例如,可以通过ADC模块读取传感器的信号,然后通过计算得到当前误差。

接下来,根据比例项、积分项和微分项的系数,计算PID控制量。

最后,将PID控制量输出到执行机构,例如电机或舵机,来控制系统的输出。

在编写PID算法程序时,需要注意一些细节。

首先,要根据实际系统的特点和要求来选择合适的PID参数。

比例项的系数决定了控制量对误差的敏感程度,积分项的系数决定了控制量对误差累积值的敏感程度,微分项的系数决定了控制量对误差变化速度的敏感程度。

其次,要注意处理PID算法中的积分项和微分项的累积误差。

积分项的累积误差可能会导致系统出现超调或震荡,需要适当地进行限制或清零。

微分项的累积误差可能会导致系统出现噪声放大或不稳定,需要进行滤波或限制。

最后,要注意程序的效率和实时性。

PID算法通常需要以一定的频率进行计算和更新,要保证程序能够及时响应系统的变化。

除了基本的PID算法,还可以根据具体的应用需求进行算法的优化和改进。

例如,可以引入自适应调整PID参数的方法,使系统能够根据实时的工作条件自动调整PID参数。

还可以引入前馈控制或模糊控制等方法,进一步提高系统的控制性能和鲁棒性。

51单片机是一种常用的嵌入式系统开发平台,可以很方便地实现PID算法。

通过合理选择PID参数和优化算法,可以实现对系统的精确控制。

51单片机PID算法程序增量式PID控制算法

51单片机PID算法程序增量式PID控制算法

51单片机PID算法程序增量式PID控制算法增量式PID控制算法是一种常用的控制算法,可以应用于各种控制系统中。

该算法的原理是通过计算目标值与实际值之间的差异,来调整控制系统的输出,使其逐渐接近目标值。

增量式PID控制算法的核心思想是通过对目标值与实际值之间的差异进行积分和微分计算,来调整控制系统的输出。

这样可以使得控制系统对误差的响应更加敏感,从而实现更精确的控制效果。

在51单片机中实现增量式PID控制算法,可以按照以下步骤进行:1.参数设置:首先需要设置PID控制算法的参数,包括比例系数Kp、积分系数Ki和微分系数Kd。

这些参数可以根据实际控制系统的需求进行调整。

2.变量定义:定义控制系统所需的变量,包括目标值、实际值、误差值、上一次的误差值、累积误差值等。

3.计算误差:将目标值与实际值之间的差异作为误差值进行计算。

4.计算增量输出:根据误差值以及上一次的误差值和累积误差值,计算控制系统的增量输出。

增量输出的计算公式为:增量输出=Kp*(当前误差-上一次误差)+Ki*当前误差+Kd*(当前误差-上一次误差)5.更新变量:更新控制系统所需的变量,包括上一次的误差值和累积误差值。

6.输出信号:将增量输出作为控制系统的输出信号,并进行相应的处理。

通过上述步骤,就可以实现51单片机的增量式PID控制算法。

在实际应用中,可以根据具体情况对算法进行优化和改进,以满足实际控制的需求。

总结起来,增量式PID控制算法是一种常用的控制算法,可以通过计算目标值与实际值之间的差异,调整控制系统的输出,从而实现精确的控制效果。

在51单片机中实现增量式PID控制算法,可以按照参数设置、变量定义、计算误差、计算增量输出、更新变量和输出信号等步骤进行。

根据具体情况可以对算法进行优化和改进,以满足实际控制的需求。

单片机PID算法实现

单片机PID算法实现

单片机PID算法实现在网络上收集了一个PID控制程序,看到很多研友的毕业设计可能涉及到PID控制,这是一个PID的程序,希望能做到抛砖引玉,仅供大家参考。

/*/////////////////////////////////////////////////////////////*//* initial interrupter *//*/////////////////////////////////////////////////////////////*/void init_interrupter(void) /**/{TMOD=0x21; /* 设置计时器0工作于模式1,设置计时器1工作于模式2*/TL0=0x00; /* T0=0000定时时间为71.1ms;71.1ms*15=1.066s*/TH0=0xdc; /*T0=DC00定时时间为10ms;10ms*100=1s*/ /*T0=FC66定时时间为1m s;10ms*1000=1s*/TL1=0xfd; /* 设置串口通信速率9600bps*/TH1=0xfd;PCON=0x00; /* SMOD=0, 速率不倍增*/SCON=0x50; /* 8位数据通信,串行通信方式1,允许单片机接收数据*/IP=0x10; /*serial com is preferential*/IE=0x92; /* 定时器0, 串口中断允许;定时器1中断禁止*/rs485_receive=0;rs485_transmitte=0;TR0=1; /* 启动定时器0*/TR1=1; /* 启动定时器1*/}void tim er0_server(void) interrupt 1 using 1 /**/{TL0=0x00; TH0=0xdc;/*T0=DC00 timing interval is 10ms;10ms*100=1s*//*T0=FC66 timing interval is 1ms;10ms*1000=1s*/if (flag_serial==1){tim er0_counter_3++;if (tim er0_counter_3>11){tim er0_counter_3=0;flag_serial=0;pointer_serial_com_data=serial_com_data;counter_serial_com_data=0;}}dog=!dog;/*Tim er0 is full(10ms), feed dog*/if (timing_interval==0) {timing_interval=1;} /*tim ing_interval is lost then set it to 1 second*/tim er0_counter_1++;/*tim er0_counter_1 is software tim er. when timer0 interrupt is full, it increase autom atically*/if ((unsigned char) (tim er0_counter_1/100)==timing_interval) /*tim ing_interval arrives*/{out_flag=1;/*indexing 占空比high level begin*//*-scan 0809 to get current equipment's tem perature-*/scan_current_Tem perature();origina_address=0x82;display1_Temperature(current_Tem perature,origina_address);/*-calculate out_value-*/PID_algorithm_function(PID_mode,PP,II,DD,BB,current_Tem perature,seted_t em perature);//out_value=0.5;if (out_value>0.0) /*out_value=0.0, then 占空比is zero*/{control_0=1;ledctrl_address=0x8c;leddata_address=0xff;}//reset tim er0_counter_1 and timer0_counter_2,tim er0_counter_1=0; //indexing timing_interval's timingtim er0_counter_2=0; //indexing 占空比's timing}if(out_flag==1){tim er0_counter_2++;if (out_value<1.0){if( (unsigned char) (timer0_counter_2/out_value/100) >= timing_interval){tim er0_counter_2=0;control_0=0;ledctrl_address=0x8c;leddata_address=0x00;out_flag=0;}}}}float PID_algorithm_function(uchar PID_mode_2,floatP_2,I_2,D_2,B_2,current_Temperature_2,seted_tem perature_2){float idata delta;switch (PID_mode_2){case 1: break;/*PID mode*/case 2: D_2=0; break;/*PI m ode*/case 3: I_2=0; break;/*PD m ode*/case 4: I_2=0; D_2=0; break;/*P m ode*/}if (PID_mode_2<5)/*PID algorithm*/ek=(seted_tem perature_2-current_Tem perature_2)/99.9;delta=P_2*(ek-ek1)+I_2*ek+D_2*(ek-2.0*ek1+ek2);out_value=out_value+de lta;ek2=ek1;ek1=ek;if (out_value>1.0){out_value=1;}else if (out_value<=0){out_value=0.0;}if (PID_mode_2==5) /*BB algorithm*/{if (current_Tem perature_2-seted_temperature_2>=B_2) {out_value=0.0;} if (seted_tem perature_2-current_Temperature_2>=B_2) {out_value=1.0;} }return (out_value);}软件练习十二:将十六进制数据转换成十进制数据熟悉51 单片机指令系统,掌握程序设计方法。

单片机PID算法程序精编版

单片机PID算法程序精编版

单片机P I D算法程序公司内部编号:(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-51单片机P I D算法程序(二)位置式P I D控制算法由51单片机组成的数字控制系统控制中,PID控制器是通过PID控制算法实现的。

51单片机通过AD对信号进行采集,变成数字信号,再在单片机中通过算法实现PID运算,再通过DA把控制量反馈回控制源。

从而实现对系统的伺服控制。

位置式PID控制算法位置式PID控制算法的简化示意图上图的传递函数为:(2-1)在时域的传递函数表达式(2-2)对上式中的微分和积分进行近似(2-3)式中n是离散点的个数。

于是传递函数可以简化为:(2-4)其中u(n)——第k个采样时刻的控制;KP——比例放大系数;Ki——积分放大系数;Kd——微分放大系数;T ——采样周期。

如果采样周期足够小,则(2-4)的近似计算可以获得足够精确的结果,离散控制过程与连续过程十分接近。

(2-4)表示的控制算法直接按(2-1)所给出的PID控制规律定义进行计算的,所以它给出了全部控制量的大小,因此被称为全量式或位置式PID控制算法。

缺点:1)由于全量输出,所以每次输出均与过去状态有关,计算时要对e(k)(k=0,1,…n)进行累加,工作量大。

2)因为计算机输出的u(n)对应的是执行机构的实际位置,如果计算机出现故障,输出u(n)将大幅度变化,会引起执行机构的大幅度变化,有可能因此造成严重的生产事故,这在实际生产中是不允许的。

位置式PID控制算法C51程序具体的PID参数必须由具体对象通过实验确定。

由于单片机的处理速度和ram资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,运算到最后再除以一个2的N次方数据(相当于移位),作类似定点数运算,可大大提高运算速度,根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的“余数”,做好余数补偿。

这个程序只是一般常用pid算法的基本架构,没有包含输入输出处理部分。

51单片机PID的算法实现程序

51单片机PID的算法实现程序

51单片机PID的算法实现程序用整型变量来实现PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了,关于系数和采样电压全部是放大10倍处理的.所以精度不是很高. 但是也不是那么低,大部分的场合都够了. 实在觉得精度不够, 可以再放大10倍或者100倍处理,但是要注意不超出整个数据类型的范围就可以了.本程序包括PID计算和输出两部分.当偏差>10度全速加热,偏差在10度以内为PID计算输出. 具体的参考代码参见下面:*///================================================================// pid.H// Operation about PID algorithm procedure// C51编译器 Keil 7.08//================================================================// 作者:zhoufeng// Date :2007-08-06// All rights reserved.//================================================================#include <reg52.h>#include <intrins.h>typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long int uint32;/**********函数声明************/void PIDOutput ();void PIDOperation ();/*****************************/typedef struct PIDValue{uint32 Ek_Uint32[3]; //差值保存,给定和反馈的差值uint8 EkFlag_Uint8[3]; //符号,1则对应的为负数,0为对应的为正数uint8 KP_Uint8;uint8 KI_Uint8;uint8 KD_Uint8;uint16 Uk_Uint16; //上一时刻的控制电压uint16 RK_Uint16; //设定值uint16 CK_Uint16; //实际值}PIDValueStr;PIDValueStr PID;uint8 out ; // 加热输出uint8 count; // 输出时间单位计数器/*********************************PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式) 函数入口: RK(设定值),CK(实际值),KP,KI,KD函数出口: U(K)//PID运算函数********************************/void PIDOperation (void){uint32 Temp[3]; //中间临时变量uint32 PostSum; //正数和uint32 NegSum; //负数和Temp[0] = 0;Temp[1] = 0;Temp[2] = 0;PostSum = 0;NegSum = 0;if( PID.RK_Uint16 > PID.RK_Uint16 ) //设定值大于实际值否?{if( PID.RK_Uint16 - PID.RK_Uint16 >10 ) //偏差大于10否?{_Uint16 = 100; } //偏差大于10为上限幅值输出(全速加热)else{Temp[0] = PID.RK_Uint16 - PID.CK_Uint16; //偏差<=10,计算E(k)PID.EkFlag_Uint8[1]=0; //E(k)为正数//数值移位PID.Ek_Uint32[2] = PID.Ek_Uint32[1];PID.Ek_Uint32[1] = PID.Ek_Uint32[0];PID.Ek_Uint32[0] = Temp[0];/****************************************/if( PID.Ek_Uint32[0] >PID.Ek_Uint32[1] ) //E(k)>E(k-1)否?{Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1]; //E(k)>E(k-1)PID.EkFlag_Uint8[0]=0; } //E(k)-E(k-1)为正数else{Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1]; //E(k)<E(k-1)PID.EkFlag_Uint8[0]=1; } //E(k)-E(k-1)为负数/****************************************/Temp[2]=PID.Ek_Uint32[1]*2 ; // 2E(k-1)if( (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])>Temp[2] )//E(k-2)+E(k)>2E(k-1)否?{Temp[2]=(PID.Ek_Uint32[0]+PID.Ek_Uint32[2])-Temp[2]; //E(k-2)+E(k)>2E(k-1)PID.EkFlag_Uint8[2]=0; }//E(k-2)+E(k)-2E(k-1)为正数else{Temp[2]=Temp[2]-(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]); //E(k-2)+E(k)<2E(k-1)PID.EkFlag_Uint8[2]=1; } //E(k-2)+E(k)-2E(k-1)为负数/****************************************/Temp[0] = (uint32)PID.KP_Uint8 * Temp[0]; //KP*[E(k)-E(k-1)]Temp[1] = (uint32)PID.KI_Uint8 * PID.Ek_Uint32[0]; // KI*E(k)Temp[2] = (uint32)PID.KD_Uint8 * Temp[2]; //KD*[E(k-2)+E(k)-2E(k-1)]/*以下部分代码是讲所有的正数项叠加,负数项叠加*//**********KP*[E(k)-E(k-1)]**********/if(PID.EkFlag_Uint8[0]==0)PostSum += Temp[0]; //正数和elseNegSum += Temp[0]; //负数和/********* KI*E(k)****************/if(PID.EkFlag_Uint8[1]==0)PostSum += Temp[1]; //正数和else; //空操作,E(K)>0/****KD*[E(k-2)+E(k)-2E(k-1)]****/if(PID.EkFlag_Uint8[2]==0)PostSum += Temp[2]; //正数和elseNegSum += Temp[2]; //负数和/***************U(K)***************/PostSum += (uint32)_Uint16;if(PostSum > NegSum ) // 是否控制量为正数{ Temp[0] = PostSum - NegSum;if( Temp[0] < 100 ) //小于上限幅值则为计算值输出_Uint16 = (uint16)Temp[0];else_Uint16 = 100; //否则为上限幅值输出}else //控制量输出为负数,则输出0(下限幅值输出)_Uint16 = 0;}}else{ _Uint16 = 0; }}*********************************函数入口: U(K)函数出口: out(加热输出)//PID运算植输出函数********************************/void PIDOutput (void){static int i;i=_Uint16;if(i==0)out=1;else out=0;if((count++)==5)//如定时中断为40MS,40MS*5=0.2S(输出时间单位),加热周期20S(100等份){ //每20S PID运算一次count=0;i--;}}Welcome To Download !!!欢迎您的下载,资料仅供参考!。

51单片机PID算法程序(三)增量式PID控制算法

51单片机PID算法程序(三)增量式PID控制算法

51单片机PID算法程序(三)增量式PID控制算法前言在之前的两篇文章中,我们分别介绍了基础PID算法和位置式PID控制算法。

在本文中,我们将介绍另一种常见的PID算法——增量式PID控制算法,以及如何在51单片机上实现增量式PID控制算法。

增量式PID控制算法简介增量式PID控制算法与位置式PID控制算法最大的区别在于输出控制量的计算方式不同。

位置式PID算法的输出控制量是与目标值的误差和历史误差之和的积分和误差的比例和微分,而增量式PID算法的输出控制量只与误差和历史误差的差值有关。

在增量式PID控制算法中,输出控制量的计算方式如下:$$ OutPut=K_p \\cdot Err+K_i \\cdot \\Delta Err+K_d \\cdot \\Delta^2 Err $$ 其中,K p、K i和K d分别是比例、积分和微分系数。

增量式PID控制算法的优点在于可以避免积分饱和、能够快速响应控制量变化,因此在某些要求高响应速度的应用中,常选择使用增量式PID控制算法。

51单片机上的增量式PID控制算法相比较于位置式PID控制算法,增量式PID控制算法的实现更加复杂,需要考虑历史误差的存储、误差的差值计算等问题。

因此,在51单片机上实现增量式PID控制算法需要一些特殊的处理方式。

我们可以通过以下三个步骤来实现增量式PID控制算法:步骤一:初始化变量在增量式PID控制算法中,需要定义一些变量,如上一次的误差值和输出控制量等。

因此,在使用增量式PID控制算法之前,需要先初始化这些变量。

//定义变量double set_point=0; //目标值double process_pv=0; //实际值double Kp=1,Ki=1,Kd=1; //PID参数double last_error=0,prev_error=0; //历史误差double output=0, dInput=0; //输出控制量和误差的差值double output_max=100.0,output_min=-100.0; //控制量范围//初始化变量void PID_Init(){last_error = 0;prev_error = 0;dInput = 0;output = 0;}步骤二:控制量计算根据增量式PID控制算法的公式,我们可以计算控制量的值。

51单片机PID算法程序

51单片机PID算法程序

51单片机PID算法程序51单片机(也称为STC单片机)是一种常见的单片机型号,它可以使用PID(Proportional-Integral-Derivative,比例-积分-微分)算法来实现控制系统。

PID算法可以根据系统当前的误差、误差的积分以及误差的变化率来动态调整系统的输出,使得系统达到期望的目标。

下面是一个使用51单片机实现PID算法的程序示例:```c#include <reg52.h>#include <intrins.h>//定义PID参数#define Kp 1 // 比例系数#define Ki 0.1 // 积分系数#define Kd 0.01 // 微分系数//定义控制输出范围#define OutputMax 100#define OutputMin 0//定义系统参数#define SetPoint 100 // 设定值#define SampleTime 100 // 采样时间(单位:ms)//全局变量unsigned int SetPointValue;unsigned int ProcessValue;signed int PIDOutput;unsigned int LastProcessValue;signed long Integral;signed int Error;signed int LastError;//初始化函数void InitSetPointValue = SetPoint;ProcessValue = 0;PIDOutput = 0;LastProcessValue = 0;Integral = 0;Error = 0;LastError = 0;//PID计算函数signed int PIDCalculation(signed int input)Error = SetPointValue - input; // 当前误差Integral += Error * SampleTime; // 积分项signed int dError = Error - LastError; // 当前误差的变化率PIDOutput = Kp * Error + Ki * Integral + Kd * dError; // PID 输出//限制输出在控制范围内if (PIDOutput > OutputMax)PIDOutput = OutputMax;}else if (PIDOutput < OutputMin)PIDOutput = OutputMin;}LastError = Error;return PIDOutput;//主函数void mainInit(;while (1)//获取传感器测量值ProcessValue = GetProcessValue(; // 自定义函数,获取传感器测量值//PID控制signed int controlValue = PIDCalculation(ProcessValue);//输出控制信号SetControlOutput(controlValue); // 自定义函数,设置输出控制信号//延时采样时间Delay(SampleTime); // 自定义函数,延时指定的时间}```上述示例程序在使用51单片机编写PID算法时,首先定义了PID参数(比例系数Kp、积分系数Ki和微分系数Kd)、控制输出范围(OutputMax和OutputMin)以及系统参数(设定值SetPoint和采样时间SampleTime)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机PID的算法实现程序
用整型变量来实现PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了,关于系数和采样电压全部是放大10倍处理的.所以精度不是很高. 但是也不是那么低,大部分的场合都够了. 实在觉得精度不够, 可以再放大10倍或者100倍处理,但是要注意不超出整个数据类型的范围就可以了.本程序包括PID计算和输出两部分.当偏差>10度全速加热,偏差在10度以内为PID计算输出. 具体的参考代码参见下面:*/
//================================================================
// pid.H
// Operation about PID algorithm procedure
// C51编译器Keil 7.08
//================================================================
// 作者:zhoufeng
// Date :2007-08-06
// All rights reserved.
//================================================================
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long int uint32;
/**********函数声明************/
void PIDOutput ();
void PIDOperation ();
/*****************************/
typedef struct PIDValue
{
uint32 Ek_Uint32[3]; //差值保存,给定和反馈的差值
uint8 EkFlag_Uint8[3]; //符号,1则对应的为负数,0为对应的为正数uint8 KP_Uint8;
uint8 KI_Uint8;
uint8 KD_Uint8;
uint16 Uk_Uint16; //上一时刻的控制电压
uint16 RK_Uint16; //设定值
uint16 CK_Uint16; //实际值
}PIDValueStr;
PIDValueStr PID;
uint8 out ; // 加热输出
uint8 count; // 输出时间单位计数器
/*********************************
PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式)
函数入口: RK(设定值),CK(实际值),KP,KI,KD
函数出口: U(K)
//PID运算函数
********************************/
void PIDOperation (void)
{
uint32 Temp[3]; //中间临时变量
uint32 PostSum; //正数和
uint32 NegSum; //负数和
Temp[0] = 0;
Temp[1] = 0;
Temp[2] = 0;
PostSum = 0;
NegSum = 0;
if( PID.RK_Uint16 > PID.RK_Uint16 ) //设定值大于实际值否?
{
if( PID.RK_Uint16 - PID.RK_Uint16 >10 ) //偏差大于10否?
{
_Uint16 = 100; } //偏差大于10为上限幅值输出(全速加热) else
{
Temp[0] = PID.RK_Uint16 - PID.CK_Uint16; //偏差<=10,计算E(k)
PID.EkFlag_Uint8[1]=0; //E(k)为正数
//数值移位
PID.Ek_Uint32[2] = PID.Ek_Uint32[1];
PID.Ek_Uint32[1] = PID.Ek_Uint32[0];
PID.Ek_Uint32[0] = Temp[0];
/****************************************/
if( PID.Ek_Uint32[0] >PID.Ek_Uint32[1] ) //E(k)>E(k-1)否?
{
Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1]; //E(k)>E(k-1)
PID.EkFlag_Uint8[0]=0; } //E(k)-E(k-1)为正数else
{
Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1]; //E(k)<E(k-1)
PID.EkFlag_Uint8[0]=1; } //E(k)-E(k-1)为负数
/****************************************/
Temp[2]=PID.Ek_Uint32[1]*2 ; // 2E(k-1)
if( (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])>Temp[2] ) //E(k-2)+E(k)>2E(k-1)否?
{
Temp[2]=(PID.Ek_Uint32[0]+PID.Ek_Uint32[2])-Temp[2]; //E(k-2)+E(k)>2E(k-1) PID.EkFlag_Uint8[2]=0; } //E(k-2)+E(k)-2E(k-1)为正数
else
{
Temp[2]=Temp[2]-(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]); //E(k-2)+E(k)<2E(k-1)
PID.EkFlag_Uint8[2]=1; } //E(k-2)+E(k)-2E(k-1)为负数
/****************************************/
Temp[0] = (uint32)PID.KP_Uint8 * Temp[0]; // KP*[E(k)-E(k-1)]
Temp[1] = (uint32)PID.KI_Uint8 * PID.Ek_Uint32[0]; // KI*E(k)
Temp[2] = (uint32)PID.KD_Uint8 * Temp[2]; // KD*[E(k-2)+E(k)-2E(k-1)]
/*以下部分代码是讲所有的正数项叠加,负数项叠加*/
/**********KP*[E(k)-E(k-1)]**********/
if(PID.EkFlag_Uint8[0]==0)
PostSum += Temp[0]; //正数和
else
NegSum += Temp[0]; //负数和
/********* KI*E(k)****************/
if(PID.EkFlag_Uint8[1]==0)
PostSum += Temp[1]; //正数和
else
; //空操作,E(K)>0
/****KD*[E(k-2)+E(k)-2E(k-1)]****/
if(PID.EkFlag_Uint8[2]==0)
PostSum += Temp[2]; //正数和
else
NegSum += Temp[2]; //负数和
/***************U(K)***************/
PostSum += (uint32)_Uint16;
if(PostSum > NegSum ) // 是否控制量为正数
{ Temp[0] = PostSum - NegSum;
if( Temp[0] < 100 ) //小于上限幅值则为计算值输出
_Uint16 = (uint16)Temp[0];
else
_Uint16 = 100; //否则为上限幅值输出
}
else //控制量输出为负数,则输出0(下限幅值输出)
_Uint16 = 0;
}
}
else
{ _Uint16 = 0; }
}
*********************************
函数入口: U(K)
函数出口: out(加热输出)
//PID运算植输出函数
********************************/
void PIDOutput (void)
{
static int i;
i=_Uint16;
if(i==0)
out=1;
else out=0;
if((count++)==5)//如定时中断为40MS,40MS*5=0.2S(输出时间单位),加热周期20S(100等份) { //每20S PID运算一次
count=0;
i--;
}
}。

相关文档
最新文档