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

📄 89c52电流采集.c

📁 使用51实现的高速电流下降沿记录
💻 C
字号:
_MDEL_=0;                              //small编译模式

/*****************文件包括******************/
#include<reg52.h>
#include<absacc.h>
#include <intrins.h>

/*****************宏定义******************/
#define uchar unsigned char
#define uint  unsigned int
#define tranad    0X7000                                //传输数据存放在ram中的首地址
#define r6264     0X8000                                //6264首地址
#define fifo1     XBYTE[0XC000]                         //fifo1 地址
#define fifo2     XBYTE[0XE000]                         //fifo2 地址

/*****************函数说明******************/

/*****************intrins.h内包括的函数******************/
void _nop_(void);                                       //空操作函数
unsigned char _cror_(unsigned char val,unsigned char n);//右移函数

/*****************自定义函数******************/
void delay(uint time);                                  //延时时间为(time*2+2)
void initsys(void);                                     //系统初始化
void resetfifo(void);                                   //复位FIFO
void resetram(void);                                    //ram初始化
void writeram(uchar ctime,uint dnumw);                             //把从FIFO读的数据写到RAM
void startad(void);                                     //跟下降沿取得同步就启动采集
void averdata(uchar avertime,uint dnuma);               //叠加后取平均
void mazhizhuanhuan(uint dnum,uint datanum);            //把从000-fff编码的数据转换成从800-7ff的编码
void readram(uint qsaddr);                //把从RAM的数据传送给PC机
void transmitdata(void);                                //传送ASCII缓冲区的内容给PC机
void startadt(void);                                    //采集电流下降沿,计算下降时间
void mazhinihuan(uint dnumn,uint datanumn);             //码制逆转换
void avcurret(void);                                    //取平均电流并传数
void timecm(void);                                      //关断时间计算程序


/*****************管脚定义*******************/
sbit AD_START=P1^0;                                     //ad采集信号
sbit FIFO_RS=P1^1;                                      //FIFO 复位信号
sbit LEDRED=P1^2;                                       //红灯显示
sbit LEDGREED=P1^3;                                     //绿灯显示
sbit PC_TEM=P1^4;                                       //通信选择信号
sbit TBOUT=P1^5;                                        //同步信号
sbit ASRESET=P1^6;                                      //fifo辅助复位信号
sbit MODE=P1^7;                                         //模式选择
sbit key=P3^3;                                          //按键信号
sbit elect_r=P3^4;                                      //反馈电阻的选择(放大倍数选择)

/*****************变量定义***************************/
uchar data yxxhtime;                                    //采集次数

/*****************主函数***************************/
void main(void)
{
 mainstart:
     AD_START=1;
     SP=0x60;
     yxxhtime=0;
     initsys();
     resetfifo();                                   //FIFO复位
     startad();                                      //与tem_单片机通信
/*****************测量电流和关断时间******************/
         for(yxxhtime=0;yxxhtime<14;yxxhtime++)          //直到有效的循环次数为14时才停止采集与叠加
         {
         resetfifo();                                   //FIFO复位
         startad();                                     //开始采集
         writeram(yxxhtime,200);                            //写存储器
         }//end for 14 times
         averdata(yxxhtime,100);                            //取平均值
         avcurret();
         mazhinihuan(1000,1);
         readram(1000);
/*****************测量关断时间******************/
         for(yxxhtime=0;yxxhtime<14;yxxhtime++)
        {
         resetfifo();                                   //FIFO复位
         startadt();                                    //开始采集
         writeram(yxxhtime,1000);                                   //写存储器
        }// end for
         averdata(yxxhtime,500);
         timecm();
         transmitdata();
     goto mainstart;                                    //循环
}
/*****************主函数结束******************/

