使用DA卡控制电磁铁周期震动(修订版)

/*-----------------------------------------------
  Aj-psi.cpp
  This program is used to adjust the phase lag, i.e, psi
  of the vertical vibratioin while the other parameters
  i.e., frequency, vibration angle and vertical vibration
  amplitude remain unchanged.
------------------------------------------------*/

#define pi 3.1415926
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
#include <math.h>
#include <complex.h>

/*------------- Time Delay Subprogram ---------------*/
void udelay(int num)
 {
  int x,y;
  for(x=0;x<=10;x++)
  for(y=0;y<num;y++);
 }
/*----------- Time Delay Subprogram End -------------*/

/*------------- D-A Conversion Subprogram ------------*/
/*---------------------------------------------
  syntax: setAnalog0(intAddress,intData) &
   setAnalog1(intAddress,intData)
  where:  setAnalog0(intAddress,intData) for DA Channel0
   setAnalog1(intAddress,intData) for DA Channel1
   intAddress=The base address of the Super 14 ADDA Card
   intData=The data to be send out
   0=minimum voltage
   0X3fff=maximum voltage
  return: void
-----------------------------------------------*/
void setAnalog0(int intAddress,int intData)
{
 int lb,hb;
 lb=intData&0xff;
 hb=(intData&0x3f00)>>8;
 outportb(intAddress+5,hb);
 outportb(intAddress+4,lb);
}

void setAnalog1(int intAddress,int intData)
{
 int lb,hb;
 lb = intData &0xff;
 hb = (intData &0x3f00)>>8;
 outportb(intAddress+7,hb);
 outportb(intAddress+6,lb);
}
/*----------- D-A Conversion Subprogram End ----------*/

//int data0[100],data1[100];
int adata0[100],adata1[100];
float ds0[100],ds1[100];
float vm0[100],vm1[100];
int theAddress,theChannel;
int base825,i,a,j,dh,dl,k,d0,d1,ns,np,jj;
float f,ah,av,phs,vb0,vb1,s0,s1;
float kp0,ki0,kd0,e0,ep0,es0,u0,up0,ts;
float kp1,ki1,kd1,e1,ep1,es1,u1,up1;
float fp0,fp1,psi,anog,gama;
char ans;
static int fph0[36]={-50,-52,-54,-59,-74,-62,-58,-57,-56,-59,-59,-60,-60,-56,-56,-59,-208,-188,-237,-213,-229,-238,-242,-242,-245,-252,-254,-255,-258,-256,-256,-257,-214,-257,-258,-245};
static int fph1[36]={-56,-56,-57,-63,-79,-66,-61,-61,-61,-62,-63,-62,-63,-65,-66,-68,-69,-73,-75,-107,-185,-205,-203,-189,-186,-208,-216,-224,-230,-235,-241,-244,-246,-249,-250,-252};

 

