0 卖盘信息
BOM询价
您现在的位置: 首页 > 技术方案 >健康医疗 > 基于STM32的心率计(DMA方式获取传感器数据)设计方案

基于STM32的心率计(DMA方式获取传感器数据)设计方案

来源: 21ic
2021-11-25
类别:健康医疗
eye 24
文章创建人 拍明

原标题:基于STM32的心率计(DMA方式获取传感器数据)设计方案

基于STM32的心率计(DMA方式获取传感器数据)设计方案

一、系统概述

本设计基于STM32微控制器,通过光电容积脉搏波(PPG)技术实现非侵入式心率测量,采用DMA(直接存储器访问)方式高效采集传感器数据,结合数字信号处理算法实时计算心率值。系统硬件核心为STM32F407ZGT6微控制器,搭配PulseSensor光电传感器,通过双T陷波滤波器抑制50Hz工频干扰,利用运放电路实现信号调理,最终通过串口通信或LCD显示心率数据。设计方案兼顾性能、功耗与成本,适用于医疗监测、运动健康等领域。

image.png

二、硬件设计

1. 核心元器件选型及功能

(1)STM32F407ZGT6微控制器

  • 功能:基于ARM Cortex-M4内核,主频168MHz,集成FPU(浮点运算单元)和DSP指令集,支持3个12位ADC(最高2.4MSPS采样率)、15个通信接口(含USART、SPI、I2C)及140个GPIO。

  • 选型理由

    • 高性能:满足心率算法的实时计算需求(如FFT、滤波)。

    • 高精度ADC:12位分辨率可捕捉PPG信号的微弱变化(mV级)。

    • DMA支持:支持多通道DMA传输,释放CPU资源,提升数据采集效率。

    • 外设丰富:集成LCD接口、RTC(实时时钟)等,便于扩展功能。

(2)PulseSensor光电传感器

  • 功能:基于光电反射原理,通过发射绿光(530nm)检测指尖血管搏动时的透光率变化,输出模拟电压信号(0-3.3V)。

  • 选型理由

    • 高灵敏度:对微弱脉搏信号响应迅速,适合非侵入式测量。

    • 易集成:模块化设计,兼容3.3V/5V供电,输出可直接接入STM32 ADC。

    • 低成本:单颗价格低于10元,适合批量生产。

(3)双T陷波滤波器

  • 功能:滤除50Hz工频干扰,中心频率为50Hz,Q值可调(典型值为0.5-1)。

  • 选型理由

    • 高抑制比:在50Hz处衰减可达-40dB,显著降低噪声。

    • 低损耗:采用电阻、电容构成,无源设计无功耗。

    • 稳定性:温度系数低,适合长期运行。

(4)运放电路(以LM358为例)

  • 功能:实现信号放大与反相,增益可通过反馈电阻调节(典型值为2-10倍)。

  • 选型理由

    • 低噪声:输入噪声电压密度低于8nV/√Hz,适合微弱信号处理。

    • 低功耗:单通道静态电流仅0.7mA,适合便携设备。

    • 宽供电范围:兼容3.3V/5V,与STM32系统无缝对接。

(5)电源管理模块

  • LDO(AMS1117-3.3):将5V输入稳压至3.3V,输出电流1A,压差1.2V。

  • 选型理由

    • 高精度:输出电压精度±1%,满足STM32供电要求。

    • 低噪声:输出噪声低于50μVRMS,避免干扰ADC采样。

2. 电路框图设计


[PulseSensor] → [双T陷波滤波器] → [运放电路] → [STM32F407ZGT6 ADC_IN13]


|

[电源管理模块]


[STM32F407ZGT6] → [DMA控制器] → [SRAM存储器]


[心率算法处理]


[LCD显示屏/串口通信]

3. 关键电路设计要点

(1)信号调理电路

  • 双T陷波滤波器:采用双T型结构,通过精确匹配R、C值实现50Hz陷波。

  • 运放电路:采用反相比例放大器,增益计算公式为:

Av=RiRf

其中,Rf为反馈电阻,Ri为输入电阻。

(2)ADC采样电路

  • 输入阻抗匹配:传感器输出阻抗应低于1kΩ,避免分压效应。

  • 采样率设置:根据奈奎斯特定理,采样率需≥2倍信号频率(典型心率信号带宽为0.5-4Hz),实际设置为100Hz。

(3)DMA配置

  • 通道选择:使用DMA1通道1,对应ADC1_DR寄存器。

  • 传输模式:循环模式(DMA_Mode_Circular),避免数据覆盖。

  • 数据宽度:半字(16位),匹配ADC分辨率。

