一.简介

MAX30102是一个集成的脉搏血氧仪和心率监测仪生物传感器的模块(芯片)。它集成了一个660nm红光LED、880nm红外光LED、光电检测器、光器件,以及带环境光抑制的低噪声电子电路。可通过软件关断模块,待机电流为零,实现电源始终维持供电状态,可运用于低功耗产品中。
MAX30102采用一个1.8V电源和一个独立的3.3V用于内部LED的电源,标准的I2C兼容的通信接口。市面很多都将MAX30102芯片集成在一个PCB模块上,内部增加一个1.8V和3.3V LDO稳压电路,可对模块单独供5.0V电源,方便开发者进行开发。

Max30102芯片及模块

二.MAX30102原理及参数

1.芯片内部框图

从框图看,芯片可分为两部分,一部分为模拟信号采集电路,通过RED和IR灯发出特定波长的光,采集人体反射回来的光,经过PD管将光信号转化为电信号,最终通过18bit ADC转换器转化为数字信号。
第二部分为数字处理电路,将ADC转换出来的原始数据进行滤波处理后放置于缓冲区内;单片机通过IIC接口读写芯片内部寄存器,读取出相应的数据;

2.模块电路


芯片内部有3.3V-5.0V的LED电源和1.8V的逻辑电源,所以模块带有两路稳压电路,将5V电源分别转化为3.3V和1.8V;由于LED驱动电源的供电范围为3.3V-5.0V,3.3V稳压电路可省去。
由于MAX30102的逻辑电路的IIC通信电平为1.8V,这与我们常用的51单片机和STM32单片机的引脚电平不匹配。
这里有个解决方法,因为MAX30102的SDA、SCL、INT引脚为开漏,

可以将模块上的R1、R2、R3电阻去掉,对于51单片机来说,在SDA、SCL、INT引脚上分别加一个4.7-10k电阻上拉至5V;对于STM32单片机,只需要将相应的控制引脚配置为上拉模式即可。

模块只需要接上5V电源,SDA、SCL、INT引脚与单片机连接即可;IRD、RD一般不接,以STM32单片机接线为例(单片机采用模拟IIC的控制方式),如图:

三.MAX30102编程

MAX30102内部集成了一整套完整信号采集电路,包括光信号发射及接收、AD转换、环境光干扰消除及数字滤波部分,只将数字接口留给用户。用户只需通过单片机的IIC接口(可用模拟IIC),对MAX30102内部的寄存器进行读写操作,就可以得到转换后的光强度数值。最后需要通过相应的处理算法计算出心率值和血氧饱和度。
对于MAX30102的驱动程序,将其拆分出来,可分为标准IIC程序和MAX30102寄存器的读写操作,实现这两部分的编程,便完成MAX30102的驱动;由于IIC程序比较常用,这里就不例举出来。在完成IIC的通信程序后,实现以下程序;

(1)MAX30102写寄存器函数

u8 max30102_Bus_Write(u8 Register_Address, u8 Word_Data)
{/* 采用串行EEPROM随即读取指令序列,连续读取若干字节 *//* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(max30102_WR_address | I2C_WR);   /* 此处是写指令 *//* 第3步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;   /* EEPROM器件无应答 */}/* 第4步:发送字节地址 */i2c_SendByte(Register_Address);if (i2c_WaitAck() != 0){goto cmd_fail; /* EEPROM器件无应答 */}/* 第5步:开始写入数据 */i2c_SendByte(Word_Data);/* 第6步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;  /* EEPROM器件无应答 */}/* 发送I2C总线停止信号 */i2c_Stop();return 1; /* 执行成功 */cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();return 0;
}

(2)MAX30102读寄存器函数

u8 max30102_Bus_Read(u8 Register_Address)
{u8  data;/* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(max30102_WR_address | I2C_WR);  /* 此处是写指令 *//* 第3步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;   /* EEPROM器件无应答 */}/* 第4步:发送字节地址, */i2c_SendByte((uint8_t)Register_Address);if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}/* 第6步:重新启动I2C总线。下面开始读取数据 */i2c_Start();/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(max30102_WR_address | I2C_RD);   /* 此处是读指令 *//* 第8步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;   /* EEPROM器件无应答 */}/* 第9步:读取数据 */{data = i2c_ReadByte(); /* 读1个字节 */i2c_NAck();  /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */}/* 发送I2C总线停止信号 */i2c_Stop();return data; /* 执行成功 返回data值 */cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();return 0;
}