/*****************子函数定义******************/
 void delay(uint time)                                  //延时时间为(time*2+2)
 {
  uint data s;
  for(s=0;s<time;s++)
  _nop_();
 }

 void initsys(void)                                     //系统初始化
 {
  P0=0xff;                                              ////////
  P1=0xff;                                              //可有//
  P2=0xff;                                              //可无//
  P3=0xff;                                              ////////
  PC_TEM=0;
  AD_START=1;
  TR0=TR1=0;
  TF0=TF1=0;
  PC_TEM=0;                                             //选择和tem控制板通讯
  TMOD=0x21;                                            //定时器0方式1,定时20ms左右
  TH0=0xdd;                                             //定时20ms
  TL0=0x00;
  PCON=0x00;
  TH1=0xf4;//fd;//fa;                                   //波特率为2400//9600//4800
  TL1=0xf4;
  TR1=1;                                                //启动定时器1
  SCON=0x40;                                            //设置串行口为10位异步收发,不允许接收
  TI=0;
  }

 void resetfifo(void)                                   //复位FIFO
 {
     FIFO_RS=1;
     delay(5);
     ASRESET=0;
     delay(5);                                          //复位fifo
     AD_START=1;
     delay(5);                                          //fifo复位的时候,R,W都要是高电平
     FIFO_RS=0;
     delay(5);
     delay(5);
     delay(5);
     FIFO_RS=1;
     delay(5);
     delay(5);
     ASRESET=1;
     delay(5);
     delay(5);
  }
/*****************采集程序定义******************/

/*****************采集程序1******************/
  void startad(void)
  {
     TBOUT=1;                                           //检测同步信号
     do{_nop_();}while(TBOUT==0); //0
     //TBOUT=1;
     do{_nop_();}while(TBOUT==1); //1  //上升沿采集
     delay(150); //150              //38ms
     AD_START=0;                  //开始采集
     delay(3200);
     AD_START=1;                  //采集结束
  }



/*****************采集程序2******************/
  void startadt(void)              //用于采集下降沿时间
  {
     TBOUT=1;                      //检测同步信号
     do{;}while(TBOUT==1);   //1
     //TBOUT=1;
     do{;}while(TBOUT==0);   //0     //下降沿开始采集
     AD_START=0;                  //开始采集
     delay(3200);
     AD_START=1;                  //采集结束
  }


/*****************写ram程序******************/
 void writeram(uchar ctime,uint dnumw)        //把从FIFO读的数据写到RAM (读了500个数据)
 {
     uint data i;
     uchar data databuf;
     _nop_();
     databuf=fifo1;
     databuf=fifo2;                             //把fifo中前2个无效数据丢弃
     databuf=fifo1;
     databuf=fifo2;
     if(ctime==0)
   {
     for(i=0;i<dnumw;i++)
     {
     databuf=fifo2;
     XBYTE[i]=databuf;
     i++;
     databuf=fifo1;
     _nop_();
     XBYTE[i]=databuf;
     _nop_();
     }//end for

     mazhizhuanhuan(0,dnumw/2);  //转换

   }//end if

   else
   {
    for(i=0;i<dnumw;i++)//for 2
      {
     databuf=fifo2;
     _nop_();
     XBYTE[i+1000]=databuf;
     i++;
     databuf=fifo1;
     _nop_();
     XBYTE[i+1000]=databuf;
     _nop_();

      }//end for2

       mazhizhuanhuan(500,dnumw/2); //转换

       for(i=0;i<dnumw/2;i++) //for 3 //叠加
       {
        int  data number1,number2;
        number1=XWORD[i];
        number2=XWORD[i+500];
        number1=number1+number2;
        XWORD[i]=number1;
        _nop_();

       }//end for3
   }//end else

 }

/*****************码制转换程序******************/
void mazhizhuanhuan(uint dnum,uint datanum)
  {
      uint data i=0;
      uint data datatemp;
      datatemp=((XWORD[2+dnum]+XWORD[4+dnum]+XWORD[6+dnum]+XWORD[8+dnum])/4);
      if((datatemp&0x0fff)>0x0800)                                       //整体是负值
        {  for(i=0;i<datanum;i++)
          {
          datatemp=XWORD[i+dnum];
          datatemp=(0x1000-datatemp);

           if((datatemp&0x0fff)<0x0800)
          {
              datatemp=datatemp|0x0800;
              XWORD[i+dnum]=datatemp&0x0fff;
          }//end if
          else
          {
              datatemp=datatemp&0x07ff;
              XWORD[i+dnum]=datatemp&0x0fff;
          }//end else


          }//end for
        }//end if

     else                                       //整体是正值
     {
       for(i=0;i<datanum;i++)
        {
          datatemp=XWORD[i+dnum];
       if((datatemp&0x0fff)<0x0800)
          {
              datatemp=datatemp|0x0800;
              XWORD[i+dnum]=datatemp&0x0fff;
          }//end if
          else
          {
              datatemp=datatemp&0x07ff;
              XWORD[i+dnum]=datatemp&0x0fff;
          }// end else
        }//end for
     }//end else

        delay(2);
  }


