⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pid程序.c

📁 用PID算法闭环控制BANGK3区DAC0832的输出电压
💻 C
字号:
/***********************************************************************
文件名:PID程序.C
功能:  用PID算法闭环控制BANGK3区DAC0832的输出电压,通过设置年想要的输出
		电压,它通过ADC0804将O832的输出电压读回单片机进行PID自动调节,
		并经过短时间将DAC0832的输出电压升到设置的电压
		/此程序用的是位置式调节/
作者:测控五组 ¤春暖花★开
日期:2007/4/16/17:16
版本:V1.0
***********************************************************************/

#include <reg51.h>
#include <absacc.h>
#include <string.h>
#include <stdio.h>
#include<math.h>

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<50;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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -