2025电赛G题-发挥部分-参数自适应FIR滤波器

发布于:2025-08-02 ⋅ 阅读:(19) ⋅ 点赞:(0)

(1)测评现场提供由RLC元件(各1个)组成的“未知模型电路”。 按照图3所示,探究装置连接该电路的输入和输出端口,对该电路进行 自主学习、建模(不可借助外部测试设备),2分钟内完成学习建模,显 示“未知模型电路”的滤波类型。 图3 学习、建模

(2)学习建模完成后,断开探究装置和“未知模型电路”的端口连接,将信号发生器接入探究装置和“未知模型电路”的输入端口(探究装置输入 电阻不小于100kΩ),如图4所示。探究装置能根据信号发 生器的输出信号推理生成与“未知模型电路”相同的输出信 号。要求探究装置和“未知模型电路”的输出信号相比波形 无失真、在示波器上能连续同频稳定显示(相位无要求), 两者峰峰值相对误差绝对值不大于10%。

        信号发生器的输出为频率1kHz~50kHz(步长200Hz)、 图4 装置与未知模型电路输出比对 峰峰值2V的周期信号,类型分别为:正弦波、矩形波(占空比10%~50%、步长5%)和其他 周期信号。 

        该部分核心功能为对电路进行自主学习、建模。并且要学习的电路对于不同频率的输入有着不同的响应。因此,可以使用参数自适应的FIR滤波器来实现该功能。
        

计算 FIR(有限脉冲响应)滤波器参数是设计 FIR 滤波器的核心步骤,其目标是确定滤波器的单位脉冲响应系数(即抽头系数),以满足预设的频率响应指标(如通带截止频率、阻带截止频率、通带波纹、阻带衰减等)。以下是详细的计算方法和步骤:

一、FIR 滤波器设计的基本原理

FIR 滤波器的频率响应由其单位脉冲响应 h(n) 决定,表达式为:H(ejω)=∑n=0N−1​h(n)e−jωn
其中,N 是滤波器的阶数(抽头数),ω 是数字角频率(范围 0∼π)。
设计的核心是找到合适的 h(n),使 H(ejω) 逼近理想频率响应。

二、FIR 滤波器参数计算的关键步骤

1. 明确设计指标

首先需确定滤波器的基本参数,包括:

  • 滤波器类型:低通、高通、带通、带阻。
  • 截止频率:通带截止频率 ωp​(或 fp​)、阻带截止频率 ωs​(或 fs​)(需转换为数字频率,公式:ω=2πf/fs​,fs​ 为采样频率)。
  • 通带最大波纹:δp​(允许的通带衰减波动,如 0.1 dB)。
  • 阻带最小衰减:As​(阻带衰减要求,如 60 dB)。
2. 选择设计方法

FIR 滤波器参数计算的主流方法有以下三种,各有适用场景:

(1)窗函数法(最常用)

原理:用理想滤波器的脉冲响应(非因果、无限长)与窗函数(有限长)卷积,得到有限长、因果的 h(n)。
步骤

  1. 确定理想频率响应 Hd​(ejω)(如低通滤波器的理想响应为:∣ω∣≤ωc​ 时为 1,否则为 0)。
  2. 计算理想脉冲响应 hd​(n):通过逆傅里叶变换 hd​(n)=2π1​∫−ππ​Hd​(ejω)ejωndω。
    • 例:理想低通的 hd​(n)=πnsin(ωc​n)​(ωc​ 为截止角频率)。
  3. 选择窗函数(如矩形窗、汉宁窗、汉明窗、布莱克曼窗等),窗函数需满足:
    • 长度 N(需根据过渡带宽和阻带衰减确定,见下文)。
    • 因果性:将 hd​(n) 右移 (N−1)/2 个采样点,得到 h(n)=hd​(n−(N−1)/2)⋅w(n),其中 w(n) 为窗函数。

窗函数选择参考

窗函数 过渡带宽(2π/N) 阻带最小衰减(dB) 适用场景
矩形窗 1.8 21 过渡带宽要求严,衰减要求低
汉宁窗 6.2 44 平衡过渡带和衰减
汉明窗 6.6 53 常用,衰减适中
布莱克曼窗 11.0 74 高阻带衰减要求

阶数 N 计算
根据过渡带宽 Δω=ωs​−ωp​,窗函数法的 N≈Δω窗函数过渡带宽系数⋅2π​。

  • 例:汉明窗的过渡带宽系数为 6.6,若 Δω=0.2π,则 N≈6.6×2π/0.2π=66。
(2)频率采样法

原理:在频域对理想频率响应 Hd​(ejω) 进行等间隔采样,通过 IDFT 得到 h(n)。
步骤

  1. 确定采样点数 N(滤波器阶数),在 ωk​=2πk/N(k=0,1,...,N−1)处对 Hd​(ejω) 采样,得到 H(k)。
  2. 为改善过渡带性能,可在通带与阻带之间设置过渡采样点(非 0 非 1 的中间值)。
  3. 计算 h(n)=N1​∑k=0N−1​H(k)ej2πkn/N。

特点:直接控制频域采样点,但过渡带性能较差,需额外优化过渡点。

(3)等波纹优化设计法(切比雪夫逼近法)

原理:通过极小化最大误差(通带和阻带内的波纹均匀分布),使实际频率响应与理想响应的偏差最小。
步骤

  1. 定义逼近区间(通带 [0,ωp​]、阻带 [ωs​,π])和误差权重(阻带误差权重通常更大)。
  2. 利用 Remez 交换算法求解最优 h(n),该算法通过迭代找到极值点,使误差在各区间内达到最大值且符号交替。

