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

📄 ad.c

📁 msp430 ad采样的可靠行排序算法。平均
💻 C
字号:
  #include "MSP430x14x.h"
#define ADCMEM ((int*) 0x0140)          // ADC12MEMx 定义
    unsigned int Result[3];     	//用以保存转换结果
 float ad_result[3];

 //float  vol_a01[5]={1.8302, 2.101,2.365, 2.635, 2.907},pressure_a01[5]={20,24,28,32,36};//一

//float  vol_a01[5]={1.8302, 2.101,2.365, 2.635, 2.907},pressure_a01[5]={20,24,28,32,36};//二
float  vol_a01[5]={2.2, 2.480,2.76, 3.02, 3.3},pressure_a01[5]={20,24,28,32,36};//三(进传感)
// float  vol_a01[5]={0.717, 1.650,2.614, 3.55, 4.47},pressure_a01[5]={0,15,30,45,60};//三(进传感)
 float  vol_a10[5]={2.2, 2.480,2.76, 3.02, 3.3},pressure_a10[5]={20,24,28,32,36};//from high to low 10
 float  vol_b01[5]={2.2, 2.480,2.76, 3.02, 3.3},pressure_b01[5]={20,24,28,32,36};
 float  vol_b10[5]={2.2, 2.480,2.76, 3.02, 3.3},pressure_b10[5]={20,24,28,32,36};

/*
float  vol_a01[5]={1.858, 2.1,2.3, 2.6, 2.9},pressure_a01[5]={20,24,28,32,36};//  from low to high 01
float  vol_a10[5]={1.848, 2.115,2.381, 2.65, 2.912},pressure_a10[5]={20,24,28,32,36};//from high to low 10
float  vol_b01[5]={1.868, 2.142,2.409, 2.688, 2.959},pressure_b01[5]={20,24,28,32,36};
float  vol_b10[5]={1.858, 2.125,2.386, 2.661, 2.926},pressure_b10[5]={20,24,28,32,36};
*/
float a[2];
float a_01[2],a_10[2],b_01[2],b_10[2],a00[2],b00[2];

int  s_a,s_b;
#define delta_s   10    //定义上压,下压差值
//--------------------------------------------------------------------------
void Init_ad(void);          		// Initialization of System/Control Registers

void ad_process();
void  sensor_calculate(float voltage[5], float pressure[5]);
void  sensor_Init();

//Parameter init
void  sensor_Init()
{

//a sensor
 sensor_calculate(vol_a01,pressure_a01); //01
a_01[0]=a[0];a_01[1]=a[1];
sensor_calculate(vol_a10,pressure_a10);//10
a_10[0]=a[0];a_10[1]=a[1];

///////////b sensor
sensor_calculate(vol_b01,pressure_b01); //  from low to high 01
b_01[0]=a[0];b_01[1]=a[1];
sensor_calculate(vol_b10,pressure_b10);//from high to low 10
b_10[0]=a[0];b_10[1]=a[1];


a00[0]=a_01[0]; a00[1]=a_01[1];   //设置初值
b00[0]=b_01[0]; b00[1]=b_01[1];

}


void  sensor_calculate(float voltage[5], float pressure[5])
{

float a11=0,a12=0,a21=0,a22=0;
float b11=0,b21=0;

a11=5;
a12=voltage[0]+voltage[1]+voltage[2]+voltage[3]+voltage[4];
a21=a12;
a22=voltage[0]*voltage[0]+voltage[1]*voltage[1]+voltage[2]*voltage[2]+voltage[3]*voltage[3]+voltage[4]*voltage[4];
b11=pressure[0]+pressure[1]+pressure[2]+pressure[3]+pressure[4];
b21=voltage[0]*pressure[0]+voltage[1]*pressure[1]+voltage[2]*pressure[2]+voltage[3]*pressure[3]+voltage[4]*pressure[4];

//calculate the pra
a[0]=a22/(a11*a22-a12*a21)*b11-a12/(a11*a22-a12*a21)*b21;
a[1]= -a21/(a11*a22-a12*a21)*b11+a11/(a11*a22-a12*a21)*b21;
//return(a[0]);

}

