基于stm32及Max30102的心率血氧检测cubemx生成

本文介绍了基于STM32开发心率血氧监测小型设备的过程。硬件采用stm32f103c8t6、MAX30102和0.96寸OLED,软件使用keil5。详细说明了cubemx配置工程文件、MAX30102驱动、硬件I2c驱动OLED等步骤,还给出了算法代码及获取方式。

一、前言

        Max30102是一款集成了红外发光二极管、光电检测器、信号处理和数据输出功能于一体的脉搏血氧测量模块。它能够通过皮肤进行非侵入式的心率和血氧饱和度监测,常被用于可穿戴设备或医疗设备中。Max30102具有高精度、低功耗和小尺寸的特点,广泛应用于健康监测领域。于是准备做个监测心率血氧的小型设备。

二、准备

硬件:stm32f103c8t6,MAX30102,0.96寸OLED

软件:keil5

三、cubemx配置工程文件

        配置SYS,RCC,时钟数,I2C1(用于OLED),I2C2(用于MAX30102),GPIO

        PA7配置为INT引脚,输入模式,配上拉电阻(INT默认高电平,低电平有效)

        I2C1和I2C2都配置为高速I2C(只为了更快)

        生成工程文件

        生成并进入工程文件

四、MAX30102驱动

4.1 读取FIFO函数

//写Data到max30102中
HAL_StatusTypeDef Max30102_WriteData(uint8_t MemAddress,uint8_t Command,uint16_t SendCount)
{
	HAL_StatusTypeDef status=HAL_OK;
	status=HAL_I2C_Mem_Write(&hi2c2,Max30102_Write_Address,MemAddress,I2C_MEMADD_SIZE_8BIT,&Command,SendCount,100);
	return status;
}

//I2C读取函数
HAL_StatusTypeDef Max30102_ReadData(uint8_t DatAddress,uint8_t *Data,uint16_t ReceiveCount)
{
	HAL_StatusTypeDef status=HAL_OK;
	status=HAL_I2C_Mem_Read(&hi2c2,Max30102_Read_Address,DatAddress,I2C_MEMADD_SIZE_8BIT,Data,ReceiveCount,100);
	return status;
}

void Max30102_FIFO_ReadData(uint8_t DatAddress,uint8_t SixData[6],uint16_t Size)
{
	uint8_t temp;
	Max30102_ReadData(REG_INTR_STATUS_1,&temp,1);
	Max30102_ReadData(REG_INTR_STATUS_2,&temp,1);
	Max30102_ReadData(DatAddress,SixData,Size);
}

 4.2 MAX30102初始化

void Max30102_Reset(void)
{
	Max30102_WriteData(REG_MODE_CONFIG,0x40,1);
	Max30102_WriteData(REG_MODE_CONFIG,0x40,1);
}

void Max30102_Init(void)
{
	Max30102_Reset();
	
	Max30102_WriteData(REG_INTR_ENABLE_1,0xc0,1);	// INTR setting
	Max30102_WriteData(REG_INTR_ENABLE_2,0x00,1);
	Max30102_WriteData(REG_FIFO_WR_PTR,0x00,1);  	//FIFO_WR_PTR[4:0]
	Max30102_WriteData(REG_OVF_COUNTER,0x00,1);  	//OVF_COUNTER[4:0]
	Max30102_WriteData(REG_FIFO_RD_PTR,0x00,1);  	//FIFO_RD_PTR[4:0]
	Max30102_WriteData(REG_FIFO_CONFIG,0x0f,1);  	//sample avg = 1, fifo rollover=false, fifo almost full = 17
	Max30102_WriteData(REG_MODE_CONFIG,0x03,1);  	//0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
	Max30102_WriteData(REG_SPO2_CONFIG,0x27,1);  	// SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)  
	Max30102_WriteData(REG_LED1_PA,0x24,1);   	//Choose value for ~ 7mA for LED1
	Max30102_WriteData(REG_LED2_PA,0x24,1);   	// Choose value for ~ 7mA for LED2
	Max30102_WriteData(REG_PILOT_PA,0x7f,1);   	// Choose value for ~ 25mA for Pilot LED
}

        先连接好线,把初始化程序烧进去,如果MAX30102红灯亮则没问题可以继续下一步,如果红灯不亮,大概率是I2C没通,仔细检查是不是线没接好!

MAX30102接线:

 SCL-----PB10     SDA-----PB11     INT-----PA7

OLED接线:

SCL-----PB6       SDA-----PB7

4.3 MAX30102算法实现心率血氧检测

        在写MAX30102程序前先把下面的algorithm文件放入工程文件中并在Keil5中添加文件路径,这是一个针对于心率血氧的算法,把前辈研究好的东西拿来用也是不错的!algorithm文件中的.c和.h文件代码的代码我放在最下面。也可以直接下载我上传的文件解压即可。

链接:https://pan.baidu.com/s/1-GGcoyf4qizAIo3MfZ7qug 
提取码:ae86

        MAX30102心率血氧读取代码(代码以注释明确)

4.3.1 各种变量的声明

uint8_t TempData[6];
uint32_t red_buffer[500];  //红光数据red,用于计算心率
uint32_t ir_buffer[500];  //红外数据 ir,用于计算血氧
int32_t ir_buffer_length=500;   //计算前500个样本得到的数据
int32_t pn_SpO2_value;   //血氧实际值
int8_t SpO2_valid;        //血氧值有效标志
int32_t pn_hr_value;    //心率实际值
int8_t hr_valid;         //心率有效标志
uint32_t red_max=0,red_min=0x3FFFF;  //红光取值范围
uint32_t prev_data;      //前一次的值
float f_temp;           //临时变量
int32_t n_brightness;    //明确变量 

 4.3.2 MAX30102数据初始化函数

void Max30102_Safety(void)
{
	for(int i=0;i<ir_buffer_length;i++)
	{
		while(Max30102_INT==GPIO_PIN_SET); //等待中断引脚相应,默认为高,当触发后会拉低
		Max30102_FIFO_ReadData(REG_FIFO_DATA,TempData,6);
		red_buffer[i]=((TempData[0]&0x03)<<16) | (TempData[1]<<8) | (TempData[2]); //前三位数据组成HR
		ir_buffer[i]=((TempData[3]&0x03)<<16) | (TempData[4]<<8) | (TempData[5]); //后三位数据组成BO
		if(red_min>red_buffer[i]) red_min=red_buffer[i];  //更新当前最小值
		if(red_max<red_buffer[i]) red_max=red_buffer[i];  //更新当前最大值
	}
	maxim_heart_rate_and_oxygen_saturation(ir_buffer,ir_buffer_length,red_buffer,&pn_SpO2_value,&SpO2_valid,&pn_hr_value,&hr_valid);
	//传入500个采样,通过算法得出实际心率血氧值
}

 4.3.3 心率血氧计算函数

void Max30102_Calculate_HR_BO_Value(int32_t* HR_Value,int8_t* HR_Valid,int32_t* BO_Value,int8_t* BO_Valid)
{
	for(int i=100;i<500;i++)  //将数组中的100~500采样值向前挪到0~400
	{
		red_buffer[i-100]=red_buffer[i];
		ir_buffer[i-100]=ir_buffer[i];
		if(red_min>red_buffer[i]) red_min=red_buffer[i];  //更新当前最小值
		if(red_max<red_buffer[i]) red_max=red_buffer[i];  //更新当前最大值
	}
	for(int i=400;i<500;i++)  //实际只取100个采样值来计算
	{
		prev_data=red_buffer[i-1]
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫色小薇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值