51单片机PID的算法实现程序
- 格式:docx
- 大小:14.32 KB
- 文档页数:4
《自动控制原理》课程设计指导老师:邹恩年级专业: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算法。
PID算法是一种经典的控制算法,它能够根据系统的反馈信息,自动调整控制量,使系统的输出接近期望值。
PID算法由比例项(P 项)、积分项(I项)和微分项(D项)组成。
比例项用来根据当前误差大小调整控制量,积分项用来根据过去误差的累积值调整控制量,微分项用来根据误差的变化速度调整控制量。
在51单片机上实现PID算法,首先需要编写程序来读取系统的反馈信息和期望值。
例如,可以通过ADC模块读取传感器的信号,然后通过计算得到当前误差。
接下来,根据比例项、积分项和微分项的系数,计算PID控制量。
最后,将PID控制量输出到执行机构,例如电机或舵机,来控制系统的输出。
在编写PID算法程序时,需要注意一些细节。
首先,要根据实际系统的特点和要求来选择合适的PID参数。
比例项的系数决定了控制量对误差的敏感程度,积分项的系数决定了控制量对误差累积值的敏感程度,微分项的系数决定了控制量对误差变化速度的敏感程度。
其次,要注意处理PID算法中的积分项和微分项的累积误差。
积分项的累积误差可能会导致系统出现超调或震荡,需要适当地进行限制或清零。
微分项的累积误差可能会导致系统出现噪声放大或不稳定,需要进行滤波或限制。
最后,要注意程序的效率和实时性。
PID算法通常需要以一定的频率进行计算和更新,要保证程序能够及时响应系统的变化。
除了基本的PID算法,还可以根据具体的应用需求进行算法的优化和改进。
例如,可以引入自适应调整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的程序,希望能做到抛砖引玉,仅供大家参考。
/*/////////////////////////////////////////////////////////////*//* 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 单片机指令系统,掌握程序设计方法。
单片机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算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了,关于系数和采样电压全部是放大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控制算法前言在之前的两篇文章中,我们分别介绍了基础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单片机(也称为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)。
基于PID算法和51单片机的温度控制系统0 引言温控技术无论是在工业生产,还是日常生活中都起着非常重要的作用。
在冶金、石油、化工、电力和现代农业等行业,温度是极为重要而又普遍的热工参数之一,在普通家庭里热水器、电饭煲、电烤箱等依赖于温控技术的家电设备也是必不可少。
可以说温度控制技术无处不在。
常规的温度控制方法以设定温度为临界点,超出设定允许范围即进行温度调控:低于设定值就加热,反之就停止或降温。
这种方法实现简单、成本低,但控制效果不理想,控制温度精度不高、容易引起震荡,达到稳定点的时间也长,因此,只能用在精度要求不高的场合。
而采用PID 算法进行温度控制,它具有控制精度高,能够克服容量滞后的特点,特别适用于负荷变化大、容量滞后较大、控制品质要求又很高的控制系统。
单片机作为控制系统中必不可少的部分,在各个领域得到了广泛的应用,用单片机进行实时系统数据处理和控制,保证系统工作在最佳状态,提高系统的控制精度,有利于提高系统的工作效率。
本系统采用单片机编程实现PID 算法进行温度控制。
1 PID 控制的原理和特点在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID 控制,又称PID 调节。
PID 控制器以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。
当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型,控制理论的其他技术也难以采用,系统控制器的结构和参数必须依靠经验和现场调试来确定时,应用PID 控制技术最为方便。
PID 控制器的参数整定是控制系统设计的核心内容。
它是根据被控过程的特性确定PID 控制器的比例系数、积分时问和微分时间的大小。
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 方案一 选用铂电阻温度传感器。
式中或式中控制系统中的应用在单回路控制系统中,由于扰动作用使被控参数偏离给定值,从而产生偏差。
自动控制系统的调节单元将来自变送器的测量值与给定值相比较后产生的偏差进行比例、积分、微分(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反应速度更快并且没有了过冲。
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,用于控制系统的输出。
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 PUBLIC PID_Kp,PID_Ki,PID_Kd,PID_Umax,PID_Emax PUBLICPID_U,PID_En1,PID_En2,PID_Temp,PID_TempL RSEG ?DT?PID_k?PIDWorkPID_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 _PIDRSEG ?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),同时更新En2subb 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,r7mul 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 pswpop 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。
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算法的基本架构,没有包含输入输出处理部分。
51单片机PID程序(1)什么是PID控制器?PID控制器是一种常见的自动控制器,可以被广泛地应用于工业制造、机械控制、电子控制等领域。
PID控制器采用比例(P)、积分(I)和微分(D)等控制策略,实现对被控制对象的控制,可以使被控制对象的输出尽可能地接近预设值,从而实现自动控制的目的。
51单片机PID程序实现原理在51单片机中,开发者可以通过编写相应的程序实现PID控制。
其基本原理如下:1.取得被控制对象的实际值和期望值,计算出误差(设为E)。
2.根据比例控制策略,计算出比例项(设为P)。
3.根据积分控制策略,计算出积分项(设为I)。
4.根据微分控制策略,计算出微分项(设为D)。
5.将比例项、积分项和微分项加权求和,得到控制输出,控制被控制对象。
下面,我们来详细介绍如何在51单片机上实现PID控制。
PID控制器的代码实现为了方便开发者理解,在下面的代码中,我们将PID控制器分为三个部分:PID初始化、PID计算和PID输出。
/** PID控制器初始化* kp:比例系数* ki:积分系数* kd:微分系数* error_sum:误差总和(初始值为0)* last_error:上一次误差值(初始值为0)*/void PID_Init(float kp, float ki, float kd, float *error_sum, float *la st_error){*error_sum = 0;*last_error = 0;Kp = kp;Ki = ki;Kd = kd;}/** 计算PID控制量* target:期望值* pv:被控制对象的实际值* error_sum:误差总和* last_error:上一次误差值* 返回值:PID控制值*/float PID_Calc(float target, float pv, float *error_sum, float *last_er ror){float error = target - pv;float p = Kp * error;*error_sum += error;float i = Ki * (*error_sum);float d = Kd * (error - *last_error);*last_error = error;return p + i + d;}/** 控制被控制对象* pid_val:PID控制值*/void PID_Output(float pid_val){// 将pid_val用于控制被控制对象}PID控制器的调试方法在实际应用中,对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]; //正数和
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--;
}
}。