(3)MAX30102读缓冲器FIFO

void max30102_FIFO_Read(u8 Register_Address,u16  Word_Data[][2],u8 count)
{u8 i=0;u8 no = count;u8 data1, data2;/* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(max30102_WR_address | I2C_WR);    /* 此处是写指令 *//* 第3步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;   /* EEPROM器件无应答 */}/* 第4步:发送字节地址, */i2c_SendByte((uint8_t)Register_Address);if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}/* 第6步:重新启动I2C总线。下面开始读取数据 */i2c_Start();/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(max30102_WR_address | I2C_RD);   /* 此处是读指令 *//* 第8步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;   /* EEPROM器件无应答 */}/* 第9步:读取数据 */while (no){data1 = i2c_ReadByte();  i2c_Ack();data2 = i2c_ReadByte();i2c_Ack();Word_Data[i][0] = (((u16)data1 << 8) | data2);  //data1 = i2c_ReadByte();   i2c_Ack();data2 = i2c_ReadByte();if(1==no)i2c_NAck();    /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */elsei2c_Ack();Word_Data[i][1] = (((u16)data1 << 8) | data2); no--; i++;}/* 发送I2C总线停止信号 */i2c_Stop();cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();
}

(4)MAX30102初始化(可根据自己的实际情况更改相应的配置)

