51单片机PID算法程序

合集下载

51单片机控制DS18B20测温的PID温控程序

51单片机控制DS18B20测温的PID温控程序

51单片机控制DS18B20测温的PID温控程序51单片机控制DS18B20测温的PID温控程序#include;#include;#include;#include;struct PID {unsigned int SetPoint; // 设定目标 Desired Value unsigned int Proportion; // 比例常数 Proportional Constunsigned int Integral; // 积分常数 Integral Const unsigned int Derivative; // 微分常数 Derivative Constunsigned int LastError; // Error[-1]unsigned int PrevError; // Error[-2]unsigned int SumError; // Sums of Errors};struct PID spid; // PID Control Structure unsigned int rout; // PID Response (Output) unsigned int rin; // PID Feedback (Input) sbit data1=P1^0;sbit clk=P1^1;sbit plus=P2^0;sbit subs=P2^1;sbit stop=P2^2;sbit output=P3^4;sbit DQ=P3^3;unsigned char flag,flag_1=0;unsigned char high_time,low_time,count=0;//占空比调节参数unsigned char set_temper=35;unsigned char temper;unsigned char i;unsigned char j=0;unsigned int s;void delay(unsigned char time){unsigned char m,n;for(n=0;nfor(m=0;m;>;i;temp=temp&1;write_bit(temp);}delay(7);// TR0=1;EA=1;}unsigned char read_bit(){unsigned char i,value_bit;EA=0;DQ=0;_nop_();_nop_();DQ=1;for(i=0;i;>;4;temper=i|j;}void PIDInit (struct PID *pp){memset ( pp,0,sizeof(struct PID)); //全部初始化为0 }unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) {unsigned int dError,Error;Error = pp->;SetPoint - NextPoint; // 偏差pp->;SumError += Error; // 积分dError = pp->;LastError - pp->;PrevError; // 当前微分pp->;PrevError = pp->;LastError;pp->;LastError = Error;return (pp->;Proportion * Error // 比例项+ pp->;Integral * pp->;SumError // 积分项+ pp->;Derivative * dError); // 微分项}void compare_temper(){unsigned char i;if(set_temper>;temper) //是否设置的温度大于实际温度{if(set_temper-temper>;1) //设置的温度比实际的温度是否是大于1度{high_time=100; //如果是,则全速加热low_time=0;}else //如果是在1度范围内,则运行PID计算 {for(i=0;i;0){high_time=0;low_time=100;}else{for(i=0;i;>;1;if(m==1)data1=1;elsedata1=0;_nop_();clk=1;_nop_();}}}void display(){unsigned char codenumber[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0 ,0xfe,0x f6};unsigned char disp_num[6];unsigned int k,k1;k=high_time;k=k00;k1=k/100;if(k1==0)disp_num[0]=0;elsedisp_num[0]=0x60;k=k0;disp_num[1]=number[k/10];disp_num[2]=number[k];k=temper;k=k0;disp_num[3]=number[k/10];disp_num[4]=number[k]+1;disp_num[5]=number[s/10];disp_1(disp_num);}void main(){unsigned char z;unsigned char a,b,flag_2=1,count1=0;unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2}; TMOD=0x21;TH0=0x2f;TL0=0x40;SCON=0x50;PCON=0x00;TH1=0xfd;TL1=0xfd;PS=1;EA=1;EX1=0;ET0=1;ES=1;TR0=1;TR1=1;high_time=50;low_time=50;PIDInit ( &spid ); // Initialize Structure spid.Proportion = 10; // Set PID Coefficients 比例常数 Proportional Constspid.Integral = 8; //积分常数 Integral Const spid.Derivative =6; //微分常数Derivative Const spid.SetPoint = 100; // Set PIDSetpoint 设定目标Desired Valuewhile(1){if(plus==0){EA=0;for(a=0;a;5)temper=a;elsetemper=b;a=temper;flag_2=0;if(++count1>;30){display();count1=0;}compare_temper();}TR0=0;z=1;while(1){EA=0;if(stop==0){for(a=0;a<5;a++)for(b=0;b<102;b++){} if(stop==0)disp_1(phil);// break;}EA=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控制程序

Jesse Rei 的51 温度PID经典算法#include<reg51.h>#include<intrins.h>#include<math.h>#include<string.h>struct PID {unsigned int SetPoint; // 设定目标Desired Valueunsigned int Proportion; // 比例常数Proportional Constunsigned int Integral; // 积分常数Integral Constunsigned int Derivative; // 微分常数Derivative Constunsigned int LastError; // Error[-1] unsigned int PrevError; // Error[-2] unsigned int SumError; // Sums of Errors };struct PID spid; // PID Control Structure unsigned int rout; // PID Response (Output) unsigned int rin; // PID Feedback (Input)sbit data1=P1^0;sbit clk=P1^1;sbit plus=P2^0;sbit subs=P2^1;sbit stop=P2^2;sbit output=P3^4;sbit DQ=P3^3;unsigned char flag,flag_1=0;unsigned char high_time,low_time,count=0;//占空比调节参数unsigned char set_temper=35;unsigned char temper;unsigned char i;unsigned char j=0;unsigned int s;void delay(unsigned char time){unsigned char m,n;for(n=0;n<time;n++)for(m=0;m<2;m++){}} void write_bit(unsigned char bitval) {EA=0;DQ=0;if(bitval==1){_nop_();DQ=1;}delay(5);DQ=1;_nop_();_nop_();EA=1;}void write_byte(unsigned char val) {unsigned char i;unsigned char temp;EA=0;TR0=0;for(i=0;i<8;i++){temp=val>>i;temp=temp&1;write_bit(temp);}delay(7);// TR0=1;EA=1;}unsigned char read_bit(){unsigned char i,value_bit;EA=0;DQ=0;_nop_();_nop_();DQ=1;for(i=0;i<2;i++){}value_bit=DQ;EA=1;return(value_bit);}unsigned char read_byte() {unsigned char i,value=0; EA=0;for(i=0;i<8;i++){if(read_bit())value|=0x01<<i;delay(4);}EA=1;return(value);}unsigned char reset() {unsigned char presence; EA=0;DQ=0;delay(30);DQ=1;delay(3);presence=DQ;delay(28);EA=1;return(presence);}void get_temper(){unsigned char i,j;do{i=reset();} while(i!=0);i=0xcc;write_byte(i);i=0x44;write_byte(i);delay(180);do {i=reset();} while(i!=0);i=0xcc;write_byte(i);i=0xbe;write_byte(i);j=read_byte();i=read_byte();i=(i<<4)&0x7f;s=(unsigned int)(j&0x0f); //得到小数部分s=(s*100)/16;j=j>>4;temper=i|j;}void PIDInit (struct PID *pp){memset ( pp,0,sizeof(struct PID)); //全部初始化为0}unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ){unsigned int dError,Error;Error = pp->SetPoint - NextPoint; // 偏差pp->SumError += Error; // 积分dError = pp->LastError - pp->PrevError; // 当前微分pp->PrevError = pp->LastError;pp->LastError = Error;return (pp->Proportion * Error // 比例项+ pp->Integral * pp->SumError // 积分项+ pp->Derivative * dError); // 微分项}void compare_temper(){unsigned char i;if(set_temper>temper) //是否设置的温度大于实际温度{if(set_temper-temper>1) //设置的温度比实际的温度是否是大于1度{high_time=100; //如果是,则全速加热low_time=0;}else //如果是在1度范围内,则运行PID计算{for(i=0;i<10;i++){get_temper(); //获取温度rin = s; // Read Inputrout = PIDCalc ( &spid,rin ); // Perform PID Interation}if (high_time<=100)high_time=(unsigned char)(rout/800);elsehigh_time=100;low_time= (100-high_time);}}else if(set_temper<=temper){if(temper-set_temper>0){high_time=0;low_time=100;}else{for(i=0;i<10;i++){get_temper();rin = s; // Read Inputrout = PIDCalc ( &spid,rin ); // Perform PID Interation}if (high_time<100)high_time=(unsignedchar)(rout/10000);elsehigh_time=0;low_time= (100-high_time);}}// else// {}}void serve_T0() interrupt 1 using 1{if(++count<=(high_time))output=1;else if(count<=100){output=0;}elsecount=0;TH0=0x2f;TL0=0xe0;}void serve_sio() interrupt 4 using 2{}void disp_1(unsigned char disp_num1[6]) {unsigned char n,a,m;for(n=0;n<6;n++){// k=disp_num1[n];for(a=0;a<8;a++){clk=0;m=(disp_num1[n]&1);disp_num1[n]=disp_num1[n]>>1;if(m==1)data1=1;elsedata1=0;_nop_();clk=1;_nop_();}}}void display(){unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0 xbe,0xe0,0xfe,0xf6};unsigned char disp_num[6];unsigned int k,k1;k=high_time;k=k%1000;k1=k/100;if(k1==0)disp_num[0]=0;elsedisp_num[0]=0x60;k=k%100;disp_num[1]=number[k/10];disp_num[2]=number[k%10];k=temper;k=k%100;disp_num[3]=number[k/10];disp_num[4]=number[k%10]+1;disp_num[5]=number[s/10];disp_1(disp_num);}void main(){unsigned char z;unsigned char a,b,flag_2=1,count1=0; unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};TMOD=0x21;TH0=0x2f;TL0=0x40;SCON=0x50; PCON=0x00;TH1=0xfd;TL1=0xfd;PS=1;EA=1;EX1=0;ET0=1;ES=1;TR0=1;TR1=1;high_time=50;low_time=50;PIDInit ( &spid ); // Initialize Structure spid.Proportion = 10; // Set PID Coefficients 比例常数Proportional Constspid.Integral = 8; //积分常数Integral Constspid.Derivative =6; //微分常数Derivative Constspid.SetPoint = 100; // Set PID Setpoint 设定目标Desired Valuewhile(1){if(plus==0){EA=0;for(a=0;a<5;a++)for(b=0;b<102;b++){}if(plus==0){set_temper++;flag=0;}}else if(subs==0){for(a=0;a<5;a++)for(b=0;a<102;b++){}if(subs==0){set_temper--;flag=0;}}else if(stop==0){for(a=0;a<5;a++)for(b=0;b<102;b++){}if(stop==0){flag=0;break;}EA=1;}get_temper();b=temper;if(flag_2==1)a=b;if((abs(a-b))>5)temper=a;elsetemper=b;a=temper;flag_2=0;if(++count1>30){display();count1=0;}compare_temper();}TR0=0;z=1;while(1){EA=0;if(stop==0){for(a=0;a<5;a++)for(b=0;b<102;b++){}if(stop==0)disp_1(phil);// break;}EA=1;}}。

