www.pudn.com > mohu.rar > CHAP10_3.CPP


//chap10_3.cpp 
//Real-time PID Control 
//Options->Linker->Libraries->Graphics Library 
//Copy c:\Borlandc\bgi\*.bgi files to the current directory 
//Copy the H file "chap10_3.h" to \include directory 
//Set:(1)c:\borlandc\include;(2)c:\borlandc\lib; 
#include        //Using sin() 
#include       //Using clrscr() and getch() and kbhit() 
#include  
#include       //Using sprintf() 
#include         //Using _disable() and _enable() 
#include  
#include        //Specially for std_fun bioskey() 
#include      //Using exit() 
#include    //Interupt parameters 
 
#define OUTPORT outportb 
#define INPORT  inportb 
#define T        500 
#define DD_PORT 0x380    //D/D board base address 
 
int channel=1;            //three frame: 0:inner; 1:middle; 2:outter 
int Signal=1;             //Sine Signal 
//int Signal=2;           //Step Signal 
 
double PositionCommand[TIMER_RATIO]; 
double Line1[TIMER_RATIO]; 
double CurrentPosition[TIMER_RATIO]; 
double Line2[TIMER_RATIO]; 
 
double A,F; 
double u=0.0,ts=0.001; 
double pi=3.14159265358979; 
double timezt=0; 
int flag=0; 
unsigned short    UpdateFlag=0; 
double mStep,mStep_1,Step,SaveStep=0;  //mStep_1(t)=mStep(t-10) 
//mStep must defined double 
unsigned short    ItemNum; 
unsigned short    TimerCount; 
unsigned long     Counter; 
 
unsigned short    flagF5; 
unsigned short    FinishSimulate; 
FILE *xyz; 
 
#define DD_PORT  0x380   //Inner frame 
void ResetShuXianBiao() 
{ 
     outport(DD_PORT,0x0); 
     outport(DD_PORT,0xf); 
     outport(DD_PORT+4,0x0); 
     outport(DD_PORT+4,0xf); 
     outport(DD_PORT+8,0x0); 
     outport(DD_PORT+8,0xf); 
} 
 
double angle_1; 
double ReadD_D(unsigned short channel) 
{ 
	unsigned short Data_H1,Data_L1,Data_H2,Data_L2; 
	long int data,angle_degree,angle_minute,angle_second; 
	double angle,angle1,errory; 
	do { 
	     Data_L1=inport(DD_PORT+4*channel); 
	     Data_H1=inport(DD_PORT+2+4*channel); 
	     Data_L2=inport(DD_PORT+4*channel); 
	     Data_H2=inport(DD_PORT+2+4*channel); 
	    }while((Data_L1!=Data_L2)||(Data_H1!=Data_H2)); 
 
	 data=((Data_H1 & 0x3f)*65536+Data_L1); 
	 angle1=data*0.9;       //Second per data 
	 if((Data_H1 & 0x80) ==0x80)  //nagative if Data_H.7 ==1 
	     angle1=-angle1; 
	 angle=angle1/3600.0;   //Change from Second to degree 
	 return(angle); 
} 
 
#define Da_Board  0x1A0 
void Write_DA(double dValue, int channel) 
{ 
   unsigned int hi,low,hilow; 
   int state; 
   double voltage; 
   voltage=dValue; 
   if(voltage>2.0)voltage=2.0; 
   if(voltage<-2.0)voltage=-2.0; 
   hilow=(unsigned int)((voltage)*65535/20); 
 
   hi=hilow&0xff00; 
   hi=hi>>8; 
   low=hilow&0xff; 
 
   outportb(Da_Board+0,channel); //Select channel 
   do 
	{ 
	 state=(inportb(Da_Board+0))&0x80; 
	} while(state==1);    //read bit D7; if D7=0 write data 
 
   outportb(Da_Board+1,low);   //write low byte 
   outportb(Da_Board+2,hi);    //write high byte 
   outportb(Da_Board+3,0);     //start da 
} 
 