void ad(void)
{
    unsigned int i;
    unsigned int j;
//    unsigned int Result[3];     	//用以保存转换结果
   // Init();                 	        //对ADC进行初始化
   // while (1)
    //{
      Init_ad();
       for (i=0;i<3;i++)
       {
            ADC12CTL0 |= 0x01;     	// 开始转换
            ADC12CTL0 &=~0x01;
          for (j=0;j<=1000;j++); 	// 延时,准备触发序列中的下一次转换
       }
       while ((ADC12CTL1&0x01)==1); 	// 等待整个序列的转换完成
       for(j = 0 ; j <3; j++)
       {
            Result[j] = ADCMEM[j];
       }
       for (i=0;i<=2000;i++);   	// 两个序列之间的一个延时
    //}
}




////////////////

#define a_limit  20  //ad  sample limit scope.



void ad_converter(unsigned p)//循环ad采样p遍
{


   int ad_0[60], ad_1[60], ad_2[60],ad_temp1,ad_temp2,ad_temp3;
   float s0=0,s1=0,s2=0;
  unsigned char j,i;
  for (int i=0;i<p;i++)
  {


  
        ad();

	//////2007-8-16 First use the limit scope method , then use average method  filter

        ad_0[i]=Result[0];
        ad_1[i]=Result[1];
        ad_2[i]=Result[2];

	/*
	if (0==i)
	    {
        ad_0[i]=Result[0];
        ad_1[i]=Result[1];
        ad_2[i]=Result[2];
		}
		
          if (i>=1)  
          	{
 //////////////////////// 0         	
          	 ad_0[i]= ( ( ( Result[0] - ad_0[i-1] > a_limit  ) || ( ad_0[i-1] - Result[0] > a_limit  )) ?  ad_0[i-1] : Result[0] );
 
///////////////////////	1			
          	 if ( ( Result[1] - ad_1[i-1] > a_limit  ) || ( ad_1[i-1] - Result[1] > a_limit  ))
          	 //	{
                     ad_1[i]=ad_1[i-1];
          	 //	}
                else
            	 //	{
                     ad_1[i]=Result[1];
          	 //	}
///////////////////////////2/
		 if ( ( Result[2] - ad_2[i-1] > a_limit  ) || ( ad_2[i-1] - Result[2] > a_limit  ))
          	 	{
                     ad_2[i]=ad_2[i-1];
          	 	}
                else
            	 	{
                     ad_2[i]=Result[2];
          	 	}
/////////////////////////////
		  }
*/
		
   }


////////////////2007-8-13 放弃取平均值方法
 /*
 for (int i=0;i<p;i++)
 {
   s0+=ad_0[i];
   s1+=ad_1[i];
   s2+=ad_2[i];
 }

 s0=s0/p;// 取平均值
 s1=s1/p;
 s2=s2/p;

*/
////////////////2007-8-13 放弃取平均值方法



//////2007-8-13 采用中值平均滤波法,abandon the Max and Min.

for (j=0;j<p-1;j++)
{
    for (i=0;i<p-j;i++)
	{
		if ( ad_0[i]>ad_0[i+1] )
			{
  				  ad_temp1 = ad_0[i];
					ad_0[i] = ad_0[i+1];
					ad_0[i+1] =ad_temp1;
			}
	}
}
///////////////////////
for (j=0;j<p-1;j++)
{
    for (i=0;i<p-j;i++)
	{
		if ( ad_1[i]>ad_1[i+1] )
			{
  				  ad_temp2 = ad_1[i];
					ad_1[i] = ad_1[i+1];
					ad_1[i+1] =ad_temp2;
			}
	}
}
////////////////
for (j=0;j<p-1;j++)
{
    for (i=0;i<p-j;i++)
	{
		if ( ad_2[i]>ad_2[i+1] )
			{
  				  ad_temp3 = ad_2[i];
					ad_2[i] = ad_2[i+1];
					ad_2[i+1] =ad_temp3;
			}
	}
}

//////////

unsigned char  counter_n=3, cha=80;   // 最大最小差值不大于20   2007-9-27
  
/*
 for (int i=3;i<p-3;i++)
 {
   s0+=ad_0[i];
   s1+=ad_1[i];
   s2+=ad_2[i];
 }
 */

 for (int i=0;i<10;i++)             //自动筛选最大最小次数,最多剔除20个数。
 {
   if( ((ad_0[p-counter_n]-ad_0[counter_n])>cha)||((ad_1[p-counter_n]-ad_1[counter_n])>cha))    counter_n++;
 }


 for (int i=counter_n;i<p-counter_n;i++)
 {
 
   s0+=ad_0[i];
   s1+=ad_1[i];
   s2+=ad_2[i];

 }



 s0=s0/(p-2*counter_n);   // 取平均值
 s1=s1/(p-2*counter_n);
 s2=s2/(p-2*counter_n);



// if ((s0-s_a)>=delta_s)  {a00[0]=a_01[0]; a00[1]=a_01[1]; s_a=s0;}
 // if ((s_a-s0)>=delta_s)  {a00[0]=a_10[0]; a00[1]=a_10[1]; s_a=s0;}
 /////////////
//   if ((s1-s_b)>=delta_s)  {b00[0]=b_01[0];b00[1]=b_01[1]; s_b=s1;}
//  if ((s_b-s1)>=delta_s)  {b00[0]=b_10[0]; b00[1]=b_10[1]; s_b=s1;}
  /////////////


 // 转换电压
  //ad_result[0]=(3.26*s0)/4095 ;
ad_result[0]=(2.486*s0)/4095 ;
	 //
 //  ad_result[1]=(3.26*s1)/4095 ;
ad_result[1]=(2.486*s1)/4095 ;
	
      ad_result[2]=(3.26*s2)/4095 ; //XIUGAI
         //ad_result[2]=(3.3*s2)/4095 ;
////
//  ad_result[0]=ad_result[0]*2;


ad_result[0]=a00[0]+a00[1]*ad_result[0]*2.0 ;////
//ad_result[0]=(ad_result[0]*2-0.5036)*11.6822;

  //   ad_result[1]=ad_result[1];
 ad_result[1]=b00[0]+b00[1]*ad_result[1]*2.02 ;   //由于电阻精度不满足要求,所以每次焊接调试时要测量这个比。
	
    // ad_result[2]=(ad_result[2]*99.96)/19.952 ;//
// ad_result[2]=ad_result[2]*6.019;//根据电路测量。

 //ad_result[2]=ad_result[2];
	
}