单片机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算法程序(三)增量式PID控制算法

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

51单片机PID算法程序(一)PID算法(原创文章,转载请注明出处/tengjingshu) 比例,积分,微分的线性组合,构成控制量u(t),称为:比例(Proportional)、积分(Integrating)、微分(Differentiation)控制,简称PID控制图1控制器公式在实际应用中,可以根据受控对象的特性和控制的性能要求,灵活地采用不同的控制组合,构成比例(P)控制器比例+积分(PI)控制器比例+积分+微分(PID)控制器式中或式中控制系统中的应用在单回路控制系统中,由于扰动作用使被控参数偏离给定值,从而产生偏差。

自动控制系统的调节单元将来自变送器的测量值与给定值相比较后产生的偏差进行比例、积分、微分(PID)运算,并输出统一标准信号,去控制执行机构的动作,以实现对温度、压力、流量、也为及其他工艺参数的自动控制。

比例作用P只与偏差成正比;积分作用I是偏差对时间的积累;微分作用D 是偏差的变化率;比例(P)控制比例控制能迅速反应误差,从而减少稳态误差。

除了系统控制输入为0和系统过程值等于期望值这两种情况,比例控制都能给出稳态误差。

当期望值有一个变化时,系统过程值将产生一个稳态误差。

但是,比例控制不能消除稳态误差。

比例放大系数的加大,会引起系统的不稳定。

图2比例(P)控制阶跃响应积分(I)控制在积分控制中,控制器的输出与输入误差信号的积分成正比关系。

为了减小稳态误差,在控制器中加入积分项,积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。

这样,即使误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减少,直到等于零。

积分(I)和比例(P)通常一起使用,称为比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。

如果单独用积分(I)的话,由于积分输出随时间积累而逐渐增大,故调节动作缓慢,这样会造成调节不及时,使系统稳定裕度下降。

图3积分(I)控制和比例积分(PI)控制阶跃相应微分(D)控制在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。

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)。

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

51单片机PID算法程序(三)增量式PID控制算法解读
图1
控制器公式
在实际应用中,可以根据受控对象的特性和控制的性能要求,灵活地采用不同的控制组合,构成
比例(P)控制器
比例+积分(PI)控制器
比例+积分+微分(PID)控制器
式中
或ቤተ መጻሕፍቲ ባይዱ
式中
控制系统中的应用
在单回路控制系统中,由于扰动作用使被控参数偏离给定值,从而产生偏差。自动控制系统的调节单元将来自变送器的测量值与给定值相比较后产生的偏差进行比例、积分、微分(PID)运算,并输出统一标准信号,去控制执行机构的动作,以实现对温度、压力、流量、也为及其他工艺参数的自动控制。
T ——采样周期。
如果采样周期足够小,则(2-4)的近似计算可以获得足够精确的结果,离散控制过程与连续过程十分接近。
51单片机PID算法程序(一)PID算法
(原创文章,转载请注明出处/tengjingshu)
比例,积分,微分的线性组合,构成控制量u(t),称为:比例(Proportional)、积分(Integrating)、微分(Differentiation)控制,简称PID控制
(图1,表1)
2)Atmel8-bit AVR Microcontrollers Application Note:AVR221: Discrete PID controller
(图2,图3,图4,图5,表2)
3)使用Ziegler-Nichols方法的自整定控制
/2007-03/200733042815.htm
最好的寻找PID参数的办法是从系统的数学模型出发,从想要的反应来计算参数。很多时候一个详细的数学描述是不存在的,这时候就需要实际地调节PID的参数.
Ziegler-Nichols方法

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--;}}。

51单片机PID算法程序(一)PID算法

51单片机PID算法程序(一)PID算法

式中或式中控制系统中的应用在单回路控制系统中,由于扰动作用使被控参数偏离给定值,从而产生偏差。

自动控制系统的调节单元将来自变送器的测量值与给定值相比较后产生的偏差进行比例、积分、微分(PID)运算,并输出统一标准信号,去控制执行机构的动作,以实现对温度、压力、流量、也为及其他工艺参数的自动控制。

比例作用P只与偏差成正比;积分作用I是偏差对时间的积累;微分作用D是偏差的变化率;比例(P)控制比例控制能迅速反应误差,从而减少稳态误差。

除了系统控制输入为0和系统过程值等于期望值这两种情况,比例控制都能给出稳态误差。

当期望值有一个变化时,系统过程值将产生一个稳态误差。

但是,比例控制不能消除稳态误差。

比例放大系数的加大,会引起系统的不稳定。

图2比例(P)控制阶跃响应积分(I)控制在积分控制中,控制器的输出与输入误差信号的积分成正比关系。

为了减小稳态误差,在控制器中加入积分项,积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。

这样,即使误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减少,直到等于零。

积分(I)和比例(P)通常一起使用,称为比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。

如果单独用积分(I)的话,由于积分输出随时间积累而逐渐增大,故调节动作缓慢,这样会造成调节不及时,使系统稳定裕度下降。

图3积分(I)控制和比例积分(PI)控制阶跃相应微分(D)控制在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。

由于自动控制系统有较大的惯性组件(环节)或有滞后(delay)组件,在调节过程中可能出现过冲甚至振荡。

解决办法是引入微分(D)控制,即在误差很大的时候,抑制误差的作用也很大;在误差接近零时,抑制误差的作用也应该是零。

图4微分(D)控制和比例微分(PD)控制阶跃相应总结:PI比P少了稳态误差,PID比PI反应速度更快并且没有了过冲。

单片机pid算法程序

单片机pid算法程序

单片机pid算法程序
PID控制算法是一种常用的控制算法,适用于各种控制系统的设
计中。

下面是基于单片机的PID算法程序:
1. 初始化参数
在程序开始时,需要先对PID控制算法的三个参数——比例、积
分和微分系数进行初始化,一般设置为:Kp=1.2、Ki=1.0、Kd=0.001,然后将误差值、上次误差值和累积误差值都设置为0。

2. 计算PID输出值
在每个控制周期内,先读取被控制的变量的实际值和期望值,计
算出两者之间的误差值err。