int KbGetKey(int *ScanCode) 
{ 
     int Key; 
     int KeyCode; 
     Key=bioskey(0); 
     if((Key&0x00ff)==0) 
     { 
	 KeyCode=0; 
	 *ScanCode=(Key>>8)&127; 
     } 
     else 
     { 
	 KeyCode=Key&0xff; 
	 *ScanCode=0; 
     } 
     return(KeyCode); 
} 
 
int SavedFlag,SaveCounter; 
void SetupKeyReaction(void) 
{ 
     int Key,Scan; 
     if(kbhit()) 
     { 
	  Key=KbGetKey(&Scan); 
	 if (Key==KB_C_N_F5 && Scan==KB_S_N_F5) 
		{ 
		 SavedFlag=1; 
		 SaveCounter=0; 
		} 
	 if(Key==KB_C_A_X && Scan==KB_S_A_X) 
	 { 
	     FinishSimulate = 1; 
	 } 
     } 
} 
 
double huge DataSaved[DATA_DIMENTION][DATA_LENGTH]; 
void DataSaveRoutine( long int SaveSpan) 
{ 
	if(SavedFlag==1) 
	  { 
	    if((SaveCounter<=SaveSpan*DATA_LENGTH)) //DATA_LENGTH is Defined by chap10_3.h 
	     { 
		int SaveIndex = SaveCounter/SaveSpan; 
//Save data(rin,yout) to xyz.dat 
		DataSaved[0][SaveIndex]=PositionCommand[ItemNum]; 
		DataSaved[1][SaveIndex]=CurrentPosition[ItemNum]; 
	     } 
	   SaveCounter++; 
	   if(SaveCounter>=SaveSpan*DATA_LENGTH) { SavedFlag=0; SaveCounter=0; } 
	  } 
	 if(SavedFlag==0)  SaveCounter=0; 
} 
 
int M; 
double yout,error,derror; 
double u_1=0,u_2=0,y_1=0,y_2=0,error_1=0,error_2=0,ei=0; 
double Control(double rin,unsigned short channel) 
{ 
M=2; 
if( M==1)    //Realtime control 
{ 
yout=ReadD_D(channel);   //Read realtime data 
CurrentPosition[ItemNum]=yout; 
} 
if( M==2 )   //Simulation control 
{ 
yout=1.94*y_1-0.94*y_2+0.0008674*u_1+0.0008503*u_2; 
} 
 
CurrentPosition[ItemNum]=yout; 
yout=CurrentPosition[ItemNum]; 
 
F=0.50; 
A=0.010; if(A==0.0) { A=0.0001; } 
rin=A*sin(F*2*pi*timezt); 
error=rin-yout; 
 
u=10.0*error+1.0*derror+0*ei; 
//Update Parameters 
y_2=y_1;y_1=yout; 
u_2=u_1;u_1=u; 
error_2=error_1; 
error_1=error; 
 
return u; 
} 
int Cycles=5;  //Display cycle times 
void DynamicDisplay() 
{ 
     //Make a window 
     char   strA[50]; 
     int    i,Spoint; 
     int    bottom,middle,top,right,left; 
     bottom=300;middle=200;top=100;left=50;right=550; 
     setcolor(RED); 
     outtextxy(270,50,"PID Controller"); 
     line(left,top,left,bottom);        //lineleft 
     sprintf(strA,"%f",A*6.0/5.0); 
     outtextxy(36,top-10,strA); 
     line(left,top,right,top);          //linetop 
     outtextxy(36,middle,"0"); 
     line(left,middle,right,middle);    //linemiddle 
     sprintf(strA,"%f",-A*6.0/5.0); 
     outtextxy(36,bottom+5,strA); 
     line(left,bottom,right,bottom);    //linedown 
     line(right,top,right,bottom);      //lineright 
 
//Make Curve Range 
     for(i=0;i