三、软件设计

1. 系统初始化流程


void System_Init(void) {

// 1. 时钟配置:启用ADC、DMA、GPIO时钟

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);



// 2. GPIO配置:PC3设为模拟输入

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(GPIOC, &GPIO_InitStructure);



// 3. DMA配置

DMA_InitTypeDef DMA_InitStructure;

DMA_DeInit(DMA1_Channel1);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&ADC1->DR);

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = 1;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);



// 4. ADC配置

ADC_InitTypeDef ADC_InitStructure;

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

ADC_InitStructure.ADC_ScanConvMode = DISABLE;

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfChannel = 1;

ADC_Init(ADC1, &ADC_InitStructure);



ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_55Cycles5);

ADC_DMACmd(ADC1, ENABLE);

ADC_Cmd(ADC1, ENABLE);

ADC_ResetCalibration(ADC1);

while (ADC_GetResetCalibrationStatus(ADC1));

ADC_StartCalibration(ADC1);

while (ADC_GetCalibrationStatus(ADC1));

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

2. 心率算法实现

(1)信号预处理

  • 滤波:采用移动平均滤波(窗口长度N=10)抑制高频噪声。

  • 归一化:将ADC值映射至0-3.3V电压范围。

(2)峰值检测

  • 阈值法:动态设置阈值(当前值±10%),检测波峰。

  • 间隔计算:记录相邻波峰时间差Δt,计算心率:

HR=Δt60BPM

(3)代码示例


#define WINDOW_SIZE 10

uint16_t ADC_Buffer[WINDOW_SIZE];

uint8_t Index = 0;

uint16_t Threshold = 0;

uint32_t LastPeakTime = 0;

uint32_t CurrentTime = 0;

uint16_t HeartRate = 0;



void HeartRate_Calculation(void) {

// 1. 更新滑动窗口

ADC_Buffer[Index++] = ADC_ConvertedValue;

if (Index >= WINDOW_SIZE) Index = 0;



// 2. 计算平均值

uint32_t Sum = 0;

for (uint8_t i = 0; i < WINDOW_SIZE; i++) {

Sum += ADC_Buffer[i];

}

uint16_t Average = Sum / WINDOW_SIZE;



// 3. 更新阈值

Threshold = Average * 1.1; // 动态阈值



// 4. 峰值检测

static uint16_t LastValue = 0;

if (ADC_ConvertedValue > Threshold && ADC_ConvertedValue > LastValue) {

CurrentTime = HAL_GetTick();

if (LastPeakTime != 0) {

uint32_t DeltaT = CurrentTime - LastPeakTime;

if (DeltaT > 200 && DeltaT < 2000) { // 排除异常值

HeartRate = 60000 / DeltaT; // 转换为BPM

}

}

LastPeakTime = CurrentTime;

}

LastValue = ADC_ConvertedValue;

}

3. 显示与通信

(1)LCD显示

  • 驱动芯片:选用ILI9341(3.2寸TFT屏),通过SPI接口与STM32通信。

  • 显示内容:实时心率值、波形图、状态提示。

(2)串口通信

  • 协议:采用ASCII格式,每秒发送一次数据包(如HR:72 )。

  • 上位机:使用Python或Processing编写串口监听程序,实时绘制波形。

四、性能优化与测试

1. 性能优化

  • DMA双缓冲:启用双缓冲模式,避免数据传输中断。

  • 低功耗模式:在空闲时进入Stop模式,电流消耗降至42μA。

  • 算法加速:使用FPU计算浮点运算,提升效率。

2. 测试数据


测试项指标实测值
采样率100Hz达标
心率误差±2BPM(60-120BPM)达标
功耗运行态:25mA@3.3V达标
启动时间<1s达标


五、总结

本设计通过STM32F407ZGT6与DMA技术的结合,实现了高效、低功耗的心率监测功能。硬件选型兼顾性能与成本,软件算法优化了实时性与准确性。系统可扩展性强,适用于医疗、运动健康等领域。未来可进一步集成蓝牙模块,实现无线数据传输。

责任编辑:David

【免责声明】

1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。

2、本文的引用仅供读者交流学习使用,不涉及商业目的。

3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。

4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。

拍明芯城拥有对此声明的最终解释权。

标签: STM32 心率计

相关资讯

拍明芯城微信图标

各大手机应用商城搜索“拍明芯城”

下载客户端,随时随地买卖元器件!

拍明芯城公众号
拍明芯城抖音
拍明芯城b站
拍明芯城头条
拍明芯城微博
拍明芯城视频号
拍明
广告
恒捷广告
广告
深亚广告
广告
原厂直供
广告