电子工坊

MAX30100血氧心率模块(三)寄存器 – FIFO

MAX30100使用先进先出队列FIFO(First Input First Output),FIFO都在通常使用的电子用于缓冲电路和流动硬件和软件之间的控制。该器件使用异步FIFO,异步FIFO的好处就是在不同时钟速率的数据传输下能保证数据的正确传输。MAX30100的FIFO_DATA是可容纳16位SpO2样本数据的储存器,每位储存4个字节(IR高低位和RED高低位)。

MAX30100的FIFO有四个寄存器,分别是FIFO读写指针、FIFO移除寄存器、FIFO数据。

FIFO Write Pointer (FIFO写入指针):FIFO写入指针指向MAX30100写入下一个采样的位置,每采样一个样本该指针推进一位,当MODE [2:0]非0的时候可以通过I2C进行更改。

FIFO Overflow Counter (FIFO溢出寄存器):当FIFO数据满了,后面采样的数据不会被推送上FIFO,所以造成数据丢失OVF_COUNTER是计数丢失的样本。 当一个完整的样本从FIFO读取(读指针推进)时FIFO溢出寄存器复位到零。

FIFO Read Pointer (FIFO读取指针):读指针指向FIFO数据的位置,每次读取数据后指针指向下个位置,如果存在数据通信错误,则可以通过写入读指针来重新读取上次的数据。

FIFO Data(FIFO数据):环形FIFO数据最大能容纳16个样本通道的SpO2数据(IR和RED)。通过FIFO_RD_PTR指向该样品。读取一组数据后I2C寄存器映射中的FIFO_DATA寄存器指向要从FIFO读取的下一个样本。

上述寄存器都可以被写入和读取,但实际上只有FIFO_RD_PTR寄存器在重新读取写入才用到,其他的寄存器则由MAX30100自动递增填充数据。

MAX30100 寄存器三 —— FIFO数据结构

数据FIFO由一个16采样存储器组成,每个储存器储存IR和RED的ADC数据。由于每个样本由一个IR字和一个RED字组成,因此每个样本有4个字节的数据,因此可以在FIFO中存储64个总字节的数据。要读取一个样本需要连续读取4个字节以读取一个样本。 读取每个4字节的样本后,FIFO读指针自动递增。

FIFO数据左对齐,无论ADC的分辨率是多少位,最高有效字节(MSB)始终在最高(15)位。

在心率模式下每个样本的第3和4个字节返回是0,但是FIFO的数据结构不变。

MAX30100 寄存器三 —— Write/Read Pointers:读写指针

用于存储新数据和用于读取数据的读写指针用于控制FIFO中的数据流。
每当新样本添加到FIFO时,写指针会自动递增。每当从FIFO读取样本的时候,读指针会自动递增。要重新读取上一个样本则将读指针减一并且再次读取数据寄存器。
如果进入了SpO2或者HR模式时,写入和读取指针都应该被清除(置零),防止旧数据产生的问题。改变模式并不会自动清零,只有在VDD重新上电或者电压低于UVLO则会被清除。

读取FIFO的读写指针计算数据数量:
START
发送 设备地址 +  读模式;
读取  FIFO_WR_PTR , FIFO_RD_PTR;
计算读取数量 NUM_SAMPLES_TO_READ = FIFO_WR_PTR - FIFO_RD_PTR;(注意指针环绕)
STOP

如果样本数据错误则更新FIFO_RD_PTR,以便重新读取数据。

重新读取数据:
START
发送 设备地址 + 写模式;
发送  FIFO_RD_PTR 地址;
写入  FIFO_RD_PTR 数据;
STOP

MAX30100 寄存器三 —— FIFO读取

通常情况下,从I2C接口读取寄存器会自动递增寄存器地址指针,使得所有的寄存器可以在不重启I2C事件下突发连续读取多个寄存器。但是在MAX30100中除了FIFO_DATA寄存器(0x05)不能连续读取,读FIFO_DATA寄存器不会自动递增寄存器地址,突发读一遍又一遍也是同个地址,其他寄存器可突发连续读取。但是如果连续读取到0XFF寄存器后还在连续读取的话会读取到没有意义的数据,所以连续读取到0xff寄存器后将指针设置回0x00。

FIFO_DATA的数据读取必须要连续读取四次才能获得其样本,先读取出的数据是IR数据的高位然后到低位,然后是RED的高位到低位总共四个数据。
刚刚我们拿到了要读取数据的长度,现在开始读取FIFO的数据吧。

FIFO数据的读取,先设定好FIFO_DATA地址:

START
发送 设备地址 +  写模式;
发送 FIFO_DATA地址;
重新开始I2C
发送 设备地址 + 读模式;
for(i = 0; i < NUM_SAMPLES_TO_READ; i++)
{
读取 FIFO_DATA;
保存IR高位 IR[15:8];
读取 FIFO_DATA;
保存IR低位 IR[7:0];
读取 FIFO_DATA;
保存RED高位 IR[15:8];
读取 FIFO_DATA;
保存RED低位 IR[7:0];
}
停止STOP