然后按照PID控制算法公式,分别计算出比例、积分和微分三个修正量的值,最后将它们相加,得到PID输出值。

3. 更新参数
PID控制算法是一种自适应算法,需要不断地根据实际情况来更
新算法参数。

如果当前的误差值较大,说明控制效果不佳,应当增加
比例系数Kp和微分系数Kd,以提高控制效果。

否则,应当增加积分系数Ki,以提高稳定性。

4. 输出控制信号
最后,将PID输出值转换成相应的控制信号,输出给执行机构,
实现对被控制系统的控制。

以上就是单片机PID算法程序的基本步骤,可以根据实际需求进
行适当的优化和改进。

51单片机PID算法程序

51单片机PID算法程序

51单片机PID算法程序PID控制(比例-积分-微分)是一种经典的控制算法,常用于单片机控制系统中。

PID控制算法结合了比例、积分和微分三个控制项,可以有效地调节系统的输出,使系统快速稳定地达到设定值。

PID控制算法的基本原理是通过比例、积分和微分三个部分来调节系统输出。

比例部分根据系统当前误差的大小来调节输出,积分部分根据系统过去误差的积累来调节输出,微分部分根据系统误差的变化率来调节输出。

通过合理地调节这三个部分的比例系数,可以使系统快速稳定地达到设定值,并且具有较好的鲁棒性。

下面给出一个单片机上实现PID控制算法的示例程序。

该程序使用C 语言编写,可以在常见的单片机开发环境中运行。

```c#include<reg52.h>sbit PWM=P1^0;sbit DIR=P1^1;sbit EN=P1^2;sbit Kp=0x30;sbit Ki=0x31;sbit Kd=0x32;int SetPoint = 100; //设定值int Kp = 1; //比例系数int Ki = 0.1; //积分系数int Kd = 0.2; //微分系数int GetFeedback//获取反馈值的函数,这里使用ADC等方式获取反馈值return feedback;void SetPWM(int pwm_value)//设置PWM输出的函数PWM = pwm_value;void PIDControlint Feedback = GetFeedback(;int Error = SetPoint - Feedback;static int LastError = Error;static int Integral = 0;int Derivative = Error - LastError;Integral += Error;int Output = Kp * Error + Ki * Integral + Kd * Derivative; SetPWM(Output);LastError = Error;void mainwhile(1)PIDControl(;}```在这个示例程序中,我们定义了一个PID控制函数PIDControl,用于控制系统的输出。

51单片机PID算法程序

51单片机PID算法程序

51单片机PID算法程序(二)位置式PID控制算法由51单片机组成的数字控制系统控制中,PID控制器是通过PID控制算法实现的。

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

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

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

?? 于是传递函数可以简化为:(2-4)其中u(n)——第k个采样时刻的控制;K P? ——比例放大系数;???K i?? ——积分放大系数;K d?? ——微分放大系数;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算法的基本架构,没有包含输入输出处理部分。

PID控制的51汇编程序

PID控制的51汇编程序

