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

📄 ad_max197.h

📁 51单片机控ADC(MAX197)采集数据
💻 H
字号:
//#include<absacc.h>
#include<math.h>
#include"lcd_12864.h"
//说明:如不做成函数形式,只获取AD值,不做处理,速度可达到100K。
#define AD_SAMPLE_HIGH XBYTE[0xfa00]
#define AD_SAMPLE_LOW  XBYTE[0xf200]
#define VREF 4096

//uchar AD_Convert=0;
sbit AD_Convert=P1^7;

//void Dispnumber(uint number,uchar j,uchar x,uchar y);
//void Disponechar(unsigned char x,unsigned char y, char character);
//void Dispnumber_long(ulong number,uchar j,uchar x,uchar y);

/****************************************
函数名称:void AD_MAX197(uchar channel,uchar sample_range)
函数功能:采集数据并将转换值的绝对值返回,数据的正负用FLAG标识。
函数说明:此函数为双极性采样,即可采集正负电压,工作方式只可选择 1:-5~5V, 3:-10~10V。
创建日期:07.08.03晚21:00
****************************************/
uint AD_MAX197(uchar channel,uchar sample_range)
//channel为通道选择控制字,sample_range为采样范围控制字(0:0~5V, 1:-5~+5V, 2:0~10V, 3:-10~+10V)
{  bit flag;
   uchar CMD;
   uchar high_4,low_8;
   uint  convert_number;
   CMD=(sample_range*8+channel)|0X40;
   XBYTE[0xfa00]=CMD;           //置控制字
   while(AD_Convert==0);
   AD_Convert=0;

   high_4=AD_SAMPLE_HIGH;        //接收高四位, P2_3=1; P22,P21,P20控制片选选通
   low_8=AD_SAMPLE_LOW;         //接收低八位, P2_3=0; P22,P21,P20控制片选选通

   if(high_4>0x0f)  { high_4=0x0f-(high_4&0x0f); low_8=0x0100-low_8; flag=1;}  //处理采集负电压时得到的补码
   else  flag=0;
   convert_number=high_4*256+low_8;

   switch(sample_range)
   {
       case 1:convert_number=convert_number*2;break;
	   case 2:convert_number=convert_number*2;break;
	   case 3:convert_number=convert_number*4;break;
	   default: break;
   }
   return convert_number; 
}

/****************************************
函数名称:void AD_MAX197_Bipolar(uchar channel,uchar sample_range)
函数功能:计算采样的均值,有效值,峰峰值。
函数说明:此函数为双极性采样,即可采集正负电压,工作方式只可选择 1:-5~5V, 3:-10~10V
创建日期:07。08。05日17:00
****************************************/

void AD_MAX197_Bipolar(uchar channel,uchar sample_range)
{
   uchar AD_CMD, AD_Vph_high=0, AD_Vph_low=0, AD_Vpl_high=0, AD_Vpl_low=0;
   uchar high_4,low_8;
   ulong AD_High_rms=0, AD_Low_rms=0, sum_rms; 
   long  AD_High_ave=0, AD_Low_ave=0, sum_ave;
   //每一次进入函数计算注意要将上次计算值清零
   uint  vpp,count=0, ave, rms;
   AD_CMD=(sample_range*8+channel)|0X40;

   while(1)
   {
     XBYTE[0xfa00]=AD_CMD;           //置控制字
     while(AD_Convert==1);
    // AD_Convert=0;
     
     high_4=AD_SAMPLE_HIGH;        //接收高四位, P2_3=1; P22,P21,P20控制片选选通
     low_8=AD_SAMPLE_LOW;         //接收低八位, P2_3=0; P22,P21,P20控制片选选通

     if( (high_4&0xf0)==0xf0 ) 
	   {   
            high_4=0x0f-(high_4&0x0f);
            low_8=0xff-low_8;          //处理采集负电压时得到的补码
	        AD_High_ave=AD_High_ave - high_4;
            AD_Low_ave =AD_Low_ave  - low_8;   

	        if( (high_4 > AD_Vpl_high) || ( (high_4==AD_Vpl_high)&&(low_8 > AD_Vpl_low) ) )
           {
               AD_Vpl_high = high_4;
	           AD_Vpl_low  = low_8;
	       }                          //峰峰值更新

	    }
     else 
	   {
           AD_High_ave=AD_High_ave +  high_4;
           AD_Low_ave =AD_Low_ave +  low_8;

           if( (high_4 > AD_Vph_high) || ( (high_4==AD_Vph_high)&&(low_8 > AD_Vph_low) ) )
            {
               AD_Vph_high = high_4;
	           AD_Vph_low  = low_8;
	        }

       }

         AD_High_rms = AD_High_rms + high_4*high_4;
         AD_Low_rms  = AD_Low_rms  + low_8*low_8 + (long)512*high_4*low_8;    //有效值计算
         //此处512不变成(LONG)型会对均值的计算产生影响??????
         count++;
         if(count==2000) break;    //采样值不宜超过三千,以防止计算有效值时数据溢出。
   }
    vpp=AD_Vph_high * 256 + AD_Vph_low + AD_Vpl_high * 256 + AD_Vpl_low;  
	                                                //峰峰值处理

    AD_High_rms=AD_High_rms/count;
	AD_Low_rms =AD_Low_rms /count;  
    sum_rms=(ulong)(AD_High_rms*65536+AD_Low_rms);
    rms=sqrt(sum_rms);                          	//有效值处理

    sum_ave=AD_High_ave*256+AD_Low_ave;
	if(sum_ave<0){ sum_ave=(-1)*sum_ave; Disponechar(1,2,'-');}
	else  Disponechar(1,2,'+');
	ave=sum_ave/count;                              //均值处理


    if( (AD_CMD&0x18)==0x08 ) { ave=ave*2; rms=rms*2; vpp=vpp*2; }  //如果选择-5~~+5v量程,应在计算上乘以2
    if( (AD_CMD&0x18)==0x18 ) { ave=ave*4; rms=rms*4; vpp=vpp*4; }  //如果选择-10~~+10v量程,应在计算上乘以4
    vpp=(uint)(vpp*1.2207);
    ave=(uint)(ave*1.2207);
    rms=(uint)(rms*1.2207);

    LcdPrintf(2,1,"vpp:");
    LcdPrintf(2,2,"ave:");
	LcdPrintf(2,3,"rms:");
	Dispnumber_float(vpp,4,3,10,1);
    Dispnumber_float(ave,4,3,10,2);
    Dispnumber_float(rms,4,3,10,3);                 //显示
}


