简介本资源是一套完整的心电采集系统整机开发方案面向电子工程师、嵌入式开发者及医疗设备研发人员解决从生物信号采集、硬件电路实现到嵌入式软件控制的全链路技术落地问题。压缩包共111个文件涵盖Altium Designer格式的PCB工程.pcbdoc与原理图.schdoc、基于C语言的单片机固件源码.c/.h为主含MKL25Z4系列底层驱动如system_MKL25Z4.c、usb.c等、上位机通信支持文件及编译输出产物.hex/.axf/.bin整体大小仅2.98MB结构紧凑、模块清晰便于快速部署与二次开发。已有637人学习下载适用于课程设计、毕业设计、便携式心电仪原型开发及嵌入式医疗电子项目实践。读者可直接导入AD进行PCB修改复现信号调理—ADC采样—实时滤波—串口上传全流程并基于源码深入理解低噪声模拟前端设计、ARM Cortex-M0平台资源调度及心电信号数字处理逻辑。1. 项目概述从零到一的心电采集系统全栈实现最近在整理过往的项目资料翻到了一个几年前做的便携式心电采集设备项目。当时的目标很明确做一个能稳定采集、处理并初步显示心电信号的完整硬件系统。这个项目麻雀虽小五脏俱全从传感器前端、模拟信号调理、主控MCU选型、PCB设计、嵌入式固件开发一直到最后的整机结构全都自己动手走了一遍。今天就把这个项目的核心资料——“心电采集 ,PCB工程原理图,硬件电路,源程序C语言,整机方案.zip”里的干货结合我踩过的坑和积累的经验系统地拆解一遍。无论你是刚入门的硬件工程师、嵌入式开发者还是对生物电信号采集感兴趣的爱好者这篇文章都能给你提供一个从图纸到成品的完整参考路径。心电信号极其微弱频率低且极易受到干扰整个设计过程就是一场与噪声和共模干扰的持续斗争。2. 硬件电路设计与微伏级信号共舞心电采集硬件设计的核心是构建一个能“听见”心脏微弱电信号的精密“耳朵”。这个“耳朵”必须足够灵敏能捕捉到0.5mV到5mV的QRS波又必须足够“聪明”能屏蔽掉比它强成百上千倍的工频干扰、肌电噪声和基线漂移。2.1 前端模拟电路仪表放大器与右腿驱动整个信号链的起点是电极。我们通常采用标准的三电极系统RA右臂、LA左臂和RL右腿。RA和LA之间的差分信号就是我们要放大的心电信号。这里第一个关键器件是仪表放大器。我选择了经典的AD620。为什么是它首先它的输入阻抗极高10GΩ以上这意味着它几乎不从人体“抽取”电流不会影响信号源。其次它的共模抑制比非常高在60Hz时典型值大于100dB这是对抗50Hz工频干扰的第一道也是最重要的一道防线。AD620的增益由一颗外部电阻Rg决定公式是 G 1 (49.4kΩ / Rg)。为了将毫伏级的心电信号放大到适合ADC采样的范围比如0-3.3V第一级增益通常设置在100-200倍。我选择了150倍计算一下Rg 49.4kΩ / (G - 1) 49.4kΩ / 149 ≈ 331Ω。这里有个细节Rg的精度和温漂直接影响增益稳定性所以务必使用1%精度、低温漂的金属膜电阻。放大后的信号依然包含大量的共模干扰。这时就需要引入右腿驱动电路。RL电极不直接接地而是接入一个反向放大器的输出端。这个放大器的输入是RA和LA信号的共模平均通过两个大电阻取平均得到。其原理是系统检测到共模电压然后通过RL电极向人体注入一个反相的电流从而主动抵消人体感应的共模电压。这相当于把人体“驱动”到一个虚地电位能显著提升整个系统的共模抑制能力。电路中的反馈电阻和电容需要仔细计算以确保环路稳定不会产生振荡。2.2 滤波与电平移位从生物信号到数字世界经过仪表放大器放大后信号中除了心电还有肌电高频、基线漂移极低频等噪声。因此必须进行滤波。高通滤波用于消除因呼吸、电极接触压力变化引起的缓慢基线漂移。心电的有效频率下限一般在0.05Hz到0.5Hz。我设计了一个一阶RC高通滤波器截止频率设在0.5Hz。电容和电阻的取值需要权衡为了达到低的截止频率RC值需要很大这意味着要么用大电容体积大、漏电流大要么用大电阻热噪声大。我选择了一个1μF的CBB电容和一个330kΩ的电阻f_c 1/(2πRC) ≈ 0.48Hz。注意这个电容的漏电流必须非常小否则会引入直流误差。低通滤波用于滤除肌电干扰通常100Hz和高频噪声。心电信号的主要能量集中在0.05Hz到100Hz之间QRS波的主要频率在10-25Hz。我将低通滤波器的截止频率设在150Hz这是一个比较常用的值能在保留QRS波主要特征和抑制高频噪声之间取得平衡。我采用了一个二阶Sallen-Key低通滤波器因为它设计灵活元件值容易获取。滤波之后信号是交流的以0V为中心上下波动。但大多数MCU的ADC只能测量0到正电源电压如3.3V的信号。因此需要一个电平移位电路将信号平移到ADC量程的中间比如1.65V。这通常通过一个电压跟随器加一个偏置电压由电阻分压产生来实现。这样心电信号的负半周也能被ADC正确采集。2.3 电源与参考电压系统的基石模拟电路的性能极度依赖干净、稳定的电源。我使用了线性稳压器如AMS1117-3.3为模拟部分供电并与数字部分MCU的电源通过磁珠或0Ω电阻进行隔离防止数字噪声串扰。对于运放有时需要双电源如±2.5V以获得最大的动态范围这可以通过电荷泵芯片或专用的双路输出LDO来生成。ADC需要一个稳定的参考电压。我强烈建议不要直接使用MCU的VCC作为参考因为VCC的任何纹波都会直接反映为测量误差。应该使用一颗独立的、低噪声的基准电压源芯片如REF30333.3V。它的初始精度和温漂比MCU内部的参考好得多。3. PCB设计实战布局布线决定性能上限原理图正确只是成功了一半PCB布局布线才是决定最终噪声水平的关键。心电采集板的PCB堪称“模拟艺术”的试金石。3.1 层叠与布局规划对于这种混合信号板至少需要4层板顶层信号/元件、内电层1模拟地AGND、内电层2电源/数字地DGND、底层信号/元件。模拟地和数字地必须在一点连接通常这个“星形接地点”选择在ADC芯片下方或电源入口处。在布局上严格遵循信号流方向电极接口 - 保护电路 - 仪表放大器 - 滤波电路 - 电平移位 - ADC - MCU。从左到右或从上到下避免信号走线回环。模拟部分和数字部分要物理隔离。将所有模拟器件运放、模拟滤波器、基准源集中放在板子的一侧数字器件MCU、晶振、数字接口放在另一侧。中间用一条“壕沟”无铜区域进行分隔只在星形接地点处跨接。3.2 关键信号线的布线规则电极输入线这是板上最敏感的信号。必须采用差分对走线从电极接口到仪表放大器的输入引脚两条线要严格等长、等宽、平行紧贴走线并包地处理。它们下方的内层必须是完整的模拟地平面为其提供最短的返回路径。去耦电容每个IC的电源引脚附近必须放置一个0.1μF的陶瓷电容并尽可能靠近引脚放置。对于运放和ADC有时还需要并联一个10μF的钽电容来滤除低频噪声。电容的接地端要通过过孔直接连接到最近的内电层地平面而不是通过一段细线绕远。晶振MCU的晶振是巨大的高频噪声源。要将晶振和其负载电容尽可能靠近MCU的时钟引脚放置并用地线包围起来下方不要走任何敏感的信号线。避免锐角与直角走线转弯用135度角或圆弧避免90度直角后者在高频下相当于一个辐射天线。Gerber文件检查投板前务必用Gerber查看器如GC-Prevue仔细检查每一层。重点检查阻焊层是否覆盖了需要焊接的焊盘丝印是否清晰且不与焊盘重叠钻孔文件是否正确。注意很多初学者容易犯的一个错误是在模拟区域的地平面上为了走线方便而随意切割。这破坏了地平面的完整性会 dramatically 增加信号回流路径的阻抗和环路面积引入意想不到的干扰。记住对于低频模拟电路一个完整、干净的地平面比什么都重要。4. 嵌入式软件C语言架构与核心算法硬件采集到的只是电压序列软件的任务是将其转化为有意义的心率值和波形。我主控选用的是STM32F103C8T6性价比高资源足够。4.1 驱动层ADC、定时器与通信首先配置ADC采用定时器触发、DMA传输的模式。这样ADC可以以固定的采样率比如250Hz或500Hz自动工作采样结果通过DMA直接搬运到内存中的环形缓冲区完全不需要CPU干预。这保证了采样时序的绝对精确也为CPU节省了大量资源用于信号处理。// 示例ADC DMA配置核心代码片段 #define ECG_BUFFER_SIZE 500 volatile uint16_t ecg_raw_buffer[ECG_BUFFER_SIZE]; void ADC_DMA_Init(void) { // 1. 配置ADC为扫描模式连续转换 ADC_InitStructure.ADC_ScanConvMode ENABLE; ADC_InitStructure.ADC_ContinuousConvMode ENABLE; ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_T3_TRGO; // 由TIM3触发 // 2. 配置DMA DMA_InitStructure.DMA_PeripheralBaseAddr (uint32_t)(ADC1-DR); DMA_InitStructure.DMA_MemoryBaseAddr (uint32_t)ecg_raw_buffer; DMA_InitStructure.DMA_BufferSize ECG_BUFFER_SIZE; DMA_InitStructure.DMA_Mode DMA_Mode_Circular; // 环形缓冲区模式 // 3. 配置TIM3以固定频率如250Hz产生TRGO事件 TIM_TimeBaseInitTypeDef TIM_InitStructure; TIM_InitStructure.TIM_Period SystemCoreClock / 250 - 1; // 计算ARR值 TIM_InitStructure.TIM_Prescaler 0; TIM_InitStructure.TIM_TriggerOutput TIM_TRGOSource_Update; // 更新事件作为触发输出 // ... 初始化并使能 }通信接口如UART/USB CDC用于将处理后的数据发送到上位机进行显示或存储。这里要注意数据打包的格式和效率。4.2 信号处理层数字滤波与QRS检测DMA缓冲区里的原始数据含有大量噪声需要在软件中进行数字滤波。工频陷波虽然硬件有RLD和高CMRR但50Hz干扰可能仍有残留。我实现了一个二阶IIR陷波器中心频率50Hz带宽5Hz。其传递函数需要根据采样率进行设计可以用MATLAB的fdatool生成系数然后移植成C代码的差分方程。软件带通滤波进一步滤除基线漂移和高频噪声。一个5阶的巴特沃斯数字带通滤波器0.5Hz - 40Hz是不错的选择。同样系数离线计算好。核心是QRS波检测算法用于计算心率。我采用了经典的Pan-Tompkins算法的简化实现。其步骤包括带通滤波已实现。微分计算信号的斜率突出R波的上升沿和下降沿。diff[n] (ecg[n] - ecg[n-2]) / 2。平方squared[n] diff[n] * diff[n]使所有点为正并放大R波特征。滑动窗口积分integrated[n] (1/N) * sum(squared[n-N1] to squared[n])平滑波形形成一个更容易检测的峰。窗口宽度N通常对应约150ms的采样点数。自适应阈值检测这是算法的灵魂。维护两个动态阈值——峰值阈值和噪声阈值。当积分波形超过峰值阈值时判定为一个可能的R波。阈值会根据最近检测到的信号峰值和噪声峰值进行更新从而适应信号幅度的变化。// 简化的自适应阈值检测逻辑 float peak_threshold 0.0; float noise_threshold 0.0; int searchback_window FS * 0.2; // 例如采样率FS250Hz则窗口为50个点 for(int i 0; i buffer_len; i) { if(integrated[i] peak_threshold) { // 找到候选峰值 int max_index i; // 在附近搜索真正的峰值点避免在上升沿误触发 for(int j 1; j searchback_window; j) { if(integrated[i-j] integrated[max_index]) max_index i-j; if(integrated[ij] integrated[max_index]) max_index ij; } // 确认max_index为R波位置计算RR间期 calculate_heart_rate(max_index); // 更新阈值新峰值阈值 旧噪声阈值 0.25 * (新峰值 - 旧噪声阈值) // 新噪声阈值 旧噪声阈值 0.125 * (新峰值 - 旧噪声阈值) float new_peak integrated[max_index]; peak_threshold noise_threshold 0.25 * (new_peak - noise_threshold); noise_threshold noise_threshold 0.125 * (new_peak - noise_threshold); } }4.3 应用层与系统整合应用层负责协调所有任务它从DMA缓冲区读取一批新数据调用信号处理函数更新心率值并通过串口发送数据包。这里需要使用实时操作系统或精心设计的前后台系统。我使用了FreeRTOS创建了三个任务一个高优先级的“数据采集处理”任务一个中优先级的“通信”任务一个低优先级的“指示灯/按键”任务。任务间通过队列传递处理好的数据包确保了系统的实时性和稳定性。5. 整机集成与调试从板卡到可靠产品单板调试通过后就要将其装入外壳成为一个完整的设备。这一步的挑战在于电磁兼容和可靠性。5.1 结构设计与屏蔽外壳最好选择导电材料如铝合金并与PCB的系统地良好连接。这为内部电路提供了一个法拉第笼屏蔽外部辐射干扰。如果使用塑料外壳则需要在内部喷涂导电漆或贴导电泡棉。电极线从外壳引出的接口处是干扰入侵的薄弱点需要使用带滤波功能的连接器或者在入口处增加磁珠和滤波电容。电池供电会引入新的问题。电机、DC-DC升压电路的开关噪声是巨大的干扰源。必须确保电池供电线路与敏感的模拟电路部分有足够的距离并在电源入口处增加π型滤波电路。如果设备有LCD屏其背光驱动电路也是噪声大户需要单独隔离和滤波。5.2 系统级调试与性能验证整机装配好后需要进行全面的测试共模抑制比测试在RA和LA电极上同时注入一个50Hz、几伏特的共模正弦波模拟工频干扰测量输出端该信号的幅度。计算CMRR 20 * log10(输入共模电压 / 输出共模电压) 差分增益。一个合格的心电前端CMRR至少应达到80dB以上。输入噪声测试将输入端短路或接一个模拟人体阻抗的RC网络到地用高精度ADC或示波器观察输出端的噪声电压峰峰值和有效值。这个值应该远小于心电信号的幅度。动态范围测试输入一个标准幅度的模拟心电信号可用信号发生器产生观察输出是否线性放大且没有削顶失真。长期稳定性测试让设备连续工作数小时甚至数天观察心率输出是否稳定基线是否漂移。这能暴露电源热稳定性、运放失调电压温漂等问题。真人实测这是最终检验。对比商用设备或标准心电图机观察波形形态P波、QRS波群、T波是否清晰可辨心率计算是否准确。注意不同个体、不同电极贴放位置带来的信号差异。调试过程中示波器是眼睛频谱分析仪如果条件允许则是X光。时域上看波形是否干净频域上看50Hz及其谐波成分是否被有效抑制。遇到问题要系统性地排查是电源纹波是地线设计不当还是软件滤波参数不合适通常需要硬件和软件手段结合使用。6. 开发环境与工具链的选型心得一个流畅的工具链能极大提升开发效率。这个项目涉及硬件和软件我使用的工具组合如下原理图与PCB设计我主要使用Altium Designer。它的集成度高从原理图到PCB再到生产文件输出一气呵成。对于这种模拟混合信号板其强大的规则检查DRC和层叠管理器非常有用。当然KiCad作为免费开源工具也越来越强大完全能够胜任此类设计。嘉立创EDA则胜在云端协作和与国内打样、元器件商城的无缝对接特别适合快速原型验证。关于Allegro与Altium网络热词里提到了两者的区别。简单说AllegroCadence在高速、高密度、复杂IC封装设计领域是行业标准规则驱动设计能力极强但学习曲线陡峭更适合大型公司芯片级和复杂主板设计。Altium则更偏向于通用型板卡设计界面相对友好集成库管理方便对于消费电子、工控、仪器仪表等领域的工程师来说更容易上手。对于心电采集板这种复杂度Altium或KiCad绰绰有余。MCU开发STM32生态下STM32CubeIDE是官方免费的一站式解决方案集成了CubeMX配置工具和IDE自动生成初始化代码非常方便。对于调试我更喜欢VS CodeCortex-Debug插件的组合编辑体验更佳再配合OpenOCD和ST-Link进行调试。信号处理算法仿真在将算法写成C代码嵌入MCU之前一定要在MATLAB或Python (NumPy/SciPy)里进行仿真。用录制的真实心电数据或标准数据库如MIT-BIH测试你的滤波器和QRS检测算法调整参数直到效果满意。这能节省大量在目标板上盲调的时间。版本控制即使是个人项目也强烈建议使用Git。硬件项目的原理图、PCB文件、源代码、文档都应该纳入版本管理。可以建立不同的分支来尝试不同的滤波方案或布局调整这比手动复制文件夹要清晰安全得多。最后把所有这些——原理图、PCB工程文件、Gerber生产文件、完整的C语言源代码、结构设计草图、元器件清单BOM、调试笔记——打包成一个清晰的“整机方案.zip”不仅是对项目的完美归档更是你技术能力最有力的证明。这个过程里每一个电阻电容的选型每一根走线的斟酌每一行代码的优化都是对“精度”和“可靠性”这两个工程师核心词汇的深刻实践。希望这份超详细的拆解能帮你少走些弯路更快地做出自己稳定可靠的心电采集设备。本文还有配套的精品资源点击获取