/*****************电压计算程序******************/
void readram(uint qsaddr)                 //把从RAM的数据计算并存入到指定空间
 {
     uint data temp1;
     uint data templong;
//     uint data i;
     float data fdata;

     _nop_();
//     for(i=0;i<datalong;i++)
//     {
       temp1=XWORD[qsaddr];
       if(temp1>=0x0800)                 //判断正负号
           {
              XBYTE[tranad+0]='-';
               temp1=0x1000-temp1;
          }
       else
           XBYTE[tranad+0]=' ';                  //dd.d
           fdata=temp1;                      //把十六进制数变换成实际电压值
           fdata=fdata*100*140/4096; //1000*10/4096;//100*125/4096; //19 1000*10/4096;//    //10
           XBYTE[tranad+8]='.';
           templong=fdata;
           XBYTE[tranad+6]=templong/1000+0x30;
           if(XBYTE[tranad+6]==0x30)
           XBYTE[tranad+6]=' ';
           templong=templong%1000;
           XBYTE[tranad+7]=templong/100+0x30;
           templong=templong%100;
           XBYTE[tranad+9]=templong/10+0x30;
           templong=templong%10;
           XBYTE[tranad+10]=templong+0x30;
//     }
   }

/*****************数据传输程序******************/
void transmitdata(void)               //传送ASCII缓冲区的内容给tem控制板
{      uchar data bufs;
       uchar data i=0;
       SBUF=0x0f;
       _nop_();
       while(TI==0);TI=0;
       SBUF=0x00;
       _nop_();
       while(TI==0);TI=0;

       for(i=1;i<11;i++)
       {  _nop_();
          bufs=XBYTE[tranad+i];
          bufs=bufs&0xf0;
          bufs=_cror_(bufs,4);
          SBUF=bufs;
          _nop_();
          while(TI==0);TI=0;
          bufs=XBYTE[tranad+i];
          SBUF=bufs&0x0f;
          _nop_();
          while(TI==0);TI=0;
       }
    }

/*****************数据平均程序******************/
void averdata(uchar avertime,uint dnuma)
  {
      uint data i=0;
      uint data k=0;
//      uchar data j=avertime;
//      delay(2);
      for(i=0;i<dnuma;i++)
      {  k=XWORD[i];
         XWORD[i]=(k/avertime)&0x0fff;
      }

  }
/*****************码制逆转换程序******************/
 void mazhinihuan(uint dnumn,uint datanumn)
 {  uint data i,dtemp;
   for(i=0;i<datanumn;i++)
   {
   dtemp=XWORD[i+dnumn];
      if(dtemp>=0x0800)
        {
         XWORD[i+dnumn]=(dtemp&0X07ff);
        }//end if
      else
        {
         XWORD[i+dnumn]=(dtemp|0x0800)&0x0fff;
        }//end else
   }//end for
}//end mazhinihuan


/*****************电流平均程序******************/
void avcurret(void)
{
      //uint data cucount=0;
      //uint data cucount1=0;
      float data avdata=0;
      uchar data cutime;
      _nop_();
      //mazhizhuanhuan(0,14);
     for(cutime=0;cutime<100;cutime++)
     {
         avdata=avdata+XWORD[cutime];
      }
     XWORD[1000]=avdata/100;
} //end avcurrent

/*****************关断时间计算程序******************/
void timecm(void)
{
// char data temp3;
 uint data i,timedata;
 i=0;
while((XWORD[i]>0x0808)&&(i<500))
{
   i++;
 }//end while

 if((i>499)||(XBYTE[tranad+6]==' '&&XBYTE[tranad+7]==0x30&&XBYTE[tranad+9]<0x32))
 {
  //overtime=0x0f0f;
  timedata=0x0000;
  }//end if i>499
  else
  {
    //overtime=0x0505;
    timedata=i;
   }//end else
   XBYTE[tranad+1]=timedata/100+0x30;
   //temp3=XBYTE[tranad+1];
   if(XBYTE[tranad+1]==0x30)
   XBYTE[tranad+1]=' ';
   timedata=timedata%100;
   XBYTE[tranad+2]=timedata/10+0x30;
   if((XBYTE[tranad+1]==' ')&&(XBYTE[tranad+2]==0x30))
   XBYTE[tranad+2]=' ';
   timedata=timedata%10;
   XBYTE[tranad+3]=timedata+0x30;
   XBYTE[tranad+4]='.';
   XBYTE[tranad+5]=0x30;
 }





⌨️ 快捷键说明

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