2021.09.11

一.完成巴特沃斯滤波、中值滤波、平均值滤波在当前工程中的实现

1.传感器结构体

typedef struct
{	
	//当前数据
	float dataNowSensor;
	float dataNowRes;
	
	//巴特沃斯滤波缓存
	Butter_BufferData bufButterSensor;//巴特沃斯滤波器,传感器数据缓存
	Butter_BufferData bufButterRes;//巴特沃斯滤波器,电阻数据缓存
	
	//中值滤波缓存
	float bufMFSensor[10];//传感器数据缓存。要对应着中值滤波中定义的用于中值滤波的数据个数
	float bufMFRes[10];//下侧电阻数据缓存。要对应着中值滤波中定义的用于中值滤波的数据个数
	
	//平均值滤波缓存
	float bufAvgFSensor[10];
	float bufAvgFRes[10];
	
	
	//巴特沃斯低通滤波后数据
	float dataLPFSensor;
	float dataLPFRes;	
	
	//中值滤波后数据
	float dataMFSensor;//传感器中值滤波后数据
	float dataMFRes;//电阻中值滤波后数据
	
	//平均值滤波后数据
	float dataAvgFSensor;
	float dataAvgFRes;
}Rt;

2.巴特沃斯滤波子程序

/******************************************************************************
 * @brief	二阶巴特沃斯低通滤波器
 * @param	curr_input 当前获取的数据
 * @param *Buffer 滤波器缓存
 * @param *Parameter 滤波器参数
 * @return 处理后数据
 *****************************************************************************/
float LPButterworth(float curr_input,Butter_BufferData *Buffer,Butter_Parameter *Parameter)
{
  static int LPF_Cnt=0;
	
  Buffer->Input_Butter[2] = curr_input;//获取最新x(n)
	
  if(LPF_Cnt>=100)
  {
    /* Butterworth滤波 */
    Buffer->Output_Butter[2]=
      Parameter->b[0] * Buffer->Input_Butter[2]
        +Parameter->b[1] * Buffer->Input_Butter[1]
          +Parameter->b[2] * Buffer->Input_Butter[0]
            -Parameter->a[1] * Buffer->Output_Butter[1]
              -Parameter->a[2] * Buffer->Output_Butter[0];
  }
  else
  {
    Buffer->Output_Butter[2]=Buffer->Input_Butter[2];
    LPF_Cnt++;
  }
	
  /* x(n) 序列保存 */
  Buffer->Input_Butter[0]=Buffer->Input_Butter[1];
  Buffer->Input_Butter[1]=Buffer->Input_Butter[2];
  /* y(n) 序列保存 */
  Buffer->Output_Butter[0]=Buffer->Output_Butter[1];
  Buffer->Output_Butter[1]=Buffer->Output_Butter[2];
	
  return Buffer->Output_Butter[2];
}

/******************************************************************************
 * @brief	计算二阶低通巴特沃斯滤波器参数
 * @param	sample_frequent 待处理数据的采样频率
 * @param cutoff_frequent 截止频率
 * @param *LPF 滤波器参数结构体
 * @return 
 *****************************************************************************/
#define M_PI_F 3.141592653589793f
void Set_Cutoff_Frequency(float sample_frequent, float cutoff_frequent,Butter_Parameter *LPF)
{
  float fr = sample_frequent / cutoff_frequent;
  float ohm = tanf(M_PI_F / fr);
  float c = 1.0f + 2.0f * cosf(M_PI_F / 4.0f) * ohm + ohm * ohm;
  if (cutoff_frequent <= 0.0f) {
    // no filtering
    return;
  }
  LPF->b[0] = ohm * ohm / c;
  LPF->b[1] = 2.0f * LPF->b[0];
  LPF->b[2] = LPF->b[0];
  LPF->a[0] = 1.0f;
  LPF->a[1] = 2.0f * (ohm * ohm - 1.0f) / c;
  LPF->a[2] = (1.0f - 2.0f * cosf(M_PI_F / 4.0f) * ohm + ohm * ohm) / c;
}

3.中值滤波

uint8_t numMF = 10;//用于中值滤波的数据个数【还要对应着control.h中的结构体数组中的定义的个数】
/**
 * @brief	中值滤波
 * @param	nowData	当前获取的数据
 * @param *Buffer 缓存数组地址
 * @return  最近N个数据的中值
 */
