ad da实现pid闭环控制 pid的一个经典应用 对学习pid算法很有用

源代码在线查看: pid程序.c

软件大小: 4 K
上传用户: nihao464667180
关键词: pid ad 闭环控制 算法
下载地址: 免注册下载 普通下载 VIP

相关代码

				/***********************************************************************
				文件名:PID程序.C
				功能:  用PID算法闭环控制BANGK3区DAC0832的输出电压,通过设置年想要的输出
						电压,它通过ADC0804将O832的输出电压读回单片机进行PID自动调节,
						并经过短时间将DAC0832的输出电压升到设置的电压
						/此程序用的是位置式调节/
				作者:测控五组 ¤春暖花★开
				日期:2007/4/16/17:16
				版本:V1.0
				***********************************************************************/
				
				#include 
				#include 
				#include 
				#include 
				#include
				
				sbit ADC_INT = P3^2;
				code unsigned char Tab[10] ={0x0c0,0x0f9,0x0a4,0x0b0,0x99,0x92,0x82,0x0f8,0x80,0x90};
				typedef struct  
				 {
								
								        double  SetPoint;           /*  设定目标 Desired Value */
				 				
								        double  Proportion;         /*  比例常数 Proportional Const */
								        double  Integral;           /*  积分常数 Integral Const */
								        double  Derivative;         /*  微分常数 Derivative Const */
								
								        double  LastError;          /*  前一项误差 */ 
								        double  PrevError;          /*  前第二项误差 */
								        double  SumError;           /*  总误差 */
									
									} PID;
				unsigned char sensor () ;                  			 /*  传感器返回信号数据 **/
				void actuator(unsigned char rDelta);            	 /*  执行机构函数 */
				void Delay(unsigned char t);
				void display(unsigned char rIn);
				
				/****************************************************************************
				   PID计算部分
				****************************************************************************/
				
				double PIDCalc( PID *pp, double NextPoint )
				{
				    double  dError,Error;
				
				        Error = pp->SetPoint -  NextPoint;          /* 计算当前偏差 */
				        pp->SumError += Error;                      /* 积分《总偏差》*/
				        dError = pp->LastError - pp->PrevError;     /* 当前微分 */
				        pp->PrevError = pp->LastError;
				        pp->LastError = Error;						/*	三个误差值移位 */ 
				        return(NextPoint+pp->Proportion * Error + pp->Integral * pp->SumError + pp->Derivative * dError  );											/*《返回总的误差值》*/
				}
				
				/*******************************************************************************
				   主函数部分
				********************************************************************************/
				void main(void)
				{
				    PID         		sPID;                   	/*  定义PID结构体变量 */
				    double      		rOut;                   	/*  PID 响应输出 */
				    unsigned char       rIn;                    	/*  PID 反馈 (Input) */
					double 				x;
				    sPID.Proportion = 0.74;              			/*  设置 PID 比例系数 */
				    sPID.Integral   = 0.70;							/* 	设置PID积分系数 */
				    sPID.Derivative = 0.0;							/* 	设置PID微分系数 */
				    sPID.SetPoint   = 2.0;            		   		/*  设置 PID 输出值 */
				
				
				    for (;;) 
					{     	
						unsigned char      sumout;
				                     						/*  PID进入循环检测状态中 */
				        unsigned char i;
				        rIn = sensor ();                			/*  读传感器输出 */
						for(i=0;i						display(rIn); 
						x = 5.0 * (double)rIn / 256.0;	
				        rOut = PIDCalc ( &sPID,x );   				/*  计算PID 输出 */
					    sumout=rOut*256/5;
						actuator ( sumout );              			    /*  将要反馈的数据输出 */
					}
				}
				
				
				/*******************************************************************************
				程序名称:8位并行D/A芯片DAC0832
				*********************************************************************************/	
				void actuator(unsigned char rDelta)
				{
					
					XBYTE[0xA000] = rDelta;
					Delay(10);
				}
				
				 
				/*******************************************************************************
				函数:Delay()
				功能:延时0.01s~2.56s
				参数:t>0时,延时(t*0.01)s
				      t=0时,延时2.56s
				说明:定时10ms的定时器初值=65536-0.01/(1/(f/12)),其中f为晶振频率
				*******************************************************************************/
				void Delay(unsigned char t)
				{	
					TMOD &= 0xF0;
					TMOD |= 0x01;
					EA=1;
					EX0=1;
					do
					{
						TH0 = 0xee;								/* 设置定时器初值(定时5ms)*/
						TL0 = 0x00;
						TR0 = 1;								/* 启动定时器 */
						while ( !TF0 );							/* 等待定时器溢出 */
						TR0 = 0;								/* 停止定时器 */ 
						TF0 = 0;								/* 清除溢出标志 */
					} while ( --t != 0 );						/* 循环t次 */
				}
				
				
				unsigned char sensor (void) 
				{
					unsigned char v;
					Delay(30);
					XBYTE[0xB000] = 0xFF;						/* 启动A/D转换 */
					Delay(1);
					while ( ADC_INT );							/* 等待A/D转换完毕 */
					v = XBYTE[0xB000];							/* 读取A/D转换结果 */
					return (v);
				}
				
				void display(unsigned char rIn)
				{
					float num;
					int N;
					num=5.0*rIn/256;
					N=(int)(num*1000.0);
					XBYTE[0x8000]=0x08;
					XBYTE[0x9000]=Tab[N/1000]&0x7f;
					Delay(1);
					XBYTE[0x8000]=0x04;
					XBYTE[0x9000]=Tab[N%1000/100];
					Delay(1);
					XBYTE[0x8000]=0x02;
					XBYTE[0x9000]=Tab[N%100/10];
					Delay(1);
					XBYTE[0x8000]=0x01;
					XBYTE[0x9000]=Tab[N%10];
					Delay(1);}
							

相关资源