/****************************************
函数名称:void AD_MAX197_Polar(uchar channel,uchar sample_range)
函数功能:计算采样的均值,有效值,峰峰值。
函数说明:此函数为单极性采样,即只采集正电压时的算法,工作方式只可选择 0:0~5V, 2:0~10V
创建日期:07。08。04日21:00
****************************************/
/*
void AD_MAX197_Polar(uchar channel,uchar sample_range)
{
   uchar AD_CMD, AD_Vph_high=0, AD_Vph_low=0, AD_Vpl_high=255, AD_Vpl_low=255;
   uchar high_4,low_8;
   ulong AD_High_ave=0, AD_Low_ave=0, AD_High_rms=0, AD_Low_rms=0, sum_ave, sum_rms;   
   //每一次进入函数计算注意要将上次计算值清零
   uint  vpp,count=0, ave, rms;
   AD_CMD=(sample_range*8+channel)|0X40;

   while(1)
   {
     XBYTE[0xfa00]=AD_CMD;           //置控制字
     while(AD_Convert==0);
     AD_Convert=0;
     
     high_4=XBYTE[0xfa00];        //接收高四位, P2_3=1; P22,P21,P20控制片选选通
     low_8=XBYTE[0xf200];         //接收低八位, P2_3=0; P22,P21,P20控制片选选通

     AD_High_ave = AD_High_ave + high_4;
     AD_Low_ave  = AD_Low_ave  + low_8;      //均值累加计算
     
	 if( (high_4 > AD_Vph_high) || ( (high_4==AD_Vph_high)&&(low_8 > AD_Vph_low) ) )
    {
      AD_Vph_high = high_4;
	  AD_Vph_low  = low_8;
	}

	 if( (high_4 < AD_Vpl_high) || ( (high_4==AD_Vpl_high)&&(low_8 < AD_Vpl_low) ) )
    {
      AD_Vpl_high = high_4;
	  AD_Vpl_low  = low_8;
	}                                       //峰峰值更新

     AD_High_rms = AD_High_rms + high_4*high_4;
     AD_Low_rms  = AD_Low_rms  + low_8*low_8 + 512*high_4*low_8;   //有效值计算
      
     count++;
     if(count==2000) break;    //采样值不宜超过两千,以防止计算有效值时数据溢出。
   }
    vpp=AD_Vph_high * 256 + AD_Vph_low - AD_Vpl_high * 256 - AD_Vpl_low;  
	                                                //峰峰值处理

    AD_High_rms=AD_High_rms/count;
	AD_Low_rms =AD_Low_rms /count;  
    sum_rms=(ulong)(AD_High_rms*65536+AD_Low_rms);
    rms=sqrt(sum_rms);                          	//有效值处理

    sum_ave=(ulong)(AD_High_ave*256+AD_Low_ave);
	ave=sum_ave/count;                              //均值处理


    if(AD_CMD&0x18) { ave=ave*2; rms=rms*2; vpp=vpp*2; }  //如果选择10V量程,应在计算上乘以2

    vpp=(uint)(vpp*1.2207);
    ave=(uint)(ave*1.2207);
    rms=(uint)(rms*1.2207);

    LcdPrintf(2,1,"vpp:");
    LcdPrintf(2,2,"ave:");
	LcdPrintf(2,3,"rms:");
	Dispnumber_float(vpp,4,3,10,1);
    Dispnumber_float(ave,4,3,10,2);
    Dispnumber_float(rms,4,3,10,3);                 //显示
}

*/


