心电信号采集与处理
1 实验需求分析
1.1 项目背景介绍
心电信号(Electrocardiogram, ECG)是反映心脏活动电生理变化的重要生物电信号,其特征包括心率、节律、波形等参数,能够直观反映心脏健康状况,在临床医学、健康监测和疾病预防中具有不可替代的作用。通过心电信号的测量与分析,可以检测心律失常、心肌缺血、心脏传导阻滞等异常,为心脏疾病的诊断和治疗提供关键支持;借助便携式和可穿戴设备,实时心电监测已成为健康管理的重要手段,为心血管疾病高危人群提供预警,有助于降低发病率和致死率。此外,心电信号还是生物医学研究的重要工具,为心血管药物开发、人工心脏研究等领域提供了基础数据。在当前人口老龄化加剧和心血管疾病高发的背景下,心电信号测量与分析技术显得尤为重要。本项目旨在开发高精度的心电信号采集系统,结合课程中介绍的数字信号处理等专业知识,为心脏健康提供更加便捷和智能的监测方案,推动精准医疗与个性化健康管理的发展。
1.2 心电信号特征与设计需求
心脏内部产生的一系列非常协调的电刺激脉冲,使得心脏肌肉细胞有节奏的舒张和收缩,这些信号传递到人体表面的不同部位形成不同的电位差。通过仪器设备可以从体表检测到这些微弱的电位差信号,称之为心电信号。换言之,心电信号即为人体心脏细胞细胞膜产生的电势差。在医学上,医生往往需要通过心率与幅值等参数来初步判断患者的健康状况,因此实现高精度的心率与幅值测量是本项目中设计的心电信号采集与处理系统的核心功能。
正常的心电信号频率范围为0.05Hz-100Hz,其能量集中在低频段,其中99%的能量集中在0Hz-35Hz。在其采集过程中容易受到各种干扰,主要分为三种:
工频和工频的谐波频率干扰,工频频率在我国为50Hz;
肌颤噪声和采样电路参考电压引入的电源纹波等高频噪声,频率通常在100Hz以上;
呼吸基线漂移和采样引入的直流分量,频率一般分布在0-0.7Hz。
以上的各种干扰会对心电信号采集结果产生较大的影响,使得采集到的心电信号中出现许多杂波与噪声,这是我们所不希望看到的。因此,为提高心电信号的测量精度,需要设计相应的滤波器对传感器采集到的信号进行滤波,从而减小信号中的噪声震荡,提高心率与幅值测量的准确程度。特别的,由于参考电压受环境温度变化会产生一定的温漂,以及人的呼吸活动和电极滑动也导致基线漂移。这些干扰的频率很低,通常在几Hz以内,但和心电信号的有效频谱非常接近,因此需要过渡带较窄的IIR直流陷波器来消除干扰。
基于心电信号的以上特性,对于该心电信号采集与处理系统,提出如下的技术指标需求:
0频处的缓变直流衰减不低于30dB;
降噪滤波器以35Hz为3dB通带截止频率,过渡带不超过10Hz,阻带衰减不低于40dB;
心率估算误差不超过10%。
2 实现方案论证
2.1 系统框架设计
本项目的核心目标是实现心电信号的采集与滤波以及心率测量,同时需要在屏幕上绘制时域波形与频谱图。具体而言,细分的功能如下:
实现ADS1292获取心电信号原始数据,并通过串口传输至PC电脑;
实现PC电脑中通过MATLAB对原始数据进行时域和频域分析;
实现PC电脑中通过MATLAB对原始数据进行降噪和提取心率;
实现STM32单片机中对原始数据进行降噪和提取心率;
TFT屏幕中绘制心电信号曲线和显示心率数值。
为实现以上功能,采用如下的系统设计流程:
调试ADS1292R_PowerOnInit函数中的ADS1292芯片读取,通过读取芯片device_id验证硬件功能正常且连接正确;
在中断驱动下,读取ADS1292的原始数据,并存储在单片机的存储器中;
把原始数据传输到PC;
在PC中分析原始数据的时域和频域;
在PC中设计滤波器对原始数据进行处理,并提取心率等;
把PC中的滤波器移植到单片机中;
在单片机中把心电波形和心率等数据显示到TFT屏幕。
根据如上设计流程,结合目前提供的材料,设计了如下图所示的心电信号采集与分析系统:
系统的工作流程如下:
首先,STM32控制器向心电传感器发送采集指令,传感器随后采集来自人体或模拟信号源的心电信号,并将数据反馈至控制器;
接着,控制器将采集到的数据传输至PC端,供进一步分析处理;
然后,根据PC端的分析结果,控制器会调整参数并优化心电信号处理;
最终,处理后的结果将在TFT屏幕上实时显示,供用户查看。
可以看到,该系统主要涉及到STM32主控芯片、ADS1292R传感器、TFT显示屏、心电信号模拟器以及PC端分析软件MATLAB等关键组件。接下来将对于本项目涉及的各硬件组件进行介绍。
2.2 STM32主控芯片
本项目选用的微控制器STM32F407ZG是系统的核心控制单元,负责协调各个模块的工作。其不仅负责信号的采集,还管理信号传输、滤波器应用、以及与TFT屏幕的显示操作。其强大的处理能力和灵活的控制方式使其成为整个系统的”大脑”。该控制器目前搭载在”正点原子”探索者STM32F407开发板V3上,负责完成系统的信号采集、处理与传输任务。
该单片机具备高性能的ARM Cortex-M4内核,主频高达168MHz,同时集成了丰富的外设接口,包括多个ADC通道、DMA(直接存储器访问)、定时器以及USART串口等,为心电信号的实时采集、处理与传输提供了强有力的硬件支持。它通过SPI协议与ADS1292传感器进行数据交换,采集来自人体或模拟信号源的心电信号,并进行初步处理。
2.3 心电信号模拟器
在实验的过程中,无法总是以人体作为心电信号源,因此在缺乏人体数据的情况下,本项目采用SKX-2000心电信号模拟仪作为测试时的模拟信号源。它能够生成不同类型的心电波形,广泛用于测试系统性能和验证心电信号采集、处理的稳定性。此设备对确保系统在实际使用前达到预期的性能标准至关重要。
在本项目中,主要使用到的是正常的心电波形与标准的心率信号,可以通过操作该模拟仪控制其产生心电信号的心率以及幅度。在连接方面,如图2.3所示,采用三导联接法,RA连接右手(红色),LA连接左手(黄色),LL连接左脚(绿色);通过3.5耳机动态导联线,将模拟仪产生的心电信号输入ADS1292S传感器中以供进一步采集。
2.3 信号采集传感器:ADS1292R
ADS1292R作为一款多通道同步采样的24位模数转换器(ADC),被广泛应用于生物电势测量领域,其独特的设计集成了可编程增益放大器、内部基准源和板载振荡器,确保了心电信号的精准采集。在本系统中,ADS1292R作为信号采集模块的核心组件,负责从心电电极捕获原始心电信号。这些信号随后通过SPI接口传输至STM32微控制器,供后续处理和分析。
该模块共有12个输出引脚(传感器模块右侧),各引脚接口功能说明如下:
GND:接供电电源地;
CLK:提供给ADS1292R工作的外部时钟,由于本项目采用内部时钟,故该引脚无需连接;
GPIO1、GPIO2:本项目中未使用,无需连接
SPI_SCK:接入由STM32单片机提供的SPI时钟信号;
SPI_MISO:向STM32单片机发送SPI数据输入信号;
SPI_MOSI:接收STM32单片机发出的数据输出信号;
SPI_CS0:接入STM32单片机GPIO,为ADS1292R提供片选选中信号;
ADS_DRDY:向STM32单片机发送外部中断输入,告知单片机可以通过SPI接收采集信号;
ADS_START:接入STM32单片机GPIO,为ADS1292R提供开始采集信号;
ADS_PWDN:接入STM32单片机GPIO,为ADS1292R提供复位信号RESET;
+5V:接供电电源+5V(由STM32输出)。
除此之外,由于选用的STM32单片机只允许接收0~3.3V的输出电压,故单片机通过SPI通信接收的信号电压必须限制在该范围内,因此需要将ADS1292R传感器模块中间的VDD与3.3V引脚通过跳线帽相连以实现电压转换(与图2.5中左图的连接方式相反)。
2.4 SPI通信读取采集数据
在本系统中,传感器将数字化后的原始心电信号数据通过SPI接口传输到STM32微控制器。SPI通信具有高速度、全双工传输的优势,非常适合用于实时性要求较高的应用场景。SPI接口确保了心电信号数据的快速、稳定传输,保证了信号的实时处理和准确性。通过SPI,ADS1292R和STM32微控制器能够高效地交换数据,从而提升系统的整体性能和响应速度。
SPI通信采用主从结构,其中STM32微控制器作为主设备,ADS1292R作为从设备。具体来说,SPI通信包括四个主要信号线:时钟信号(SCK)、主输出从输入(MOSI)、主输入从输出(MISO)和片选信号(CS)。时钟信号由STM32微控制器提供,用于同步数据传输。数据通过MOSI线从ADS1292R传输到STM32微控制器,而传感器通过MISO线将必要的反馈信息传回STM32。
为了提高系统的响应速度和处理效率,在单片机端选择了基于中断驱动的数据采集机制。当ADS1292R传感器完成一组心电数据的采集后,通过中断信号通知STM32F407进行数据读取和处理。这种机制有效减少了CPU的空闲时间,提高了系统的整体效率。
在单片机程序工程中,通过调用驱动库文件中的ADS1292_Read_Data函数,可以实现单片机与ADS1292R的数据交互以进行实时数据监测,并通过函数ADS1292_Send_CMD将信号数据通过UART串口以115200的波特率传输至PC端并保存。在此过程中,原始信号数据被保存为.dat格式的文件,后续将通过MATLAB读取和显示这些信号数据,并针对这些数据进行滤波器等模块的设计,对信号进行进一步验证与调试。
3 理论推导与MATLAB计算
PC端分析软件(本项目中使用MATLAB)用于对采集到的原始心电信号进行深入分析。为验证滤波器对心电信号的作用和效果,可以先在MATLAB上设计算法对心电信号进行一系列处理,包括数据读取、绘制原始数据时域波形、分析原始数据的频谱、设计数字直流陷波器、设计FIR数字低通滤波器、分析并比较滤波前后数据的频谱以及估算心率。通过这些分析,系统能够设计出合适的滤波器以去除噪声并提取出心率等重要参数,为后续移植到单片机上提供理论验证。
3.1 原始心电信号数据的读取与频谱分析
为了研究信号特征和评估处理效果,首先需要导入心电信号数据并进行基本分析。当心电信号传入单片机后,根据ADS1292R的数据手册,还需在单片机中对数据进行解码处理。在2.4节中,直接存入.dat文件的是未经过解码的原始数据,而图2.11展示的则是经过解码转换后的波形数据可视化结果(由单片机内部程序完成解码转换,将在4.2节中详细展开)。
本章中的MATLAB分析均基于未解码的.dat文件,因此要想获得真实的波形数据(电压值),需要先根据以下规则对数据进行解码(4.2中的解码基于同样的原理,后续不再赘述):
由于原始数据格式是24bits的二进制补码(7FFFFF对应的模拟信号是2.4V。800000对应的模拟信号是-2.4V),若考虑保留高16bits,需要注意此时为补码,同时也要考虑到16bits相比于24bits相当于右移了8位。所以此时7FFF的数值对应模拟信号相当于2.4V,8000对应模拟信号-2.4V。
基于这样的规则,可以在MATLAB编写对应的接收数据代码,从文件中读取数据(注意把负数的二进制补码转换为原码),其中Off可以为0或1(因为MATLAB接收的起始数据可能是16bits的高8位或者低8位,用off作为偏移调整,这样组合的数据才不会出现错位);同时通过plot函数绘制出原始心电信号的时域波形,并使用快速傅里叶变换(FFT)分析信号频谱,绘制出频谱图。
从频谱图(上右图)中可以明显观察到信号中的低频基线漂移和工频干扰(与1.2节中的分析基本一致),这些成分需要通过滤波器加以去除。
3.2 IIR数字直流陷波器设计与滤波效果
工程中使用高精度传感器采集动态信号,采集的原始数据会因为环境变化、量化字长和参考电压等因素,包含较强的缓变直流分量,如果不予以消除,会导致在降噪等处理中出现运算饱和溢出。由于在采集心电信号时,人的呼吸活动和电极滑动会导致基线漂移,而这些干扰的频率又与心电信号的有效频谱非常接近,因此需要设计窄带IIR直流陷波器来消除该干扰。
直流陷波器的传递函数Η(z)为:
$$
Η(z) = \frac{z - 1}{z - a}
$$
该数字系统的极点为z = a,零点为z=1,其中参数a决定了陷波器的过渡带宽和衰减性能,为接近1的正实数。因为零点对应的幅角ω = 0,所以数字系统在零频处的增益显著衰减(如图3.5所示),其衰减的程度与过渡带的宽度和极点a的数值有关:a越大衰减变小,同时过渡带变窄,反之则衰减增大和过渡带增宽。通过实验调整,选择a=0.992可在基线漂移和信号完整性之间取得平衡。
可以看到,在加入了直流陷波器进行滤波后,0频处的基线漂移基本被消除,说明该滤波器的设计有效并起到了很好的效果。
3.3 FIR数字低通滤波器设计与滤波效果
根据阻带衰减不低于40dB且过渡带不超过10Hz的要求,利用MATLAB中自带的filterDesigner滤波器设计工具对于FIR数字低通滤波器进行设计。在该滤波器中,采用固定窗口,通过对当前点及其前160个点的加权求和来计算输出(指定滤波器阶数为160)。
在固定窗口的选择上,由于不同窗函数的阻带最小衰减各不相同,过渡带应与对应窗函数的”精确过渡带宽”相等。以下是常用窗函数的对比表:
表3.1 不同窗函数的阻带最小衰减
窗函数 | 第一旁瓣衰减A/dB | 近似过渡带宽Bw | 精确过渡带宽 | 旁瓣峰值衰减/(dB * oct^(- 1)) |
---|---|---|---|---|
矩形窗 | -13 | 4π/N | 1.8π/N | 21 |
汉宁窗 | -31 | 8π/N | 6.2π/N | 44 |
海明窗 | -41 | 8π/N | 6.6π/N | 53 |
布莱克曼窗 | -57 | 12π/N | 11π/N | 74 |
凯泽窗(β = 7.865) | -57 | 10π/N | 80 |
在实际设计中,选择Chebyshev(切比雪夫)窗,其主要特点为:在给定窗口长度的情况下,能够提供最小的主瓣宽度。因此,通过选用Chebyshev窗,在频域上最小化主瓣的振幅波动,以实现滤波器的设计。
除此之外,设计时还指定采样频率为500Hz,阻带频率设计为35Hz,确定好参数后可在filterDesigner工具中导出为MATLAB函数:
在主程序中调用生成的滤波器函数构造一个FIR数字低通滤波器实例,并利用filter函数对于直流陷波后的波形数据进行FIR滤波并通过plot函数绘制滤波后的频谱,代码与结果如下所示:
可以看到,在加入了数字低通滤波器进行滤波后,50Hz处的工频干扰完全被消除,说明该滤波器的设计有效并起到了很好的效果。
3.4 滤波结果综合分析
通过IIR和FIR滤波器的级联处理,最终获得了较为清晰的心电信号波形(如图3.9所示)。此过程有效去除了干扰,为后续心率计算和信号分析提供了可靠的基础。
为了更直观地展示信号处理过程的效果,对心电信号在各个处理阶段的频谱进行了对比分析。图3.10中显示了原始心电信号以及经过直流陷波器和FIR低通滤波器联合处理后的信号频谱图。
从原始心电信号频谱可以看出,信号中存在显著的工频干扰(约50Hz)和低频基线漂移(频率较低)。此外,信号还包含较多高频噪声,影响了心电信号的质量。经过直流陷波器处理后,低频基线漂移明显被抑制,低频成分显著减少但同时工频干扰和高频噪声依然存在,但其幅值未发生明显变化,表明直流陷波器主要对低频干扰起到作用;在应用FIR低通滤波器后,信号中50Hz附近的工频干扰被有效抑制,同时高频噪声也显著减弱。
最终处理后的频谱显示出清晰的心电信号主频成分(低于30Hz),为后续的R波检测与心率计算提供了可靠的基础。
3.5 心率计算
在对原始心电信号完成滤波处理后,可进一步估算心率这一关键生理参数。心率的计算基于心电信号中的R波峰值检测,通过分析相邻R波之间的R-R间期推算心率值。R波的检测是心率估算的关键环节。在此实验中,采用MATLAB函数findpeaks来检测心电信号中的峰值。为提高检测精度,将滤波后的信号进行缩放,并设置峰值检测的阈值为信号均值加一倍标准差。
检测到R波位置后,可通过计算相邻峰值位置之间的时间间隔(R-R间期)来估算心率。使用diff函数计算相邻R波的时间间隔并计算R-R间期的平均值,并根据如下公式计算出心率:
$$
心率 = \frac{60}{平均R - R间期}
$$
最终得出结果为60.29bpm,对比实际信号发生仪60bmp的心率,可以较为准确地估算心率,其结果符合误差小于10%的预期。
4 STM32程序设计与参数选择
项目代码已推送至Github远程仓库:Asgard-Tim/ECG_Final_Project
4.1 单片机程序架构设计
为实现2.1节所提出的基本功能,除了要采集心电数据并对其进行滤波、显示时域波形外,还需要对滤波后的波形进行频谱分析并显示。为了更高效地完成这一过程,系统引入了快速傅里叶变换(FFT)算法,用于将时域信号转化为频域信号,便于分析信号的频谱特性。然而,由于FFT计算量较大,尤其是在较高采样率下,需要处理大量的点,因此为了加快运行速度,程序采用了FreeRTOS实时操作系统,分别对信号滤波和频谱分析进行任务划分和并行处理。
在系统的实现中,FreeRTOS将任务分为信号采集与滤波任务ECG和FFT计算任务。如上图所示,信号采集任务负责从ADS1292R中读取原始心电信号,并完成IIR和FIR滤波的处理,将滤波后的数据存储到循环缓冲区中,通过中断驱动的方式与传感器交互,确保数据的实时性和可靠性;而FFT计算任务则专注于对缓冲区中的数据进行频谱分析,每当缓冲区填满指定数量的数据点时,FFT计算任务将被启动,这虽然会导致实际运行时FFT频谱更新会产生一定的延时,但这样的设计将使得整个系统的工作更加稳定可控。
通过引入FreeRTOS,系统充分利用了单片机的多任务并行能力,使信号滤波和频谱分析的运行效率大幅提升,同时保证了心电信号处理的实时性。滤波和频谱分析的结合,不仅提高了信号的可用性,还为后续的心率计算和心电异常检测提供了更加丰富和可靠的数据支持。
4.2 采集原始数据解码
通过SPI接口,STM32微控制器不断与ADS1292R传感器进行交互,读取其输出的24位数字信号数据。基于3.1节提到的价码规则,将读取到的数据经过必要的解码和处理后,可将其转换为实际的电压值,并进一步用于实时显示与分析。其核心代码如下所示:
在具体实现中,通过将ADS1292R的24位原始数据解码为32位有符号整数,消除了符号位可能引起的误差。随后,将解码后的信号根据增益和参考电压转换为实际的电压值。这一过程中,左导联和右导联的连接状态也会被实时检测,以确保数据采集的可靠性。如果导联连接异常(如电极松动),系统会发出提示并暂停后续的采集。
4.3 处理算法移植:滤波器
经过STM32接收心电信号后,系统根据PC端设计好的滤波器方案对原始信号进行双重滤波处理,先通过IIR滤波器消除直流分量,然后利用FIR滤波器进一步去除高频噪声,从而得到更为清晰的心电信号。经过IIR和FIR滤波后的信号显著改善,直流漂移、工频干扰以及高频噪声均被有效抑制,这一改进不仅提高了信号的可分析性,也为后续的特征提取与心率计算打下了坚实基础。
滤波后,处理得到的心电信号被传输至PC端,并通过可视化工具显示其改进的波形。如下图所示,信号的基线漂移已完全消除,高频噪声也显著减弱。滤波后的心电信号为后续的心率估算和其他心电特征分析提供了高质量的数据输入,从而提升了系统的整体性能和实用性。
4.3.1 IIR数字直流陷波器
在IIR滤波阶段,STM32程序参考了PC端的滤波器设计,实现了高效的实时滤波。IIR滤波器的核心算法通过递归关系计算当前输出值,其中参数a=0.992控制直流分量的衰减程度。算法以较少的存储空间完成了对信号直流漂移的有效抑制,使用上一输入与上一输出值的递归关系更新当前输出值,从而达到实时滤波的目的。
4.3.2 FIR数字低通滤波器
经过IIR滤波后,信号中的直流分量被有效去除,但仍可能含有工频干扰和其他高频噪声。因此,信号会进一步通过FIR滤波器进行处理。FIR滤波器利用一个固定长度的滑动队列实现,其滤波系数矩阵B由MATLAB中的filterDesigner工具生成并导出到C代码中。该滤波运算采用定点方式,在初始化时需要将滤波器系数乘以66536(如图4.5中右图所示),再取整保存为16bits整数。该部分的核心算法是,通过遍历队列数据与滤波器系数进行逐项乘积累加,实现对信号的精准滤波。代码设计充分考虑了队列操作的效率,通过队列循环的方式减少内存消耗并保证实时性。
4.4 处理算法移植:心率与幅值计算
系统的心跳检测功能基于心电信号的峰谷变化,通过heartbeat_check函数实现对R波峰值的实时检测。该函数采用简单高效的阈值法,以波峰和波谷之间的差值判断是否发生心跳事件。函数的核心逻辑包括记录当前波形的上升和下降趋势,以及动态调整波峰(up_value)和波谷(down_value)的值。
具体来说,当检测到波形从下降趋势转为上升趋势,且波峰与波谷的差值超过设定的阈值(经过调试设置为0.55较为合适),即判定为一次心跳事件。此时,波峰和波谷会重新初始化,为下一次心跳检测做好准备。如果当前波形变化幅度未达到阈值,则认为是噪声或非心跳波形,函数返回0。
在实际应用中,该函数与DWT模块配合使用,每次心跳事件发生时记录时间戳,通过计算相邻两次事件的时间间隔(R-R间期)估算心率。高精度的DWT计数器和简洁的心跳检测算法相结合,使得系统能够在保证实时性的同时,准确识别心跳并计算心率。
为衡量心率信号的幅值范围,编写函数 Cal_PeakToPeak 以计算一组浮点数数据的峰峰值,即数据中的最大值与最小值之间的差值,用以反映数据的动态范围或振幅。函数通过接收一个浮点数数组 samples 和数组中的元素个数 sample_count 作为输入,首先将数组的第一个元素初始化为当前的最大值和最小值,然后从第二个元素开始逐一遍历整个数组。在遍历过程中,函数逐步更新最大值 max 和最小值 min,确保能够捕获数据中的真实极值。遍历完成后,函数通过计算 max - min 得到峰峰值,并将结果作为返回值。整个过程采用单次遍历的方法,计算效率较高,适合处理较大规模的采样数据。
4.5 TFT屏幕绘制采集波形
TFT屏幕是系统的重要输出模块,负责实时显示处理后的心电波形和心率数据。通过高分辨率和快速刷新率,TFT屏幕能够清晰呈现心电信号的变化,供用户随时监控自己的心脏健康状况。它不仅显示心电波形,还提供当前的心率和可能的异常信号提示,帮助用户及时发现问题。
对于已经滤波后的心电信号,在移植并调用原有LCD驱动库的基础上,编写了drawCurve函数实现实时的波形显示。该函数根据输入的心电信号数值,将其映射到屏幕的像素坐标,并绘制出连续的曲线。
可以看到,对于滤波后的心电信号值,除了基本的指定区域绘制波形外,为避免波形超出屏幕边界,还对计算得到的y坐标进行上下限约束,使其始终位于屏幕的有效显示区域内:如果y坐标超过屏幕范围,则自动截断至边界位置;当x坐标超出屏幕宽度时,程序清空屏幕并从起始位置重新开始绘制新的波形。通过这种循环显示方式,确保波形在屏幕上以滚动形式连续更新,为实时心电信号的监测提供直观的显示效果。
4.6 频谱分析及其TFT屏幕绘制
在频谱FFT计算的具体实现中,程序使用CMSIS-DSP库提供的高效FFT算法,首先将心电信号数据打包为复数输入,其中实部为滤波后的心电数据,虚部置为零。随后调用arm_cfft_radix4_f32函数完成快速傅里叶变换,并通过arm_cmplx_mag_f32函数计算复数频谱的幅值。计算结果存储在FFT输出缓冲区中,用于后续的频谱绘制。
对于频域波形,系统通过FFT算法计算心电信号的频率分量,并将其可视化为频谱图。频谱图的x轴代表频率,y轴代表频率分量的幅值,能够直观反映心电信号的频率特性。频域波形的可视化主要依赖Draw_Spectrum函数:
由于屏幕高度有限,为避免绘图时坐标溢出,函数将FFT输出的幅值限制在合理范围内(0到150,其余位置留给时域波形)。当幅值超过上限或低于下限时,进行截断处理。每个频率分量对应一条垂直线,从屏幕底部开始绘制到计算得到的y坐标。
5 程序测试方法
5.1 ADS1292R驱动移植及引脚配置
首先,在通过STM32CubeMX创建工程时,需要配置单片机的时钟速率,SPI接口,中断以及UART串口通信等。为实现与ADS1292R传感器的数据传输,选用SPI1并对引脚进行如下配置:
其中与ADS1292R传感器通信的SPI接口配置为主模式,时钟极性为CPOL=LOW,时钟相位为CPHA=2EDGE,数据帧格式为8位,通信速率依据传感器要求设置在8MHz以下,此处设置为656.25Kbit/s。
此外,还需要根据ADS1292R库文件中的说明,对UART通信进行设置,其中波特率设置为115200,8位数据位,1位停止位,无校验。
完成引脚配置后就可以进行初始代码生成。在生成的初始代码工程中,引入ADS1292R的相关库文件(ADS1292R.c与ADS1292R.h),根据对应的配置代码将STM32F407开发板与ADS1292R传感器模块进行连线:
连线完成后,要通过SPI接口实现与ADS1292R的数据交互,还需要在主程序中完成相应的初始化,即调用ADS1292R驱动库中的相关函数,由单片机向ADS1292R发送相应的命令以启动数据采集,并配置工作模式、采样速率、增益等参数。根据ADS1292R数据手册及项目要求,以下是对ADS1292R的主要配置过程:
首先,将ADS1292R的CONFIG2寄存器配置为0xA3,以启用内部参考电压。内部参考电压的稳定性对于后续心电信号的准确采集至关重要,因此在配置完成后需通过DWT_Delay_ms(10)添加延时,确保内部参考电压稳定。随后,将CONFIG1寄存器设置为0x02,配置心电采集的采样速率为500SPS(Samples Per Second),这一速率能够兼顾信号的时域分辨率和数据量。
接下来,对通道1和通道2进行配置。其中,通道1的CH1SET寄存器设置为0x00,表示通道1工作于正常采集模式,且未启用测试信号输入。通道2的CH2SET寄存器配置为0x05,用于指定通道2采集来自内部测试信号的方波,方便在调试阶段验证系统的采集和传输功能。
此外,为了进一步优化信号的质量,对右腿驱动(RLD)电极进行了配置,通过将RLD_SENS寄存器设置为0x2C,使右腿驱动电极同时连接到通道1和通道2,增强了共模信号的抑制能力。在呼吸阻抗测量相关功能中,将RESP1和RESP2寄存器分别配置为0x02和0x03,根据手册要求开启适当的工作模式。
通过上述配置,ADS1292R可以稳定运行于双通道心电采集模式,通道1用于实时采集患者的心电信号,通道2可用于采集ADS1292R传感器的测试信号以验证该传感器模块是否被正常驱动。
5.2 ADS1292R驱动移植验证:读取传感器设备ID
事实上,在ADS1292_PowerOnInit函数中,图5.5所示初始化代码之前还有一段代码:
可以看到,要实现5.1节中对于ADS1292R传感器模块的正确驱动,就必须要顺利运行该段代码,其中调用了ADS1292_ReadDeviceID这一函数并设置了判断条件,若读取到的设备ID不为83(ADS1292)或115(ADS1292R)则会一直循环读取ID而不进行后续的初始化,以确保读取的心电信号不会出现无效数据且采集数据符合预期格式。由于本次项目使用的传感器芯片为ADS1292R,故成功读取到并在串口助手中打印的device_id为115,这也证明驱动库文件的移植是正确的且能正常驱动该传感器模块。
5.3 ADS1292R驱动移植验证:测试信号采集及其TFT屏幕绘制
在ADS1292R的芯片数据手册中,给出了其内置测试信号的相关参数:
可以看到,当PGA增益倍数设置为1时,芯片将输出测试方波信号,通过MATLAB读取并解码原始数据,得到(含直流)范围在-20到8;而去除直流后,该方波动态范围为-14到14。由于参考电压为2.4V(16bits),此时14/32768*2400mv
约等于1mv,说明此时方波动态范围转换为电压是正负1mv,和数据手册说明一致。方波测试信号的成功读取也进一步验证了ADS1292R驱动库移植的正确性且能正常驱动该传感器模块。
图5.8:MATLAB读取测试方波结果
6 实验数据记录与分析
演示视频链接:https://www.bilibili.com/video/BV1HWCkYzETe/
6.1 测试信号采集
在测试ADS1292的内部方波信号时,设置PGA增益为1,测试结果显示方波波形良好,基本无误差。系统能够准确读取方波信号的峰峰值和幅度值,其效果如图所示:
此外,系统新增了按键功能,按压KEY_0即可实现在显示测试信号波形与显示心电信号波形间切换。
6.2 模拟器心电信号采集
在实际运行中,drawCurve函数结合系统滤波模块的输出数据和心跳检测结果,将心电信号时域与频域的动态变化以实时曲线的形式绘制在屏幕上。同时,在屏幕上显示心率、波幅等关键参数,进一步增强了系统的直观性和信息量。其效果如下图所示:
经过测试,测算出的心率值与心电模拟仪中给出的心率值误差不超过3 BPM(每分钟心跳数),满足系统设计需求;但此时滤波器的滤波效果有点过度,也可能是显示的波形幅度调整的不好,导致最终显示的波形丢失了过多的有用信息。
6.3 模拟器心率信号采集
将模拟器调至2档(心率档),产生的心率信号默认为75BPM,此时时域与频域波形的显示效果如下:
可以看到,此时测得的心率基本准确,与心电模拟仪中给出的心率值误差不超过3 BPM,满足系统设计需求,且频谱图也有较明显的尖峰且噪声较少;此时滤波器的滤波效果虽然也有点过度了,但效果明显由于6.2节中对于心电信号的测量,有明显的波峰。
心跳检测功能的设计不仅能够适应动态变化的心电信号,还通过灵活的阈值调整提高了对不同信号幅度的适应性。将模拟器调至8档,以调整产生心率信号的幅值(心率BPM仍为75),采集与显示效果如下:
可以看到,随着心率信号幅值的成倍变化,测量出的波形幅值也在成倍变化,且频谱较为干净,这说明该心电信号采集系统对于不同的信号幅度具有较高的灵敏性,但未对测量的幅值数值进行对应电压的换算导致结果并不直观;同时由于测量心率程序中对于检测跳变幅度的阈值设置较小,导致此时当幅值明显增大时,震荡信号的跳变幅度也随之增加,导致心率测量出现一定程度的偏差。
6.4 人体心电信号采集与测量
未接入人体心电信号时,采集到信号的时域波形与频谱如下:
对于人体心电信号检测,由于心电电极对接触状态的敏感性,最佳效果仅在涂抹酒精并佩戴三分钟内获得,因此系统仅能在心电电极贴附于人体的短时间内实现精确检测
在实际测试时,邀请室友将电极片分别贴于手腕和脚部,并分别与数据线连接,此时系统采集到的心电波形如下所示(详细测试过程在演示视频中):
从图中可以看出,检测人体心电信号时,波形与心电信号模拟仪的输出相比仅存在轻微差别,整体表现良好,但仍然存在滤波过度的问题。
除了将电极贴于手腕和脚部进行测试外,系统还测试了将电极贴在左右锁骨中线第一肋间和胸骨左缘第四肋间的位置。测试结果显示,这些位置的信号稳定性优于手脚部位,并且能够维持更长时间的良好效果。
7 实验结果总结和心得体会
7.1 实验结果
在本项目中,基于 STM32F407ZG 主控芯片和 ADS1292R 传感器模块,成功实现了人体心电信号的采集与分析功能。针对心电信号易受工频干扰和低频基线漂移影响的问题,设计并实现了 IIR 数字直流陷波器 和 FIR 数字低通滤波器,有效消除了干扰并获得了较为清晰的心电波形。
在开发过程中,利用心电信号模拟仪对单片机程序进行了调试,使系统能够稳定采集和显示心电波形。尽管滤波器在MATLAB仿真中效果良好,但移植到单片机工程中后,出现了滤波过度的问题。初步分析认为,这可能与信号采样频率、显示波形的幅度比例调节以及滤波算法的具体实现有关,仍需进一步优化。然而,系统总体性能令人满意,其采集效果、频域分析结果、心电峰峰值及心率测算结果均较为准确。
此外,系统还实现了对 ADS1292R模块自带测试方波信号的读取、显示以及峰峰值测量功能,基本满足了所有的设计需求。最终也成功采集并显示了实际人体心电信号的时域波形与频谱。
7.2 心得体会
通过本次项目的实践,我对数字信号的采集与处理以及滤波器的设计与实现有了更加深刻的理解。这不仅加深了我对数字信号处理理论知识的掌握,还让我在理论与实践的结合中得以进一步巩固相关技能。在单片机的编程实践与调试过程中,我对STM32尤其是F4系列开发板的硬件和软件开发有了更深入的认识,这大大提升了我的开发效率和调试能力。
本项目也是我首次尝试使用 FreeRTOS操作系统搭建整个工程框架。在此过程中,我学习并掌握了实时操作系统的基本原理和任务调度机制,初步理解了如何优化系统资源管理,成功地将操作系统的使用融入到嵌入式项目开发中。这一尝试不仅丰富了我的开发经验,也让我更好地认识到实时操作系统在复杂工程中的价值。
尽管最终心电信号的显示结果并未完全达到预期,但我从问题中发现了自身在信号采集频率、滤波算法实现以及系统显示优化方面的不足,并明确了未来改进的方向。整个项目开发的过程充满了挑战,同时也伴随着大量的收获。我深刻体会到硬件开发与数字信号处理是一个不断探索和优化的过程,而这次项目实践无疑为我在这些领域的技能提升打下了坚实基础。
此外,本次项目还培养了我独立分析和解决问题的能力。从模块功能的实现到整体工程的构建,我逐步熟悉了完整的开发流程,对系统的设计、调试和优化有了更加系统化的认识。我相信,这些经验和能力将在今后的学习和工作中发挥重要作用,为更高层次的开发任务奠定基础。
参考资料
[1] 朱冰莲,方敏编著.数字信号处理[M].电子工业出版社,2014:276.
[2] 程佩青编著.数字信号处理教程[M].清华大学出版社,2015:524.
[3] 任勇,曾浩编著.单片机原理及应用[M].清华大学出版社,2023.
[4] 德州仪器. ADS1292 数据手册
[5] 任勇. CQU_S12XDEV开发板原理图 微电子与通信工程学院
[6] 任勇. ADS1292-心电信号采集原理图及接口说明-RY