[嵌入式C编程与固件开发] 软件带通滤波器

[复制链接]
jerry尧 发表于 2025-8-10 17:54 | 显示全部楼层 |阅读模式
带通滤波器(Bandpass Filter, BPF)是一种仅允许特定频率范围内的信号通过,而衰减或阻止其他频率信号的电子电路或数字信号处理组件。
通带(Passband):允许通过的频率范围,通常由下限截止频率(fL)和上限截止频率(fH)定义。
阻带(Stopband):被显著衰减的频率范围(低于fLfL​或高于fHfH​)。
带宽(Bandwidth, BW):通带宽度,BW=fH−fLBW=fH​−fL​
中心频率(f0f0​)通带的几何中心频率,[size=1.21em]f0=fL⋅fHf0​=fL​⋅fH​​对于窄带滤波器可近似为算术平均)。
(1) 按实现方式模拟带通滤波器:由电阻(R)、电容(C)、电感(L)或运放等模拟元件构成。常见类型:RLC谐振电路:通过LC谐振选择频率。有源滤波器(如Sallen-Key拓扑):使用运放提高性能。数字带通滤波器:通过数字算法(如IIR或FIR)实现,应用于DSP或软件中。设计方法:双线性变换、窗函数法等。
(2) 按响应特性巴特沃斯(Butterworth):通带平坦,但过渡带较宽。切比雪夫(Chebyshev):通带或阻带内有波纹,过渡带更陡峭。椭圆(Elliptic):通带和阻带均有波纹,过渡带最陡。贝塞尔(Bessel):群延迟平坦,相位线性,但频率选择性较差。
1. 二阶IIR带通滤波器实现
#define PI 3.14159265358979323846
typedef struct {
    float a0, a1, a2;  // 分子系数
    float b1, b2;      // 分母系数
    float x1, x2;      // 输入延迟
    float y1, y2;      // 输出延迟
} BiquadFilter;

// 初始化带通滤波器
void initBandPassFilter(BiquadFilter* filter, float centerFreq, float sampleRate, float Q) {
    float w0 = 2 * PI * centerFreq / sampleRate;
    float alpha = sin(w0) / (2 * Q);
    float cos_w0 = cos(w0);

    float b0 = alpha;
    float b1 = 0;
    float b2 = -alpha;
    float a0 = 1 + alpha;
    float a1 = -2 * cos_w0;
    float a2 = 1 - alpha;

    // 归一化系数
    filter->a0 = b0 / a0;
    filter->a1 = b1 / a0;
    filter->a2 = b2 / a0;
    filter->b1 = a1 / a0;
    filter->b2 = a2 / a0;

    // 初始化延迟
    filter->x1 = 0;
    filter->x2 = 0;
    filter->y1 = 0;
    filter->y2 = 0;
}

// 处理一个样本
float processSample(BiquadFilter* filter, float input) {
    float output = filter->a0 * input + filter->a1 * filter->x1 + filter->a2 * filter->x2
                   - filter->b1 * filter->y1 - filter->b2 * filter->y2;

    // 更新延迟
    filter->x2 = filter->x1;
    filter->x1 = input;
    filter->y2 = filter->y1;
    filter->y1 = output;

    return output;
}



2. FIR带通滤波器实现
FIR(有限脉冲响应)滤波器是另一种常见的带通滤波器实现方式:

#define PI 3.14159265358979323846
#define FILTER_TAP_NUM 101  // 滤波器阶数(奇数)
typedef struct {
    float taps[FILTER_TAP_NUM];
    float buffer[FILTER_TAP_NUM];
    int index;
} FIRFilter;

// 初始化FIR带通滤波器
void initFIRBandPassFilter(FIRFilter* filter, float lowCutoff, float highCutoff, float sampleRate) {
    float nyquist = sampleRate / 2;
    float normLow = lowCutoff / nyquist;
    float normHigh = highCutoff / nyquist;
    int M = FILTER_TAP_NUM / 2;

    for(int n = -M; n <= M; n++) {
        if(n == 0) {
            filter->taps[n + M] = 2 * (normHigh - normLow);
        } else {
            filter->taps[n + M] = (sin(2 * PI * normHigh * n) / (PI * n) -
                                  (sin(2 * PI * normLow * n) / (PI * n)));
        }
    }

    // 应用汉宁窗
    for(int n = 0; n < FILTER_TAP_NUM; n++) {
        filter->taps[n] *= 0.5 * (1 - cos(2 * PI * n / (FILTER_TAP_NUM - 1)));
    }

    // 初始化缓冲区
    for(int n = 0; n < FILTER_TAP_NUM; n++) {
        filter->buffer[n] = 0;
    }
    filter->index = 0;
}

// 处理一个样本
float processSampleFIR(FIRFilter* filter, float input) {
    filter->buffer[filter->index] = input;

    float output = 0;
    int sumIndex = filter->index;

    for(int n = 0; n < FILTER_TAP_NUM; n++) {
        output += filter->taps[n] * filter->buffer[sumIndex];
        sumIndex--;
        if(sumIndex < 0) sumIndex = FILTER_TAP_NUM - 1;
    }

    filter->index++;
    if(filter->index >= FILTER_TAP_NUM) filter->index = 0;

    return output;
}



应用场景
通信系统:解调特定频段的信号(如收音机选台)。

生物医学:提取EEG、ECG中的特定频率成分。

音频处理:均衡器中的频段控制。

抗干扰:滤除噪声或无关频段。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

68

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

44

主题

68

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部