PID 控制的51汇编程序PID 控制的51汇编程序;//************************************************************ **************************************************;//功能: 电机控制的PID(积分分离) PID(void) 执行时间少于70uS/932-12MHz;//设计者: 牟联树;//日期: 2003.12.28;//版本号: 1.0;//申明:;//**************************************************************** **********************************************$NOMOD51OCRAH equ 0EFhOCRAL equ 0EEhOCRBH equ 0FBhOCRBL equ 0FAhOCRCH equ 0FDhOCRCL equ 0FChOCRDH equ 0FFhOCRDL equ 0FEhTCR21 equ 0f9h$include (REG52.INC)NAME PIDWorkPR?PID?PIDWork SEGMENT CODEPR?PID_MUL?PIDWork SEGMENT CODEPR?PID_out?PIDWork SEGMENT CODEDT?PID_k?PIDWork SEGMENT DATA PUBLICPID_Kp,PID_Ki,PID_Kd,PID_Umax,PID_Emax PUBLICPID_U,PID_En1,PID_En2,PID_Temp,PID_TempL RSEG ?DT?PID_k?PIDWork PID_Kp: DS 2 ;比例系数PID_KpL data PID_Kp+1PID_Ki: DS 2 ;积分系数PID_KiL data PID_Ki+1PID_Kd: DS 2 ;微分系数PID_KdL data PID_Kd+1PID_Umax: DS 2 ;期望最大值设定PID_UmaxL data PID_Umax+1PID_Emax: DS 2 ;积分分离的误差最大值设定PID_EmaxL data PID_Emax+1PID_U: DS 2 ;当前的采样值PID_UL data PID_U+1PID_En1: DS 2 ;上一次计算的误差值PID_En1L data PID_En1+1PID_En2: DS 2 ;上一次计算的误差的误差值PID_En2L data PID_En2+1PID_Temp: DS 4 ;计算过程中的暂存PID_TempL data PID_Temp+1PID_Temp1 data PID_Temp+2PID_Temp1L data PID_Temp+3 PUBLIC _PID RSEG ?PR?PID?PIDWork_PID: push accpush pswclr c ;有符号减法mov a,PID_UmaxL ;计算当前的误差En(PID_U里暂存运算结果) subb a,PID_ULmov PID_UL,amov a,PID_Umaxsubb a,PID_Umov PID_U,ajnb acc.7,PID_kmov a,PID_ULcpl aadd a,#1mov r7,amov a,PID_Ucpl aaddc a,#0xch a,r7sjmp PID_gPID_k: mov r7,PID_Umov a,PID_ULPID_g: clr csubb a,PID_EmaxLmov a,r7subb a,PID_Emaxjnb acc.7,PID_a ;如果En>Emax则转mov r7,PID_KiL ;Ki*Enmov r6,PID_Kimov r5,PID_ULmov r4,PID_Uacall PID_MUL ;二字节伪有符号乘法(r4-r7里暂存结果) mov a,PID_Temp1L ;PID加法子程序(将结果加入输出) add a,r7mov PID_Temp1L,amov a,PID_Temp1addc a,r6mov PID_Temp1,amov a,PID_TempLaddc a,r5mov PID_TempL,amov a,PID_Tempaddc a,r4mov PID_Temp,aPID_a: mov a,PID_En1L ;更新PID_En1xch a,PID_ULmov PID_En1L,amov a,PID_En1xch a,PID_Umov PID_En1,aclr c ;有符号减法mov a,PID_En1L ;计算当前的误差差(En-En1)subb a,PID_ULmov PID_UL,amov a,PID_En1subb a,PID_Umov PID_U,amovr7,PID_KpL ;+Kp*(En-En1)mov r6,PID_Kpmov r5,PID_ULmov r4,PID_Uacall PID_MULmov a,PID_Temp1L ;PID加法子程序(将结果加入输出) add a,r7mov PID_Temp1L,amov a,PID_Temp1addc a,r6mov PID_Temp1,amov a,PID_TempLaddc a,r5mov PID_TempL,amov a,PID_Tempaddc a,r4mov PID_Temp,aclr c ;有符号减法mov a,PID_UL ;计算误差差的差(En-En1-En2),同时更新En2 subb a,PID_En2Lmov PID_En2L,amov a,PID_Usubb a,PID_En2mov PID_En2,amovr7,PID_KdL ;+Kd*(En-En1-En2)mov r6,PID_Kdmov r5,PID_En2Lmov r4,PID_En2acall PID_MULmov a,PID_Temp1L ;PID加法子程序(将结果加入输出) add a,r7mov PID_Temp1L,amov a,PID_Temp1addc a,r6mov PID_Temp1,amov a,PID_TempLaddc a,r5mov PID_TempL,amov a,PID_Tempaddc a,r4mov PID_Temp,apop pswpop accretret;//**************************************************************** **********************************************;//功能: 电机控制电流环的PI PI_I(void) 执行时间少于50uS/932-12MHz;//设计者: 牟联树;//日期: 2003.12.28;//版本号: 1.0;//申明:;//**************************************************************** **********************************************PUBLIC _PID_outRSEG ?PR?PID_out?PIDWork_PID_out: push accpush pswclr cmov a,r6rrc amov r6,amov a,r7rrc amov r7,aout_a: mov OCRAH,r6 ;PWM更新mov OCRAL,r7mov a,r7add a,#25mov OCRBL,amov a,r6addc a,#0mov OCRBH,aorl TCR21,#080h ;PWM更新out_b: pop pswpop accret;//**************************************************************** **********************************************;//功能: 整形乘法long int PID_MUL(int a,int b)用时13.5uS/932-12MHz;//设计者: 牟联树;//日期: 2003.12.28;//版本号: 1.0;//申明:;//**************************************************************** **********************************************PUBLIC _PID_MULRSEG ?PR?PID_MUL?PIDWork_PID_MUL:PID_MUL: push accpush pswclr f0 ;符号判断mov a,r4jb acc.7,PID_Masjmp PID_MdPID_Ma: setb f0mov a,r5cpl aadd a,#1mov r5,amov a,r4cpl aaddc a,#0mov r4,aPID_Md:; mov a,r6 ; mov c,acc.7;jnb f0,PID_Mf; cpl cPID_Mf:; mov f0,c ; jb acc.7,PID_Mb ; sjmp PID_McPID_Mb:; clr c; mov a,r7; subb a,#1; cpl a; mov r7,a; mov a,r6; subb a,#0; cpl a; mov r6,aPID_Mc: mov a,r5 mov b,r7 mul abxch a,r7mov r3,bmov b,r4mul abadd a,r3mov r3,amov a,baddc a,#0xch a,r5mov b,r6mul abaddc a,r3xch a,r6xch a,r5addc a,bxch a,r5mov b,r4mul abaddc a,r5mov r5,amov a,baddc a,#0mov r4,ajb f0,PID_Me pop psw pop accretPID_Me: mov a,r7cpl aadd a,#1mov r7,amov a,r6cpl aaddc a,#0mov r6,amov a,r5 cpl a addc a,#0 mov r5,a mov a,r4 cpl a addc a,#0 mov r4,a pop psw pop acc retEND。

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

