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

📄 purpid.c

📁 2407PID控制程序(附加VB控制界面)超爽!
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************/

#define DAC0	  0	    /* 1st digital to analog converter	*/
#define DAC1	  1	    /* 2nd digital to analog converter	*/
#define DAC2	  2	    /* 3rd digital to analog converter	*/
#define DAC3	  3	    /* 4th digital to analog converter	*/
#define DAC_XFER  4	    /* transfer data */
#define DAC41      4 
#define DAC4      0ch
#define DAC8      0008h
/*
  Macro Expansion Declarations
*/
#define _DAC_BASE  0h

/*
  Write Only
*/
#define _DAC0     _DAC_BASE+0		    /* 1st digital to analog converter	*/
#define _DAC1     _DAC_BASE+1		    /* 2nd digital to analog converter	*/
#define _DAC2     _DAC_BASE+2		    /* 3rd digital to analog converter	*/
#define _DAC3     _DAC_BASE+3		    /* 4th digital to analog converter	*/
#define _DAC_XFER _DAC_BASE+4         /* transfer data */
#define _DAC4     0ch
#define _DAC8     0008h
/*
  Macro definitions
*/

#define ISRA          0x7094
#define ISRB          0x7096

#define PADATDIR      0x7098

#define PBDATDIR      0x709A

#define PCDATDIR      0x709C

/******************************************************************************/

int avera[5]={0,0,0,0,0};

volatile  unsigned int  * m ;

int        YI;
float q; 

unsigned int dac_vals[4];

   
 /******************************************************************************/  
   /* define varies inorder to get the average output speed , every six time */  

int average(int y) 
 {
 int average1    ;
 avera[0]=avera[1];
 avera[1]=avera[2]; 
 avera[2]=avera[3];
 avera[3]=avera[4];
 avera[4]=y;
 average1=(int)(0.1*avera[0]+0.2*avera[1]+0.4*avera[2]+0.2*avera[3]+0.1*avera[4]); 
 avera[4]=average1;
 return average1;
 }  
 
 
/*屏蔽中断子程序*/ 
void inline disable()
{
  asm(" setc INTM");
       
}   
  

/* 开总中断子程序*/
void inline enable()
{ 
	asm(" clrc INTM ") ;
	
} 
/*系统初始化子程序*/
void initial()
{
	asm(" setc SXM");    /* 符号位扩展有效 */
	asm(" clrc OVM");    /*累加器中结果正常溢出*/
	asm("  clrc CNF");   /*B0 被配置为数据存储空间*/ 
/*	* SCSR1=0x81FE  ;  */  /*CLKIN=6 M,CLKOUT=4 * CLKIN=24 M*/     
 *(volatile unsigned int*)SCSR1 = 0x81FE;
	* WDCR =0X0E8   ;    /* 不使能看门狗,因为SCSR2中的WDOVERRIDE*/
	                     /*即WD保护位复位后的缺省值为1,故可以用*/
                         /*软件禁止看门狗*/
    *IMR=0x0001  ;       /*容许INT1中断*/
	*IFR=0x0FFFF ;        /*清除全部中断标志,"写1清0"*/
}

 /* AD初始化程序 */
 void ADINIT()
 {     
     int i;
	 *T4CNT=0X0000;         /* T4计数器清0部件*/
     *T4CON=0X170C;         /* T4为连续增计数模式,128分频,且选用内部时钟源*/
	 *T4PER=0X75;           /* 设置T4的周期寄存器*/
	 *GPTCONB=0X400;         /* T4周期中断标志触发AD转换*/
	 *EVBIFRB=0XFFFF;       /* 清除EVB中断标志,"写1清0"*/
	 /*ADCTRL1=0X10          /* 采样时间窗口预定标位为ACQ PS3~ACQ PS0为0*/
     *ADCTRL1=0X10;         /*转换时间预定标位CPS为本0,AD为起动/停止模式*/
	                        /* 排序器为级联工作方式,且禁止特殊的两种工作模式*/
	 *ADCTRL2=0X8404;         /* 可以用EVB的一个事件信号触发AD转换*/
		                      /* 且用中断模式1*/
     *MAXCONV=0X00;           /* 16通道*/
	 *CHSELSEQ1=0X3211;
     *CHSELSEQ2=0X7654;
     *CHSELSEQ3=0X0ba98;
	 *CHSELSEQ4=0X0fedc;       /* 转换通道是0~15*/
     for(i=0;i<24;i++)
	    {pcdata[i]=0;}          
 }  
 
 /* 启动AD转换子程序(通过启动定时器4的方式间接启动)*/
 void ADSOC()
 {
 *T4CON=*T4CON|0x40 ;         /*启动定时器4*/
 }  
 
  
