STM32 心电图方案全解析:手把手教你开发医疗级心电监测设备!
心电图(ECG)方案基于 STM32 芯片开发,主要应用于医疗领域的心电图机设备。该设备通过采集人体体表电信号,记录心脏电活动的波形,为心脏疾病诊断提供关键数据支持。其典型应用包括:
临床诊断:用于常规体检、心脏病患者的日常监测及病情评估。
重症监护:与多参数监护仪集成,实时监测患者心脏功能。
家庭医疗:便携式心电图机可满足家庭用户的日常健康监测需求。
工作原理

ECG组成框图
心脏在收缩和舒张过程中产生电激动,其微小电流经身体组织传导至体表,形成不同部位的电位差。心电图机通过体表电极采集这些电位差,经信号调理、模数转换和数据处理后,生成心电图波形。具体流程如下:
信号采集:通过 10 个体表电极(如右手 VR、左手 VL 等)获取 12 导联心电信号。
信号调理:经仪表运放(如 INA126)前级放大、精密运放(如 ISL28248)后级放大,以及高通 / 低通滤波(HPF/LPF)去除噪声。
模数转换:利用高精度 ADC(如 ADS1258)将模拟信号转换为数字信号。
数据处理:STM32 芯片对数字信号进行滤波、放大倍数校准等处理。
显示与存储:将处理后的波形显示在 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;
}
方案特点与优势
高精度采集:采用 12 位 ADC(如 ADS1258)和精密运放,确保信号采集精度。
抗干扰设计:通过多级滤波(高通、低通、FIR)有效抑制工频干扰、基线漂移等噪声。
多导联支持:可同时采集 12 导联心电信号,满足临床诊断需求。
实时处理:STM32 的高速运算能力实现数据的实时采集、处理与显示。
低功耗设计:采用 LDO 和 DC/DC 电源管理芯片,适合便携式设备应用。
关键词: STM32

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码