0
点赞
收藏
分享

微信扫一扫

MAX30102心率模块初步认识

骨灰级搬砖工 2022-03-30 阅读 228
c语言

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

1.中断初始化
在这里插入图片描述
在这里插入图片描述

A_FULL_EN, PPG_RDY_EN set to 1.
一个是缓存满了的FLAG还有就是新数据准备好了的FLAG

MAX30102_Write_Byte(INTERRUPT_ENABLE2, 0x02); //TEMP RDY EN 0x02

MAX30102 FIFO 的深度为32,每个buf是6个字节(两通道数据,每通道3字节)。我么可以开启 PPG_RDY_EN,这样就能每来一个新的数据,就会中断一次通知我们去取数据。读FIFO_DATA 就会自动清掉中断标志位。
在这里插入图片描述
在这里插入图片描述

FIFO Write Pointer FIFO Write Pointer是指MAX30102写入下一个sample的位置。这个指针向前推进每个样品推到先进先出。当MODE[2:0]为010,011或111时,也可以通过I2C接口进行更改。

FIFO溢出计数器当FIFO满时,样品不推到FIFO,样品丢失。OVF_COUNTER统计丢失的样本数量。饱和到0xF。当一个完整的样本从FIFO弹出(即,删除旧的FIFO数据和移动样本)(当读取指针前进),OVF_COUNTER重置为零。

FIFO读指针FIFO读指针指向处理器通过I2C接口从FIFO获取下一个样本的位置。每次从FIFO中取出样品时,这一技术都会进步。处理器也可以在读取样本后写入这个指针,以便在出现数据通信错误时从FIFO重新读取样本。
在这里插入图片描述

圆形FIFO深度是32,可以容纳多达32个数据样本。样本大小取决于配置为活动的LED通道(又称通道)的数量。由于每个通道信号被存储为一个3字节的数据信号,FIFO宽度可以是3字节或6字节大小。I2C寄存器映射中的FIFO_DATA寄存器指向要从FIFO读取的下一个样本。FIFO_RD_PTR指向这个示例。读取FIFO_DATA寄存器,不会自动增加I2C寄存器地址。突然读取这个寄存器,一遍又一遍地读取同一个地址。每个样本每个通道有3个字节的数据(即RED有3个字节,IR有3个字节,等等)。FIFO寄存器(0x04 0x07)都可以被写入和读取,但实际上只有FIFO_RD_PTR寄存器应该被写入操作中。其他部分由MAX30102自动递增或填充数据。当开始一个新的SpO2或心率转换时,建议首先清除FIFO_WR_PTR, OVF_COUNTER和FIFO_RD_PTR寄存器到所有的零(0x00),以确保FIFO是空的,处于一个已知的状态。当在一个突发读I2C事务中读取MAX30102寄存器时,寄存器地址指针通常会增加,以便发送的下一个字节的数据来自下一个寄存器,等等。例外情况是FIFO数据寄存器,寄存器0x07。当读取这个寄存器时,地址指针不会增加,但是FIFO_RD_PTR会增加。所以发送的数据的下一个字节表示FIFO中可用的数据的下一个字节。进入和退出接近模式(当PROX_INT_EN = 1时)通过设置写指针和读指针相等来清除FIFO。
在这里插入图片描述

FIFO Write Pointer:好理解,就是写指针寄存器。保存下一个新数据在 FIFO 中的写地址。每次来一个数据,这个写指针会自动移动一位。
Over Flow Counter: 如果32个FIFO深度满了,就会在这里增加1,表示溢出。
FIFO Read Pointer:FIFO读指针,始终指向下一个待读取的FIFO地址。如果数据读取后,读地址也会自动增加。
FIFO Data Register: 可以简单的理解为 *FIFO_RD_PTR,始终指向下一个数据
通常,从I2C接口读取寄存器会自动增加寄存器地址指针,这样所有的寄存器都可以在没有I2C启动事件的情况下进行突发读取。在MAX30102中,除了FIFO_DATA寄存器(寄存器0x07)之外的所有寄存器都是如此。读取FIFO_DATA寄存器不会自动增加寄存器地址。突发读入这个寄存器从同一个地址反复读取数据。每个示例包含多个字节的数据,因此应该从这个寄存器(在同一个事务中)读取多个字节,以获得一个完整的示例。另一个例外是0xFF。在0xFF寄存器之后读取更多的字节不会将地址指针向前推进到0x00,因此数据读取是没有意义的。
FIFO数据结构FIFO数据由32个样本存储库组成,可以存储IR和Red ADC数据。由于每个采样由两个数据通道组成,因此每个采样有6个字节的数据,因此FIFO中可以存储192个字节的数据。FIFO数据左对齐如表1所示;换句话说,无论ADC的分辨率设置如何,MSB位始终处于第17位数据位置。表2给出了FIFO数据结构的可视化表示。
在这里插入图片描述