/*AD中断服务子程序*/   
   int flag =0    ;  
   int  k=0;
   int  j=0 ;  
   int as=0;        /*抑制符号位扩展*/ 
   int fan=0;  
   int x=0  ;    
 /*********/      
 
/*给上位机送参数*/ 
void sendpc(float value,int charr) 
{ 
int mid; 
me=charr;
uart();  

mid=value/10;
me=mid+48;
uart(); 

me=value-mid*10+48;
uart();   
} 

void interrupt adint()
{  
  while(fan<0x0f)
 { 

  INMAC(_DAC8,as); /*关断DSP*/ 
  asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" ); 
 if(as==0x02) 
 {
 fan=0xff;
 } 
 
  /* Y=2.0;
   hd=0;
   hi=0.25;       
   p=5;       */
   m=RESULT0;           
   YI=*m>>6; 
    
    
  q=average(YI) ;        
   
  backspeed=q/1023*3.3; 
  error[0]=error[1];
  error[1]=error[2];
  error[2]=1.0-backspeed;  

  mide1= error[2]-error[1];
  mide2= error[2]-2*error[1]+error[0]; 
  mide3=(mide3+error[2]);    
                                          
                                            
  runspeed=runspeed+(kp*mide1+ki*error[2]+kd*mide2);
                    
  
  /*mul=error[2]*backspeed;*/

    
 if( runspeed >2.5)  runspeed = 2.5;                 /* 过电压时保护调节 */
 if( runspeed <0)  runspeed = 0 ;      
 j=(int)(runspeed/2.5*4095);    

  /*******************************/  
   midv=q*3.3/1023 ;  
      /*midv=5.666;*/  
  me =72 ; 
  uart();      
      
 fpart=modf(midv , &ipart) ;      
    me =ipart+48 ;    
    uart();  
       
    fpart1 =(midv-ipart)*10  ; 
    modf(fpart1 , &ipart1) ;
    
     me =ipart1+48 ; 
      uart();    
      
   fpart2 =(midv-ipart-(ipart1/10))*100  ; 
    modf(fpart2 , &ipart2) ;
  
      me =ipart2+48 ; 
      uart();    
     
     fpart3 =(midv-ipart-(ipart1/10)-(ipart2/100))*1000  ; 
     modf(fpart3 , &ipart3) ;
         
     me =ipart3+48 ; 
     uart();                
   
     
    pidi=kp;  
    pidf=(kp-pidi)*100;    
    sendpc(pidi,80);     
    sendpc(pidf,81);   
    
    pidi=ki;  
    pidf=(ki-pidi)*100;    
    sendpc(pidi,73);     
    sendpc(pidf,74); 
      
    pidi=kd;  
    pidf=(kd-pidi)*100;    
    sendpc(pidi,68);     
    sendpc(pidf,69) ; 
        
    wait_ms(2);   
     /*取一个字符*/                
     getchar=uart1_get_char();
    /********************************/ 
     OUTMAC( _DAC0, j); 
 for(x=0;x<=434;x++)
 {        
       asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" ); 
 }   
    OUTMAC( _DAC_XFER, j);      /* just need a write, any data */                   
    OUTMAC( _DAC4,j);          /* 实验现象*/ 
 for(x=0;x<=434;x++)
 {    
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" ); 
  }      
   }
 j=0;                     /*程序结束*/
        OUTMAC( _DAC0, j); 
  for(x=0;x<=34;x++)
 {    
        asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    asm("    nop" );
    OUTMAC( _DAC_XFER, j);      /* just need a write, any data */                   
  
  }                        
   *ADCTRL2=*ADCTRL2|0X4200;   /*复位SEQ1,且清除INT FLAG SEQ1 标志 "写1清0"*/ 
  flag=1;
  enable();                       /*开总中断,因为一进入中断总中断就自动关闭了*/
}
 

main()
{   
    unsigned int uart_ctr;
	disable() ;                /*禁止总中断*/  
	initial() ;                /*系统初始化*/
	ADINIT()  ;                /*AD初始化子程序*/ 	 
	test_init();               /* init variables & hardware */ 
    init_uart1();              /* set up uart 9600, no parity, 1 stop */

    uart_ctr = wait_ms(2); 
     
    enable() ;                 /*开总中断*/ 
	ADSOC();                 /*启动AD转换*/
     
	/*while(1)
	/*{
	/*	if(flag==0x1) break ;      /*如果已发生中断,则停止等待(发生中断后,i=0x1)*/
	/*}                            /*等待中断发生*/
	/*T4CON=*T4CON&0X0FFBF; /* stop定时器4 ,即间接停止A/D转换*/
    
    
}





⌨️ 快捷键说明

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