/******************* MAIN PROGRAM *******************/
void main()
{
 clrscr();
 gotoxy(10,10);
 puts("PC-7429(AD),Super ADDA14(DA) and 8255-53(Timer&DI/O) Used");
 gotoxy(10,12);
 puts("TWO AD channels of PC-7429: Ch0&Ch1 for sampling");
 gotoxy(10,14);
 puts("TWO DA channels of Super ADDA14: Ch0&Ch1 for analog output");
 gotoxy(10,16);
 puts("8253 COUNTER 0 Mode 0, timing for sampling period");
 gotoxy(10,18);
 puts("8253 COUNTER 1 and 2 not used");
 gotoxy(10,20);
 puts("8255-1 Port-A Basic input mode 0x9b");
 gotoxy(10,22);
 puts("8255-2 Not used");
 puts(" ");
 theAddress=0x270;  //base address of SupperADDA14
 base825=0x300;     //base address of 8255-53 I/O

/*
 printf("Please input frequency f=");
 scanf("%f",&f);
 printf("Please input phase lag phs=");
 scanf("%f",&phs);
 printf("Please input vertical amplitude av=");
 scanf("%f",&av);
 printf("Please input horizontal amplitude ah=");
 scanf("%f",&ah);
 printf("Please input no. of sampling poits (<=100), ns=");
 scanf("%d",&ns);
 printf("Please input no. of periods for average amplitude, np=");
 scanf("%d",&np);
 printf("Please input PID parameter, kp0=");
 scanf("%f",&kp0);
 printf("Please input PID parameter, kp1=");
 scanf("%f",&kp1);
 printf("Please input PID parameter, ki0=");
 scanf("%f",&ki0);
 printf("Please input PID parameter, ki1=");
 scanf("%f",&ki1);
 printf("Please input PID parameter, kd0=");
 scanf("%f",&kd0);
 printf("Please input PID parameter, kd1=");
 scanf("%f",&kd1);
*/


 ns=100; np=50;
 kp0=0.04; kp1=0.08; ki0=0.04; ki1=0.08; kd0=0.01; kd1=0.01;
 gama=0-40+180;
 f=53; psi=25; gama=gama+240; anog=1.2;
  do
     {

 av=anog*9.8*10000/(2*pi*f*2*pi*f);
 ah=av/tan(psi*pi/180.0);
 printf("/n");
 printf("av=%fV, ah=%fV/n",av,ah);
 printf("f=%f, psi=%f, gama=%f, anog=%f/n",f,psi,gama,anog);
 printf("/n");

 if(f<48.0||psi<20.0)
   {kp0=0.01; kp1=0.02; ki0=0.008; ki1=0.04; kd0=0.03; kd1=0.01;}
 if(f>59.0)
   {kp0=0.01; kp1=0.04; ki0=0.04; ki1=0.04; kd0=0; kd1=0;}

/*---------- Calculate desired output signals-------*/
 ts=1/(f*ns);
 i=f-35;
 fp0=fph0[i]*pi/180.0;
 fp1=fph1[i]*pi/180.0;
 phs=gama*pi/180.0;
 if(f==53.0)
   {fp0=-238*pi/180.0;
    fp1=-73*pi/180.0;}

 for(i=0;i<ns;i++)
 {
// data0[i]=ah*sin(2.0*pi/ns*(float)i)/5.0*8191.0+8192.0;
// data1[i]=av*sin(2.0*pi/ns*(float)i+phs)/5.0*8191.0+8192.0;
 ds0[i]=sin(2.0*pi/ns*(float)i-fp0)/5.0*8191.0;
 ds1[i]=sin(2.0*pi/ns*(float)i-fp1+phs)/5.0*8191.0;


 }
/*-------- Calculate desired output signals End-----*/


/*------------- 8255 and 8253 mode setting ----------*/
 a=4750000/(f*ns); //timing constant
 dl=a&0xff;           //low 4 bits
 dh=(a&0xff00)>>8;    //high 4 bits
 outportb(base825+3,0x9b);  //8255 control mode0 reading
 outportb(base825+11,0x30); //8253 control timer0 mode0
/*----------- 8255 and 8253 mode setting End --------*/

/*------------ initialize  PC-7429 -------------*/
// sample program for :
// speed = 500KHZ
// block channel scan mode
// sampleing 2 channels, start channel=0, stop channel=1
// irq disable
// data length 1 points / channel
// using software start
// using inner clk-source
// base adress: 0x210

   // set mode
      // soft-trgiger to start , bit 0 = 0
      // clk , inner clk,   bit 1 = 0
      // irq disable ,  bit 2 = 0
      // stop channel is : 1, bit 4 - 7 = 0x1
   outp(0x213,0x10);

   // set start channel = 0
   outp(0x212,0);

   // set timer, F=500KHZ, data to timer is 2uS / 0.2 uS = 10
   outp(0x21f,0xb4);  // initial timer mode
   outp(0x21e,10);    // timer low 8bit
   outp(0x21e,0);     // high 8bit

   // set length counter, length = 2x1 = 2
   outp(0x21f,0x32);  // initial counter mode
   k=2;               // length
   j=k/256;           // high 8bit
   i=k-j*256;         // low 8bit
   outp(0x21c,i);     // latch low 8bit
   outp(0x21c,j);     // latch high 8bit
/*----------initialize PC-7429 over-------------*/

/*---------------Sending Analog Signals Loop------------*/

 i=0;  jj=0;  s0=0;  s1=0;
 e0=0; e1=0; es0=0; es1=0; ep0=0; ep1=0;up0=0;up1=0;

 outportb(base825+8,dl);
 outportb(base825+8,dh);  //timing for sampling period starts
 do{

/*--------------A to D Conversion---------------*/
     outp(0x216,0); // rewind the adress counter & system reset
//            udelay(100);
     outp(0x215,0); // start A-D conversion
     do{
        j=inp(0x212) & 1;
       }while(j!=0);  // if D0 = 0 , A-D conversion finished
     outp(0x216,0); // rewind the adress counter & system reset
//            udelay(100);
     d0=inpw(0x210); //read A-D channel0 convertion data
     d1=inpw(0x210); //read A-D channel1 convertion data
     vb0=(d0-2048)*5.0/2048-0.05;
     vb1=(d1-2048)*5.0/2048-0.02; //0.1V is used for sensor offset
     if(vb0>3.9)
       {printf("vb0>3.9V/n");
        break;}
     if(vb1>3.0)
       {printf("vb1>3.0V/n");
        break;}
/*--------------A to D Conversion End------------*/

     u0=kp0*e0+ki0*es0+kd0*(e0-ep0);
     u1=kp1*e1+ki1*es1+kd1*(e1-ep1);
     ep0=e0; ep1=e1;
     if(u0>=3.0)  u0=3.0;
     if(u0<=-3.0) u0=-3.0;
     if(u1>=2.0)  u1=2.0;
     if(u1<=-2.0) u1=-2.0;
     if(e0==0) u0=up0;
     if(e1==0) u1=up1;
     adata0[i]=u0*ds0[i]+8192;
     adata1[i]=u1*ds1[i]+8192;
     setAnalog0(theAddress, adata0[i]);
     setAnalog1(theAddress, adata1[i]);
     up0=u0; up1=u1;
//     udelay(70); //suit D-A output voltage settling

/*-----------To get the Amplitude of a Period-----*/
     if(i==0)
       {
        vm0[jj]=vb0;
        vm1[jj]=vb1;
        }
      else
        {
  if(vb0>=vm0[jj]) vm0[jj]=vb0;
  if(vb1>=vm1[jj]) vm1[jj]=vb1;
        }
/*---------To get the Amplitude of a Period End-----*/

     i=i+1;
     if(i>=ns)
       {
        i=0;      //ns--no. of sampling points in one cycle
        s0=s0+vm0[jj];
        s1=s1+vm1[jj];
        jj=jj+1;
       }
     if(jj>=np)
       {
        s0=s0/np;       s1=s1/np;
        e0=ah-s0;       e1=av-s1;
        s0=0;           s1=0;
        jj=0;
        if(e0>ah)  e0=ah;
        if(e1>av)  e1=av;
        if(fabs(e0)<=0.020) e0=0;
        if(fabs(e1)<=0.015) e1=0;
        es0=es0+e0;
        es1=es1+e1;
       }


/*------------- Sampling period timing UP? ----------*/
     a=inportb(base825+0);
     a=a&0x01;
     if(a==1)
     {
        printf("Time setting is not enough");
        break;
     }
     else
     {
        do{
    a=inportb(base825+0);
    a=a&0x01;
   }while(a!=1);
     }
/*----------- Sampling period timing UP!! ----------*/
     outportb(base825+8,dl);  //reset timer
     outportb(base825+8,dh);

     a=inportb(base825+0);  //check PA1 for user stop
     a=a&0x02;
     if(a==2) break;        //if PA1=1,stop loop

   }while(1<10);
/*-------------Sending Analog Signals Loop End----------*/
 printf("program stopped by immergency button/n");
 setAnalog0(theAddress, 8192);
 setAnalog1(theAddress, 8192);

 printf("Repeat,Next,Stop? Please key in R,N,or S/n");
 do
   {
    ans=toupper(getch());
    if(ans=='R') break;
    if(ans=='N')
      {psi=psi+2.5;
       break;}
    if(ans=='S') exit(0);
   }while(1<10);
 if(psi>80.0) exit(0);
 delay(500);

    }while(1<10);

}
/***************** MAIN PROGRAM End *****************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值