void Init_ad(void)
{
    WDTCTL = WDTPW + WDTHOLD;	        // 停止Watchdog
/* ADC12 Settings: */
     P6SEL  |=  0xff;         		// 所有P6口线均为ADC模块使用
     ADC12CTL0 &=~ 0x02;   		// 在进行设置时首先复位ADC的转换使能

// ADC12CTL0 |= SHT0_8;
ADC12CTL0  |= REF2_5V;
ADC12CTL0  |= REFON;
//ADC12CTL1  |= ADC12DIV2;


ADC12MCTL0 = 0x10;  // 参考电压ref+=AVcc, 输入通道选择为 A0


ADC12MCTL1 = 0x12;  // 参考电压ref+=AVcc, 输入通道选择为 A2

ADC12MCTL2 = SREF_0+INCH_4+EOS;; // 参考电压ref+=AVcc, 输入通道选择为 A4                          		// ADC12MCTL1 是最后一个转换通道
     ADC12CTL1 |=0x021A;    		// ADC12SC 位触发采样和保持
                            		// 采样脉冲由采样定时器产生
                            		// 时钟源:内部振荡器
                            		// 时钟分频: 1
                            		// 转换模式: 多通道、单次转换
     ADC12CTL0  |= 0x0010+SHT0_1;
     ADC12CTL0 |= 0x02;     		// 使能ADC转换
}

⌨️ 快捷键说明

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