FIFO数据每个通道包含3个字节FIFO数据左对齐,这意味着无论ADC分辨率设置如何,MSB总是在相同的位置。FIFO DATA[18][23]未被使用。表2显示了每个三重字节的结构(包含每个通道的18位ADC数据输出)。SpO2模式下的每个数据样本包含两个数据三胞胎(每个3字节),要读取一个样本,每个字节需要一个I2C读命令。因此,在SpO2模式下读取一个样本需要6个I2C字节。FIFO读指针在每个样本的第一个字节被读取后自动递增。
写/读指针写/读指针用于控制FIFO中的数据流。每次FIFO中增加一个新样本时,写指针都会增加。每次从FIFO读取样本时,读指针都会增加。要从FIFO中重新读取样本,请将其值减1,然后再次读取数据寄存器。在进入SpO2模式或HR模式时,FIFO写/读指针应该被清除(回到0x00),这样就没有旧数据在FIFO中表示。如果VDD是电源循环或VDD低于其UVLO电压,指针将自动清除。

在这里插入图片描述

3.在这里插入图片描述
初始化
采样平均(SMP_AVE)为了减少数据吞吐量,可以通过设置这个寄存器在芯片上对相邻的采样(在每个单独的通道中)进行平均和抽取
在这里插入图片描述

设置为一,获取原始数据就行。
位4:FIFO滚满(FIFO_ROLLOVER_EN)这个位在FIFO完全被数据填满时控制FIFO的行为。如果设置了FIFO_ROLLOVER_EN(1),则FIFO地址滚到0,并继续填充新的数据。如果位没有设置(0),那么FIFO不会被更新,直到FIFO_DATA被读取或WRITE/ read指针位置被改变。
Bits 3:0: FIFO Almost Full Value (FIFO_A_FULL)这个寄存器设置了当中断发出时FIFO中剩余的数据样本的数量(3字节/样本)。例如,如果这个字段设置为0x0,当FIFO中有0个数据样本时(所有32个FIFO字都有未读数据),就会发出中断。此外,如果这个字段设置为0xF,则在FIFO中有15个数据样本(17个FIFO数据样本有未读数据)时发出中断。
在这里插入图片描述

4.在这里插入图片描述

第7位:关机控制(SHDN)将该位设置为1,可使部件进入省电模式。在省电模式下,所有寄存器都保留它们的值,并且读写操作正常运行。在这种模式下,所有中断都清除为零。
位6:Reset Control (Reset)当Reset位设置为1时,所有的配置、阈值和数据寄存器都通过上电复位复位到上电状态。复位顺序完成后,复位位将自动清零。注意:设置RESET位不会触发PWR_RDY中断事件。
这些位设置MAX30102的工作状态。改变模式不会改变任何其他设置,也不会删除数据寄存器中先前存储的任何数据。
SpO2 mode Red and IR
在这里插入图片描述

5.在这里插入图片描述

位6:5:SpO2 ADC范围控制该寄存器设置SpO2传感器ADC的全量程范围,如表5所示
在这里插入图片描述

频率精度设置

6.复位
在一般的配置中我们让设备开机直接开始进入SpO2/HR 模式就好(PROX_INT_EN 置 0),设置两个LED的电流都为0x40,然后开启 RDY 中断使能。这样每次数据采集ok就可以中断一次去处理数据。
位6:Reset Control (Reset)当Reset位设置为1时,所有的配置、阈值和数据寄存器都通过上电复位复位到上电状态。复位顺序完成后,复位位将自动清零。注意:设置RESET位不会触发PWR_RDY中断事件。

7.在这里插入图片描述

8.读写时序
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

9.接收两组数据写入
在这里插入图片描述

此时FIFO已经有数据
读取中断状态寄存器,来清除中断
在这里插入图片描述