void max30102_init()
{max30102_Bus_Write(0x09, 0x0b);  //mode configuration : temp_en[3]      MODE[2:0]=010 HR only enabled    011 SP02 enabledmax30102_Bus_Write(0x01, 0xF0); //open all of interruptmax30102_Bus_Write(INTERRUPT_REG, 0x00); //all interrupt clearmax30102_Bus_Write(0x03, 0x02); //DIE_TEMP_RDY_ENmax30102_Bus_Write(0x21, 0x01); //SET   TEMP_ENmax30102_Bus_Write(0x0a, 0x47); //SPO2_SR[4:2]=001  100 per second    LED_PW[1:0]=11  16BITSmax30102_Bus_Write(0x0c, 0x47); max30102_Bus_Write(0x0d, 0x47); }

(5)数据采集

此程序只演示读取出温度,读取血氧数据需要通过max30102_FIFO_Read函数读出;

int main(void)
{u8 temp_num=0;main_init();max30102_init();printf("\r\n MAX30102  init  \r\n");while(1){delay_ms(1000);            max30102_init();temp_num = max30102_Bus_Read(0x1f);printf("当前温度 = %d\r\n",temp_num);}}

如需MAX30102相关资料及完整例程, 请关注公众号,首页回复MAX30102获取资料

MAX30102血氧模块的原理及编程相关推荐

  1. MAX30102血氧模块检测心率和血氧

    1. 完成 CubeMX初始化配置 1.1 利用CubeMX完成HAL库工程模板和初始化: 通过选择芯片型号创建CubeMX工程 在弹出的对话框中输入开发板上的芯片型号,STM32F103RB 在右侧 ...

  2. 京微齐力:基于HMEP060的心率血氧模块开发(1:FPGA发送多位指令)

    目录 日常·唠嗑: 实验结果 一.硬件解析 1.国产FPGA:HMEP060 2.MAX30102心率传感器模块 二.程序设计 1.波特率计算(25MHz时钟) 2.顶层模块 3.子模块 三.工程获取 ...

  3. 基于STM32F030、MAX30102血氧心率监测仪的设计(二)

    上篇主要讲解了MAX30102寄存器相关知识,这篇主要看下程序配置. MAX30102寄存器配置 在一般的配置中我们让设备开机直接开始进入SpO2/HR 模式(PROX_INT_EN 置 0),设置两 ...

  4. MAX30100心率血氧模块

    文章目录 一.MAX30100是什么? **MAX30100参数** ***什么是光容积法?*** **(补充说明:)** 二.软件部分 一.MAX30100是什么? MAX30100是一款能测量心率 ...

  5. 智能手环监测血氧的工作原理

    智能手环所采用的血氧传感器芯片是反射式的,通过芯片将红光和红外光射向腕部,通过另一侧的光电二极管接收反射光线.通过发射与接收的光强差来计算出血氧度.生物方面的原理为:血液里的氧合血红蛋白对红光吸收量较 ...

  6. 基于STM32F030、MAX30102血氧心率监测仪的设计(三)

    本篇主要记录一下开发过程中遇到的问题与解决. max30102模块是某宝上购买的,价格不贵5元左右,如下图所示. 使用引脚为SDA.SCL.INT.VIN.GND 拿到模块后,看着资料开始移植程序,我 ...

  7. 基于STM32F030、MAX30102血氧心率监测仪的设计(一)

    搞这个设计用时大约一周,中途遇到好多问题,查找资料乱七八糟,始终没有解决问题,只能自己慢慢的啃资料,本文章主要记录设计过程及记录遇到的问题,做个记录同时帮助有需要的朋友. 目前该设计已成功读取计算出血 ...

  8. 基于STM32F030、MAX30102血氧心率监测仪的设计(四)

    这篇主要分享代码,不做过多介绍! #include "myiic.h"#define CPU_FREQUENCY_MHZ 48 // STM32时钟主频void iic_delay ...

  9. spo2数据集_Arduino 血氧心率模块传感器数据采集

    开发环境: Arduino-1.8.5-windows.exe.HXDZ-30102-ACC 硬件设备: MAX30102 MAX30102是一个集成的脉搏血氧仪和心率监测仪生物传感器的模块. 它集成 ...

  10. 实时监测心率血氧,血压,微循环,脉搏波,健康检测模块方案

    JFH142体表健康检测模块是惊帆科技研发的多光谱生理数据测量模块,用于人体体表的健康检测模块,可准确测量脉搏波形.心率值.血氧值和血管微循环 参数等信息.得益于获专利保护的前端传感器技术,模块灵敏度 ...

最新文章

  1. 200行代码解读TDEngine背后的定时器
  2. 【英语天天读】奥哈拉给女儿的信
  3. php使用aot,aot的常规使用
  4. 莫名其妙的SqlServer更新错误:OleDbException 必须声明标量变量
  5. C#日期控件(js版)
  6. golang dlv 远程调试
  7. dylib java_使用单声道可执行文件捆绑.dylib文件
  8. 工作中postgre使用过的函数。
  9. 这个技巧,让你更从容地使用Mac电脑~
  10. MatLAB从背景单一、物体相对简单且相互分离的图片中求其照片中物体的最小外接圆圆心、半径,并画出最小外接圆
  11. 创业 VS 阿里 | 当梦想遭遇现实,如何抉择?
  12. 图片验证码的实现方法
  13. taro更新页面数据_taroRefresh
  14. 听说支付宝有一个“疯起来连自己都打”的项目
  15. Android 在mac上显示手机屏幕 MAC 投影 安卓手机
  16. mysql neq什么意思_【知识科普】标准中的Eqv、Idt和Neq分别代表什么?
  17. Masking Layer的作用
  18. H.265编码视频播放器在播放FLV视频流时出现黑屏,如何解决?
  19. yum 无法安装gcc 出现Run “yum repolist all” to see the repos you have异常
  20. 通过 TokenType(){}.getType()获取Persionlt;Tgt; 泛型T的类型和数值

热门文章

  1. Nodejs 中文分词
  2. 华为交换机 查ip冲突_交换机如何解决IP地址冲突?
  3. IE tab for chrome
  4. Django序列化器
  5. 【高项】第4章 项目整体管理与变更管理【知识点精华笔记】
  6. 网狐cocos2d-lua棋牌二次开发搭建教程
  7. 公司章程应当载明什么内容
  8. VS自带数据库SqlExpress
  9. matlab绘制不同线性的直方图,Matlab绘制柱状图采用不同图案填充
  10. Vue动态加载并注册组件