float Filter_Middle3(float nowData,float *Buffer)//传入最近获取的n个数据的数组。Buffer中传入的数据一直是采集到的数据
{
	float temp[numMF];//中间量
	uint8_t i;
	float Middle;
	
	//0.数组缓存更新
	*(Buffer+numMF-1) = nowData;//将当前数据存入缓存最后一位
	
	//1.数据拷贝
	for(i=0; i<numMF; i++)
		temp[i] = *(Buffer+i);//将缓存中的数据拷贝到局部变量temp中
	
	//2.冒泡排序
	bubbleSort(temp, numMF);//传入要排序的数组、数组中数据个数
	
	//3.获取中值
	Middle = temp[numMF/2];
	
	//4.传入数组元素左移一位
	for(i=0; i<numMF-1; i++)
		*(Buffer+i) = *(Buffer+i+1);
	
	return Middle;
}

4.平均值滤波

#define numAvg 10//用于算数平均值滤波
/**
* @brief	算数平均值滤波【取一组数据的算数平均值】
 *
 * @param	NowData	当前获取的数据
 * @param *Buffer 缓存数组地址
 * @return  最近N个数据的算数平均值
 */
float Filter_Average(float nowData,float *Buffer)
{
	float Sum;//数据和
	float Average;//平均值
	uint16_t i;
	
	
	//1.数组更新
	*(Buffer+numAvg-1) = nowData;
	
	//2.求和
	for(i=0; i<numAvg; i++)
		Sum = *(Buffer+i) + Sum;//求n个数据和
	
	//3.求平均值
	Average = Sum/(numAvg*1.0);//不乘1.0的话,会出错
	
	//4.数组元素左移1位
	for(i=0; i<(numAvg-1); i++)
		*(Buffer+i) = *(Buffer+i+1);
	
	return Average;
}

5.主函数

	Set_Cutoff_Frequency(500,10,&Sensor_Parameter);
	Set_Cutoff_Frequency(500,10,&Res_Parameter);

if(g_tADS1256.ReadOver) //所有通道读取完毕。速率设置在ADS1256_CfgADC();函数
		{
			g_tADS1256.ReadOver = 0;	
			
			for (i = 0; i < 4; i++) //数据提取与转换 0~3路差分/0~7通道
			{
				adc[i] = ADS1256_GetAdc(i); //从全局缓冲区读取采样结果。 采样结果是在中断服务程序中读取的。
				volt[i] = ((int64_t)adc[i] * 2503000) / 4194303;//4194303 = (2^24)/4 --> Vref(uV)=2509700
			}
			
			/*---------------------当前数据赋值-----------------*/
			R1.dataNowSensor = -volt[0]/1000000.0;//由于PWM相位差控制的原因,目前使用的解决方案会使ADS1256的AIN0检测的负电压,AIN1引脚检测到正电压,故经差分后出来的是负电压,需要加个负号
			R1.dataNowRes = -volt[1]/1000000.0;

			/*---------------------滤波处理---------------------*/
			//1.巴特沃斯滤波
			R1.dataLPFSensor = LPButterworth(R1.dataNowSensor, &R1.bufButterSensor, &Sensor_Parameter);//传入当前数据、巴特沃斯缓存、巴特沃斯参数。得到巴特沃斯滤波后数据
			R1.dataLPFRes = LPButterworth(R1.dataNowRes , &R1.bufButterRes, &Res_Parameter);
			
			//2.中值滤波
			R1.dataMFSensor = Filter_Middle3(R1.dataLPFSensor, R1.bufMFSensor);//传入待处理的1个数据、缓存数组地址
			R1.dataMFRes = Filter_Middle3(R1.dataLPFRes, R1.bufMFRes);
			
			//3.平均值滤波
			R1.dataAvgFSensor = Filter_Average(R1.dataMFSensor, R1.bufAvgFSensor);
			R1.dataAvgFRes = Filter_Average(R1.dataMFRes, R1.bufAvgFRes);
			
			
			
			/*---------------------发送数组赋值------------------*/
			var[0] = R1.dataNowSensor;
			var[1] = R1.dataNowRes;
			
			var[2] = R1.dataLPFSensor;
			var[3] = R1.dataLPFRes;
			
			var[4] = R1.dataMFSensor;
			var[5] = R1.dataMFRes;
			
			var[6] = R1.dataAvgFSensor;
			var[7] = R1.dataAvgFRes;
			

			vcan2_sendware((uint8_t *)var, sizeof(var));//发送到山外上位机
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值