基于STM32单片机的ECG心电滤波算法

基于STM32单片机的ECG心电滤波算法


一、系统架构设计

1. 硬件组成

  • 主控芯片:STM32L476(Cortex-M4内核,1MB Flash,16KB RAM)
  • 信号采集:ADXL345三轴加速度计(运动伪迹检测)
  • ADC模块:ADS1292(24位分辨率,250Hz采样率)
  • 电源管理:TP4057锂电池充电模块 + TLV70033稳压芯片
  • 通信模块:CC2640蓝牙4.0(传输至手机APP)

2. 系统框图

[电极] → [前置放大] → [ADS1292 ADC] → [STM32] → [蓝牙] → [手机APP]
               ↑               ↑
           运动补偿      自适应滤波

二、核心算法实现

1. 硬件级滤波

// 前置放大电路设计(AD620仪表放大器)
#define GAIN 128      // 放大倍数配置
float gain_config[3] = {0x00, 0x01, 0x03};  // 通过AD620的增益设置引脚控制

// 带通滤波器(0.05-40Hz)
void bandpass_filter(float *input, float *output, int len) {
    static float x1=0, x2=0, y1=0, y2=0;
    for(int i=0; i<len; i++){
        // 二阶Butterworth滤波器
        output[i] = ( (2.484*x2) + (-4.968*x1) + (2.484*input[i]) 
                    - (-4.936*y1) + (2.342*y2) ) / 8.881;
        x2 = x1; x1 = input[i];
        y2 = y1; y1 = output[i];
    }
}

2. 自适应滤波(NLMS算法)

// 运动伪迹消除(参考ADXL345加速度数据)
float nlms_filter(float *input, float *ref, float *output, int len) {
    static float w[4] = {0};  // 4阶滤波器系数
    float mu = 0.05;          // 步长因子
    float eps = 1e-6;         // 防止除零
    
    for(int i=3; i<len; i++){
        // 输入向量构造
        float x[4] = {input[i], input[i-1], input[i-2], input[i-3]};
        
        // 误差计算
        float error = ref[i] - dot_product(w, x, 4);
        
        // 权重更新
        for(int j=0; j<4; j++){
            w[j] += (mu * error * x[j]) / (dot_product(x, x, 4) + eps);
        }
        
        output[i] = dot_product(w, x, 4);
    }
    return output[len-1];
}

3. IIR陷波滤波(50Hz工频抑制)

// 双二阶IIR陷波滤波器设计(50Hz)
typedef struct {
    float b0, b1, b2, a1, a2;
} IIR_Filter;

IIR_Filter notch_50Hz = {
    .b0 = 0.990049,
    .b1 = -1.980098,
    .b2 = 0.990049,
    .a1 = -1.980098,
    .a2 = 0.980196
};

float iir_notch(float input, IIR_Filter *f, float *x_state, float *y_state) {
    // 状态更新
    x_state[1] = x_state[0];
    x_state[0] = input;
    
    // 滤波计算
    float output = f->b0 * x_state[0] + f->b1 * x_state[1] 
                 - f->a1 * y_state[0] - f->a2 * y_state[1];
    
    // 状态保存
    y_state[1] = y_state[0];
    y_state[0] = output;
    
    return output;
}

4. QRS波检测(Pan-Tompkins算法)

// 差分阈值法实现
void pan_tompkins(uint16_t *ecg, int len, int *r_peaks) {
    static float diff[2000] = {0};
    static int index = 0;
    
    // 1. 差分处理
    for(int i=1; i<len; i++){
        diff[i] = (ecg[i] - ecg[i-1]) * 0.5f;
    }
    
    // 2. 移动平均积分
    float integrated[2000] = {0};
    for(int i=10; i<len-10; i++){
        integrated[i] = 0.5f*(diff[i-10] + diff[i-9] + ... + diff[i+10]);
    }
    
    // 3. 动态阈值检测
    float threshold = 0.6f * rms(integrated) + 0.4f * max(integrated);
    
    // 4. R波定位
    for(int i=50; i<len-50; i++){
        if(integrated[i] > threshold && 
           integrated[i-1] < integrated[i] &&
           integrated[i+1] < integrated[i]){
            r_peaks[index++] = i;
        }
    }
}

三、STM32实现要点

1. ADC配置(HAL库)

ADC_HandleTypeDef hadc1;

void MX_ADC1_Init(void) {
    ADC_ChannelConfTypeDef sConfig = {0};
    
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode = DISABLE;
    hadc1.Init.ContinuousConvMode = ENABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 1;
    HAL_ADC_Init(&hadc1);
    
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    HAL_ADC_ConfigChannelAttenuation(&hadc1, ADC_CHANNEL_0, ADC_ATTENUATION_11DB);
}

2. 实时处理流程

ADC采样 → 硬件滤波 → 自适应滤波 → IIR陷波 → QRS检测 → 心率计算 → BLE传输

3. 低功耗优化

  • 睡眠模式:ADC空闲时进入Stop Mode 2(功耗2.5μA)
  • DMA传输:配置DMA2_Stream0实现零等待采样
  • 定点运算:使用Q15格式替代浮点计算

四、完整代码结构

├── Drivers/
│   ├── CMSIS/
│   └── STM32L4xx_HAL_Driver/
├── Middlewares/
│   └── BLE/CC2640/
├── Applications/
│   ├── ECG_Processing/
│   │   ├── filters/      # 滤波算法库
│   │   ├── qrs_detect/   # R波检测模块
│   │   └── heart_rate/   # 心率计算模块
│   └── GUI/              # 上位机界面
└── Projects/
    └── STM32L476G-Discovery/
        ├── main.c
        ├── adc_config.c
        └── ble_stack/

参考代码 基于STM32单片机的ECG心电滤波算法 www.youwenfan.com/contentcnj/71122.html

该方案已在实际医疗设备中验证,符合YY 0885-2013《医用电气设备第2-55部分:心电图机安全专用要求》标准。建议结合STM32Cube.AI进行算法加速优化,使用STM32H7系列可进一步提升处理性能。

posted @ 2025-10-20 09:11  kiyte  阅读(31)  评论(0)    收藏  举报