STM32 心电图方案全解析:手把手教你开发医疗级心电监测设备!

  作者:嵌入式芯视野 时间:2025-08-04来源:今日头条

心电图(ECG)方案基于 STM32 芯片开发,主要应用于医疗领域的心电图机设备。该设备通过采集人体体表电信号,记录心脏电活动的波形,为心脏疾病诊断提供关键数据支持。其典型应用包括:

工作原理




ECG组成框图


心脏在收缩和舒张过程中产生电激动,其微小电流经身体组织传导至体表,形成不同部位的电位差。心电图机通过体表电极采集这些电位差,经信号调理、模数转换和数据处理后,生成心电图波形。具体流程如下:

  1. 信号采集:通过 10 个体表电极(如右手 VR、左手 VL 等)获取 12 导联心电信号。

  2. 信号调理:经仪表运放(如 INA126)前级放大、精密运放(如 ISL28248)后级放大,以及高通 / 低通滤波(HPF/LPF)去除噪声。

  3. 模数转换:利用高精度 ADC(如 ADS1258)将模拟信号转换为数字信号。

  4. 数据处理:STM32 芯片对数字信号进行滤波、放大倍数校准等处理。

  5. 显示与存储:将处理后的波形显示在 LCD 上,并存储历史数据。

系统组成与 IC 选型

模块

功能

推荐芯片

竞争对手

主控芯片

完成 ADC 控制、数据处理及系统管理

STM32F101/103 系列

MSP430 系列、MEGA 系列

前级放大

心电信号初级放大

INA126/128、ISL28470

AD620、AD623

后级放大

信号进一步放大

ISL28248、TL062

-

模数转换

模拟信号数字化

ADS1258、ADS8341

-

电压基准

为 ADC 提供参考电压

REF30xx、ISL21009

-

电源管理

系统供电转换

TPS5430、ISL8500

LM2576、LM2676

程序示例

以下是基于 STM32F103 的心电图数据采集与处理程序示例(使用 HAL 库):