/*  
//本函数只计算均值
AD_MAX197_Bipolar(uchar channel,uchar sample_range)   //将补码变换后再处理
{
   char sign;
   uchar AD_CMD;
   uchar high_4,low_8;
   long AD_High=0,AD_Low=0,sum;      //每一次进入函数计算注意要将上次计算值清零
   int  count=0;
   uint ave;
   AD_CMD=(sample_range*8+channel)|0X40;

   while(1)
   {
     XBYTE[0xfa00]=AD_CMD;           //置控制字
     while(AD_Convert==0);
     AD_Convert=0;
     
     high_4=XBYTE[0xfa00];        //接收高四位, P2_3=1; P22,P21,P20控制片选选通
     low_8=XBYTE[0xf200];         //接收低八位, P2_3=0; P22,P21,P20控制片选选通

     if( (high_4&0xf0)==0xf0 ) 
	   {   
            high_4=0x0f-(high_4&0x0f);
            low_8=0x0100-low_8;
	        AD_High=AD_High - high_4;
            AD_Low =AD_Low  - low_8;        
	    }                             //处理采集负电压时得到的补码
     else 
	   {
           AD_High=AD_High +  high_4;
           AD_Low=AD_Low +  low_8;
       }
     count++;
     if(count==1000) break;
   }
   // Dispnumber_long((-1)*AD_High,6,10,3);
   // Dispnumber_long((-1)*AD_Low,6,10,3);

    sum=AD_High*256+AD_Low;
    if(sum<0) { sum=(-1)*sum; sign=1; }
	else sign=0;
    ave=sum/count;

	if(AD_CMD&0x18) { ave=ave*2; //rms=rms*2; vpp=vpp*2;
                    }    //如果选择10V量程,应在计算上乘以2

   // vpp=(uint)(vpp*1.2207);
    ave=(uint)(ave*1.2207);
   // rms=(uint)(rms*1.2207);
    Dispnumber_float(ave,4,3,10,2);
	if(sign==1)Disponechar(5,1,'-');
	if(sign==0)Disponechar(5,1,'+');
}

*/

/*
AD_MAX197_Bipolar(uchar channel,uchar sample_range)   //直接用补码处理
{
   uchar CMD;
   uchar high_4,low_8;
   long AD_High=0,AD_Low=0,sum;      //每一次进入函数计算注意要将上次计算值清零
   int  count=0,ave;
   CMD=(sample_range*8+channel)|0X40;

   while(1)
   {
     XBYTE[0xfa00]=CMD;           //置控制字
     while(AD_Convert==0);
     AD_Convert=0;
     
     high_4=XBYTE[0xfa00];        //接收高四位, P2_3=1; P22,P21,P20控制片选选通
     if(high_4&0xf0==0xf0)  (long)high_4=high_4+0xffff00;
     AD_High=AD_High+high_4;
     low_8=XBYTE[0xf200];         //接收低八位, P2_3=0; P22,P21,P20控制片选选通
     AD_Low=AD_Low+low_8;
     
     count++;
     if(count==1000) break;
   }

    sum=(long)(AD_High*256+AD_Low);
    if(sum<0) sum=(-1)*sum;
    ave=sum/count;
    Dispnumber(ave,4,10,1);
}

*/


/*
AD_MAX197_Process(uchar channel,uchar sample_range)
{
   uchar CMD;
   uchar high_4,low_8;
   ulong AD_High,AD_Low,sum,high_temp;
   uint  count=0,ave;
   CMD=(sample_range*8+channel)|0X40;
   XBYTE[0xfa00]=CMD;           //置控制字
   while(1)
   {
     while(AD_Convert==0);
     AD_Convert=0;

     high_4=XBYTE[0xfa00];        //接收高四位, P2_3=1; P22,P21,P20控制片选选通
     if(high_4>0x0f)  high_temp=high_4+0xffff00;
     AD_High=AD_High+high_temp;
     low_8=XBYTE[0xf200];         //接收低八位, P2_3=0; P22,P21,P20控制片选选通
     AD_Low=AD_Low+low_8;
     
     count++;
     if(count==1000) break;
   }
    sum=(ulong)(AD_High*256+AD_Low);
    sum=0x100000000-sum;
    ave=sum/count;
    Dispnumber(ave,4,10,1);
}
*/

⌨️ 快捷键说明

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