在STM32F103RC上实现64阶数字FIR低通滤波

在STM32F103RC上实现64阶FIR低通滤波器的步骤如下:

1. 生成滤波器系数

使用Python和SciPy生成归一化的64阶FIR低通滤波器系数,截止频率1kHz,采样频率134635Hz:

import numpy as np
from scipy.signal import firwin

fs = 134635    # 采样频率
fc = 1000      # 截止频率
num_taps = 65  # 64阶,65个系数

# 生成汉明窗FIR低通滤波器系数
taps = firwin(num_taps, fc, fs=fs, window='hamming')

# 归一化系数以确保直流增益为1
taps_normalized = taps / np.sum(taps)

# 转换为Q15格式(16位定点数)
q15_coeffs = np.round(taps_normalized * 32767).astype(np.int16)

print("Q15 Coefficients:")
print(q15_coeffs.tolist())

2. 在STM32中配置FIR滤波器

使用CMSIS-DSP库的Q15定点运算实现:

定义系数和状态变量
#include "arm_math.h"

#define NUM_TAPS 65

// Q15格式的滤波器系数
const q15_t firCoeffsQ15[NUM_TAPS] = { /* 粘贴生成的Q15系数 */ };

// 滤波器实例和状态缓冲区
static arm_fir_instance_q15 firInstance;
static q15_t firStateQ15[NUM_TAPS + 1 - 1]; // 块处理所需状态缓冲区

void FIR_Init(void) {
    arm_fir_init_q15(&firInstance, NUM_TAPS, (q15_t*)firCoeffsQ15, firStateQ15, 1);
}
处理采样数据
q15_t FIR_ProcessSample(q15_t inputSample) {
    q15_t outputSample;
    arm_fir_q15(&firInstance, &inputSample, &outputSample, 1);
    return outputSample;
}

3. 集成到ADC采样中

在ADC中断处理函数中调用滤波器:

void ADC_IRQHandler(void) {
    if (ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET) {
        q15_t adcValue = (q15_t)(ADC_GetConversionValue(ADC1) - 2048) << 4; // 12位ADC转Q15
        q15_t filtered = FIR_ProcessSample(adcValue);
        // 使用filtered数据
        ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
    }
}

4. 主函数初始化

int main(void) {
    // 系统时钟和ADC初始化
    SystemInit();
    ADC_Init();
    FIR_Init();

    while (1) {
        // 主循环
    }
}

验证滤波器性能

使用Python生成系数后,绘制频率响应以验证截止频率和衰减特性:

import matplotlib.pyplot as plt
from scipy.signal import freqz

w, h = freqz(taps_normalized, fs=fs)
plt.plot(w, 20 * np.log10(np.abs(h)))
plt.axvline(fc, color='red', linestyle='--')
plt.xlim(0, fs/2)
plt.ylim(-60, 5)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Gain (dB)')
plt.grid()
plt.show()

注意事项

  • 实时性:STM32F103的72MHz主频足以处理134.635kHz的采样率,每个样本约有534个时钟周期,FIR滤波约需130周期(65阶)。
  • 定点运算:使用Q15格式时,确保输入数据正确转换(如12位ADC值转换为有符号Q15)。
  • 内存分配:状态缓冲区大小需足够(NUM_TAPS + block_size - 1),逐点处理时block_size=1

通过上述步骤,即可在STM32F103RC上实现所需的FIR低通滤波器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值