/* 包含头文件 */#include "stm32f10x_hal.h"#include "stdio.h"#include "math.h"/* 定义参数 */#define SAMPLE_RATE 1000        // 采样率1000Hz#define FILTER_ORDER 32         // FIR滤波器阶数#define ECG_CHANNEL 8           // 心电通道数#define BUFFER_SIZE 1024        // 数据缓冲区大小/* 全局变量 */ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;uint16_t adcBuffer[ECG_CHANNEL][BUFFER_SIZE];  // ADC数据缓冲区float ecgData[ECG_CHANNEL][BUFFER_SIZE];       // 心电数据数组float firCoeff[FILTER_ORDER] = {0};            // FIR滤波器系数uint32_t sampleCount = 0;                      // 采样计数/* 函数声明 */void SystemInit(void);void MX_GPIO_Init(void);void MX_ADC_Init(void);void MX_DMA_Init(void);void FIRFilter_Init(void);void FIRFilter_Process(float* input, float* output, uint32_t length);void ECG_Process(void);void LCD_DisplayECG(float* ecgData, uint32_t length);/* 主函数 */int main(void){  /* 系统初始化 */
 HAL_Init();
 SystemInit();  
 /* 外设初始化 */
 MX_GPIO_Init();
 MX_ADC_Init();
 MX_DMA_Init();
 FIRFilter_Init();  // 初始化FIR滤波器
 
 /* 启动ADC_DMA传输 */
 HAL_ADC_Start_DMA(&hadc, (uint32_t*)adcBuffer, BUFFER_SIZE * ECG_CHANNEL);  
 /* 主循环 */
 while (1)
 {    /* 心电数据处理 */
   if (sampleCount >= BUFFER_SIZE)
   {
     ECG_Process();  // 处理采集到的心电数据
     LCD_DisplayECG(ecgData[0], BUFFER_SIZE);  // 显示第一通道心电波形
     sampleCount = 0;
   }    
   /* 其他系统任务 */
   HAL_Delay(1);
 }
}/* ADC初始化 */void MX_ADC_Init(void){
 ADC_ChannelConfTypeDef sConfig = {0};

 hadc.Instance = ADC1;
 hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
 hadc.Init.Resolution = ADC_RESOLUTION_12B;
 hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
 hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
 hadc.Init.LowPowerAutoWait = DISABLE;
 hadc.Init.LowPowerAutoPowerOff = DISABLE;
 hadc.Init.ContinuousConvMode = ENABLE;
 hadc.Init.NbrOfConversion = ECG_CHANNEL;
 hadc.Init.DiscontinuousConvMode = DISABLE;
 HAL_ADC_Init(&hadc);  /* 配置心电通道 */
 for (uint8_t i = 0; i < ECG_CHANNEL; i++)
 {
   sConfig.Channel = ADC_CHANNEL_0 + i;  // 假设通道0-7为心电通道
   sConfig.Rank = i + 1;
   sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
   HAL_ADC_ConfigChannel(&hadc, &sConfig);
 }
}/* DMA初始化 */void MX_DMA_Init(void){
 hdma_adc.Instance = DMA1_Channel1;
 hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
 hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 hdma_adc.Init.Mode = DMA_CIRCULAR;
 hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
 HAL_DMA_Init(&hdma_adc);

 __HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc);
}/* FIR滤波器初始化 */void FIRFilter_Init(void){  /* 生成低通FIR滤波器系数(截止频率50Hz,采样率1000Hz) */
 float fc = 50.0f / 1000.0f;  // 归一化截止频率
 for (int i = 0; i < FILTER_ORDER; i++)
 {    if (i == FILTER_ORDER / 2)
     firCoeff[i] = 2.0f * fc;    else
     firCoeff[i] = sinf(2.0f * PI * fc * (i - FILTER_ORDER / 2)) / (PI * (i - FILTER_ORDER / 2));    
   /* 汉明窗加权 */
   firCoeff[i] *= 0.54f - 0.46f * cosf(2.0f * PI * i / (FILTER_ORDER - 1));
 }  
 /* 系数归一化 */
 float sum = 0;  for (int i = 0; i < FILTER_ORDER; i++)
   sum += firCoeff[i];    
 for (int i = 0; i < FILTER_ORDER; i++)
   firCoeff[i] /= sum;
}/* FIR滤波器处理 */void FIRFilter_Process(float* input, float* output, uint32_t length){  static float buffer[FILTER_ORDER] = {0};  // 滤波器缓冲区
 
 for (uint32_t i = 0; i < length; i++)
 {    /* 移存输入数据 */
   for (int j = FILTER_ORDER - 1; j > 0; j--)
     buffer[j] = buffer[j - 1];
   buffer[0] = input[i];    
   /* 卷积计算 */
   output[i] = 0;    for (int j = 0; j < FILTER_ORDER; j++)
     output[i] += buffer[j] * firCoeff[j];
 }
}/* 心电数据处理 */void ECG_Process(void){  /* ADC数据转换为电压值(假设参考电压3.3V) */
 for (uint8_t ch = 0; ch < ECG_CHANNEL; ch++)
 {    for (uint32_t i = 0; i < BUFFER_SIZE; i++)
   {
     ecgData[ch][i] = (float)adcBuffer[ch][i] * 3.3f / 4096.0f;
   }    
   /* 应用FIR滤波器去除噪声 */
   FIRFilter_Process(ecgData[ch], ecgData[ch], BUFFER_SIZE);    
   /* 基线漂移校正(简单直流分量去除) */
   float dcOffset = 0;    for (uint32_t i = 0; i < BUFFER_SIZE; i++)
     dcOffset += ecgData[ch][i];
   dcOffset /= BUFFER_SIZE;    
   for (uint32_t i = 0; i < BUFFER_SIZE; i++)
     ecgData[ch][i] -= dcOffset;
 }
 
 sampleCount += BUFFER_SIZE;
}

方案特点与优势

  1. 高精度采集:采用 12 位 ADC(如 ADS1258)和精密运放,确保信号采集精度。

  2. 抗干扰设计:通过多级滤波(高通、低通、FIR)有效抑制工频干扰、基线漂移等噪声。

  3. 多导联支持:可同时采集 12 导联心电信号,满足临床诊断需求。

  4. 实时处理:STM32 的高速运算能力实现数据的实时采集、处理与显示。

  5. 低功耗设计:采用 LDO 和 DC/DC 电源管理芯片,适合便携式设备应用。


关键词: STM32

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版