特点:相同阶数下性能优于窗函数法,过渡带更窄,阻带衰减更高,但计算更复杂(通常需工具实现)。

其中频率采样法易于实现

发挥部分可以分为两个方向来处理,

对于频率步进要求较高,意味着计算精度高,计算复杂度高(滤波器阶数高于512阶),对此,直接使用傅里叶变换进行滤波处理较为合适。

1.测试出电路的幅频特性曲线(频率步进应与FFT的频率精度保持一致);

2.对输入信号进行傅里叶变换

3.使用幅频特性曲线对信号频谱进行加权处理

4.对处理过后的频谱进行信号重建,使用傅里叶反变换实现


C语言版本 FFT函数
	int NUM = 1 << num;
    float XI[64] = {0};
    int i,j,k;      
    float PLL = Fs / 64;
    for(i=0;i<NUM;i++) {
        arr2[i] = arr[(int)(PLL * i)];
    }
    for(i=0;i<NUM;i++)
    {
        XR[i] = (float)arr2[K_VALUE[i]];
    }
    int TR, TI, WR, WI;
    for(int i=0;i<num;i++)            
    {
        int B = 1<<i;                  
        for(int j=0;j<B;j++)            
        {
            int p=j*(1<<(num-i-1));       //旋转因子的系数
            for(int k=j;k<NUM;k=k+2*B)
            {
                TR= XR[k];
                TI=XI[k];
                WR= XR[k+B]*COS_VALUE[p]+XI[k+B]*SIN_VALUE[p];
                WI=-XR[k+B]*SIN_VALUE[p]+XI[k+B]*COS_VALUE[p];
                XR[k]=(TR+WR);
                XI[k]=TI+WI;
                XR[k+B]=(TR-WR);
                XI[k+B]=TI-WI;
            }
        }
    }

对于实时性要求较高(滤波器阶数低于512阶),意味着较少的计算量,和较低的频率步进,对此,使用fir滤波器较为合适
通过将幅频特性曲线转换到时域,得到FIR滤波器系数。


C语言版本的FIR滤波器系数计算
 

	/*------------数字指标-------------------*/ 
  	double 	Wc1=2*pi*((Transfer_param->fp1+Transfer_param->fst1)/2)/Transfer_param->fs;
  	double	Wc2=2*pi*((Transfer_param->fp2+Transfer_param->fst2)/2)/Transfer_param->fs;
  	double  det_W1=2*pi*abs(Transfer_param->fst1-Transfer_param->fp1)/Transfer_param->fs;           
  	double  det_W2=2*pi*abs(Transfer_param->fst2-Transfer_param->fp2)/Transfer_param->fs;			
  	double 	det_W=det_W1;
  	if((Filter_type==BANDPASSFILTER)||(Filter_type==BANDSTOPFILTER)) 
  	{
  		det_W=det_W1>det_W2?det_W2:det_W1;
	}
	
	
	int n;
	int N;
	int window; 
	/*窗函数选择--------------------------------------------------------------------------- */ 
	// 根据衰as减选择窗 
	switch((int)(Transfer_param->ast/10))
	{
	  	case 2:   //20db 
	  		N=(int)1.8*pi/det_W;
	  		if(N!=1.8*pi/det_W)N++;
	  		window=Rectangle;
	  		break;	
		case 3://30db 
			N=(int)6.1*pi/det_W;
	  		if(N!=6.1*pi/det_W)N++;
	  		window=triangle;
	  		break;
		case 4: //40db 
			N=(int)(6.2*pi/det_W);
	  		if(N!=6.2*pi/det_W)N++;
	  		window=Hanning;
	  		break;
	  	case 5 ://50db 
	  		N=(int)(6.6*pi/det_W);
	  		if(N!=6.6*pi/det_W)N++;
	  		window=Hamming;
	  		break;
		case 7 ://70db
			N=(int)11*pi/det_W;
	  		if(N!=11*pi/det_W)N++;
	  		window=Blackman;
	  		break;
		default: 
			return 0;	
	}
 
	int const const_N=N;

	switch(window)
	{
	  	case Rectangle:       
	  		for(n=0;n<N;n++)
	  		{
	  			win_param[n]=1;  			
			}
	  		break;
		case triangle:
			for(n=0;n<N;n++)
	  		{
	  				win_param[n]=1; 	
			}
	  		break;
		case Hanning:  
			for(n=0;n<N;n++)
	  		{
	  				win_param[n]=0.5*(1-cos(2*pi*n/(N-1))); 			
			}
	  		break;
	  	case Hamming :
			for(n=0;n<N;n++)
	  		{
	  				win_param[n]=0.54-0.46*cos(2*pi*n/(N-1));
			}  		
	  		break;
		case Blackman :
			for(n=0;n<N;n++)
	  		{
	  				win_param[n]=0.42-0.5*cos((4*pi*n/(N-1))-0.08*(4*pi*n/(N-1))); 			
			}  		
	  		break;
		default:
			return 0;	
	}
  
 
	/*计算FIR的传递函数*/ 

	Filter_h.N=N;
	for(n=0;n<N;n++) 
	{
	  		
		Filter_h.Hn[n] = h_lixiang[n]*win_param[n];
				  					  			
	}
	return &Filter_h;	   

另外对于32单片机,实时处理信号较为困难,一般使用乒乓操作对数据进行处理


网站公告

今日签到

点亮在社区的每一天
去签到