当一个中断被触发时,MAX30102将active-low中断引脚拉到它的低状态,直到中断被清除。
A_FULL: FIFO Almost Full Flag在SpO2和HR模式下,当FIFO写指针有一定数量的空闲空间时,这个中断触发。触发数可以通过FIFO_A_FULL[3:0]寄存器设置。通过读取中断状态1寄存器(0x00),中断被清除。
ALC_OVF: Ambient Light Cancellation Overflow当SpO2/HR光电二极管的环境光抵消功能达到其最大限制时,该中断触发,因此,环境光影响ADC的输出。通过读取interrupt Status 1寄存器(0x00)来清除中断。
PPG_RDY: New FIFO Data Ready在SpO2和HR模式下,当数据FIFO中有一个新的样本时,这个中断触发。通过读取中断状态1寄存器(0x00)或读取FIFO_DATA寄存器可以清除中断。
PROX_INT: Proximity Threshold Triggered当接近阈值达到,SpO2/HR模式开始时,触发接近中断。这让主机处理器知道要开始运行SpO2/HR算法并收集数据。通过读取中断状态1寄存器(0x00),中断被清除。
当电源电压VDD从低于欠压锁定(UVLO)电压过渡到高于UVLO电压时,电源就绪中断被触发,信号表明模块已上电并准备收集数据。
当一个内部模具温度转换完成时,这个中断被触发,处理器可以读取温度数据寄存器。通过读取中断状态2寄存器(0x01)或TFRAC寄存器(0x20)来清除中断。
当读取中断状态寄存器时,或者当读取触发中断的寄存器时,中断将被清除。例如,如果SpO2传感器触发了一个中断,由于完成转换,读取FIFO数据寄存器或中断寄存器清除中断引脚(返回到其正常的HIGH状态)。这也将把中断状态寄存器中的所有位清除为零
在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

最大从FIFO寄存器读取6次
在这里插入图片描述

清除标志
在这里插入图片描述
在这里插入图片描述
读到数据

I2C寄存器映射中的FIFO_DATA寄存器指向要从FIFO读取的下一个样本。 FIFO_RD_PTR指向此样本。所以虽然通过连续读 FIFO_DATA 不会使该寄存器自增,但是 FIFO_DATA 寄存器实际是映射到FIFO_RD_PTR,而FIFO_RD_PTR 寄存器始终指向下一个待读取的数据,所以对FIFO_DATA 连续读,是能够实现的。读 FIFO 函数如下:
/*****************************************************************************************

  • Function Name: MAX30102_Read_FIFO_Data

  • Description : 通过硬件I2C,读取FIFO中的数据RED, IR.

  • Arguments : *data:两路电流值大小

  • Return Value : none
    ******************************************************************************************/
    void MAX30102_Read_FIFO_Data(uint32_t *data)
    {
    uint8_t tmp[6];

    MAX30102_Read_Len(FIFO_DATA, tmp, 6);
    data[0] = ((tmp[0]<<16 | tmp[1]<<8 | tmp[2]) & 0x03ffff);
    data[1] = ((tmp[3]<<16 | tmp[4]<<8 | tmp[5]) & 0x03ffff);

    //am_util_stdio_printf("%d, %d\n", data[0], data[1]);
    }
    在这里插入图片描述

读出红光数据最大采集3字节数据

在这里插入图片描述
在这里插入图片描述

等待,直到中断引脚断言,检测数据当有数据时为低电平,跳出循环。
在这里插入图片描述
在这里插入图片描述

低电平有效中断(校验)。用上拉电阻连接外部电压。

一个样本的数据(红光和红外数据)
在这里插入图片描述
在这里插入图片描述

Longlonglong可能是防止溢出
接着算法处理前500个样本(前5秒)计算心率和血氧饱和度

在这里插入图片描述

//将前100组样本转储到内存中,并将后400组样本移到内存顶部
在这里插入图片描述

在计算心率前,取100组样本。

在这里插入图片描述

最后通过UART将计算结果和样本输出到终端程序中
在这里插入图片描述

sprintf指的是字符串格式化命令,函数声明为 int sprintf(char *string, char *format [,argument,…]);,主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。
int sprintf(char *string, char *format [,argument,…]);
参数
string-- 这是指向一个字符数组的指针,该数组存储了 C 字符串。
format-- 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是%[flags][width][.precision][length]specifier
[argument]…:根据不同的 format 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 format 参数中指定的每个 % 标签。参数的个数应与 % 标签的个数相同。
在这里插入图片描述

举报

相关推荐

0 条评论