51单片机PID算法程序(二)位置式PID控制算法
由51单片机组成的数字控制系统控制中,PID控制器是通过PID控制算法实现的。

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

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

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

于是传递函数可以简化为:
(2-4)其中
u(n)——第k个采样时刻的控制;
K P ——比例放大系数;
K i ——积分放大系数;
K d ——微分放大系数;
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算法的基本架构,没有包含输入输出处理部分。

#include <reg52.h>
#include <string.h> //C语言中memset函数头文件
/*========================================================== ==========================================
PID Function
The PID (比例、积分、微分) function is used in mainly
control applications. PIDCalc performs one iteration of the PID
algorithm.
While the PID function works, main is just a dummy program showing
a typical usage.
=========================================================== ==========================================*/
typedef struct PID {
double SetPoint; // 设定目标Desired value
double Proportion; // 比例常数Proportional Const
double Integral; // 积分常数Integral Const
double Derivative; // 微分常数Derivative Const
double LastError; // Error[-1]
double PrevError; // Error[-2]
double SumError; // Sums of Errors
} PID;
/*========================================================== ==========================================
PID计算部分
=========================================================== ==========================================*/
double PIDCalc( PID *pp, double NextPoint )
{
double dError, Error;
Error = pp->SetPoint - NextPoint; // 偏差
pp->SumError += Error; // 积分
dError = Error - pp->LastError; // 当前微分
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error // 比例项
+ pp->Integral * pp->SumError // 积分项
+ pp->Derivative * dError // 微分项
);
}
/*========================================================== ==========================================
Initialize PID Structure PID参数初始化
=========================================================== ==========================================*/
void PIDInit (PID *pp)
{
memset ( pp,0,sizeof(PID));
}
/*========================================================== ==========================================
Main Program 主程序
=========================================================== ==========================================*
double sensor (void) // Dummy Sensor Function
{
return 100.0;
}
void actuator(double rDelta) // Dummy Actuator Function
{}
void main(void)
{
PID sPID; // PID Control Structure
double rOut; // PID Response (Output)
double rIn; // PID Feedback (Input)
PIDInit ( &sPID ); // Initialize Structure
sPID.Proportion = 0.5; // Set PID Coefficients
sPID.Integral = 0.5;
sPID.Derivative = 0.0;
sPID.SetPoint = 100.0; // Set PID Setpoint
for (;;) { // Mock Up of PID Processing
rIn = sensor (); // Read Input
rOut = PIDCalc ( &sPID,rIn ); // Perform PID Interation
actuator ( rOut ); // Effect Needed Changes
}。

相关文档
最新文档