一. 簡介
MAX30102是一個集成的脈搏血氧儀和心率監(jiān)測儀生物傳感器的模塊(芯片)。 它集成了一個660nm紅光LED、880nm紅外光LED、光電檢測器、光器件,以及帶環(huán)境光抑制的低噪聲電子電路。 可通過軟件關(guān)斷模塊,待機電流為零,實現(xiàn)電源始終維持供電狀態(tài),可運用于低功耗產(chǎn)品中。
MAX30102采用一個1.8V電源和一個獨立的3.3V用于內(nèi)部LED的電源,標準的I2C兼容的通信接口。 市面很多都將MAX30102芯片集成在一個PCB模塊上,內(nèi)部增加一個1.8V和3.3V LDO穩(wěn)壓電路,可對模塊單獨供5.0V電源,方便開發(fā)者進行開發(fā)。
二. MAX30102原理及參數(shù)
1. 芯片內(nèi)部框圖
從框圖看,芯片可分為兩部分,一部分為模擬信號采集電路,通過RED和IR燈發(fā)出特定波長的光,采集人體反射回來的光,經(jīng)過PD管將光信號轉(zhuǎn)化為電信號,最終通過18bit ADC轉(zhuǎn)換器轉(zhuǎn)化為數(shù)字信號。
第二部分為數(shù)字處理電路,將ADC轉(zhuǎn)換出來的原始數(shù)據(jù)進行濾波處理后放置于緩沖區(qū)內(nèi); 單片機通過IIC接口讀寫芯片內(nèi)部寄存器,讀取出相應的數(shù)據(jù);
2. 模塊電路
芯片內(nèi)部有3.3V-5.0V的LED電源和1.8V的邏輯電源,所以模塊帶有兩路穩(wěn)壓電路,將5V電源分別轉(zhuǎn)化為3.3V和1.8V;由于LED驅(qū)動電源的供電范圍為3.3V-5.0V,3.3V穩(wěn)壓電路可省去。
由于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內(nèi)部集成了一整套完整信號采集電路,包括光信號發(fā)射及接收、AD轉(zhuǎn)換、環(huán)境光干擾消除及數(shù)字濾波部分,只將數(shù)字接口留給用戶。 用戶只需通過單片機的IIC接口(可用模擬IIC),對MAX30102內(nèi)部的寄存器進行讀寫操作,就可以得到轉(zhuǎn)換后的光強度數(shù)值。 最后需要通過相應的處理算法計算出心率值和血氧飽和度。
對于MAX30102的驅(qū)動程序,將其拆分出來,可分為標準IIC程序和MAX30102寄存器的讀寫操作,實現(xiàn)這兩部分的編程,便完成MAX30102的驅(qū)動; 由于IIC程序比較常用,這里就不例舉出來。 在完成IIC的通信程序后,實現(xiàn)以下程序;
(1)MAX30102寫寄存器函數(shù)
u8 max30102_Bus_Write(u8 Register_Address, u8 Word_Data)
{
/* 采用串行EEPROM隨即讀取指令序列,連續(xù)讀取若干字節(jié) */
/* 第1步:發(fā)起I2C總線啟動信號 */
i2c_Start();
/* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
i2c_SendByte(max30102_WR_address | I2C_WR);/* 此處是寫指令 */
/* 第3步:發(fā)送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第4步:發(fā)送字節(jié)地址 */
i2c_SendByte(Register_Address);
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第5步:開始寫入數(shù)據(jù) */
i2c_SendByte(Word_Data);
/* 第6步:發(fā)送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 發(fā)送I2C總線停止信號 */
i2c_Stop();
return 1;/* 執(zhí)行成功 */
cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
/* 發(fā)送I2C總線停止信號 */
i2c_Stop();
return 0;
}
(2)MAX30102讀寄存器函數(shù)
u8 max30102_Bus_Read(u8 Register_Address)
{
u8 data;
/* 第1步:發(fā)起I2C總線啟動信號 */
i2c_Start();
/* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
i2c_SendByte(max30102_WR_address | I2C_WR);/* 此處是寫指令 */
/* 第3步:發(fā)送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第4步:發(fā)送字節(jié)地址, */
i2c_SendByte((uint8_t)Register_Address);
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第6步:重新啟動I2C總線。下面開始讀取數(shù)據(jù) */
i2c_Start();
/* 第7步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
i2c_SendByte(max30102_WR_address | I2C_RD);/* 此處是讀指令 */
/* 第8步:發(fā)送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第9步:讀取數(shù)據(jù) */
{
data = i2c_ReadByte();/* 讀1個字節(jié) */
i2c_NAck();/* 最后1個字節(jié)讀完后,CPU產(chǎn)生NACK信號(驅(qū)動SDA = 1) */
}
/* 發(fā)送I2C總線停止信號 */
i2c_Stop();
return data;/* 執(zhí)行成功 返回data值 */
cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
/* 發(fā)送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步:發(fā)起I2C總線啟動信號 */
i2c_Start();
/* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
i2c_SendByte(max30102_WR_address | I2C_WR);/* 此處是寫指令 */
/* 第3步:發(fā)送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第4步:發(fā)送字節(jié)地址, */
i2c_SendByte((uint8_t)Register_Address);
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第6步:重新啟動I2C總線。下面開始讀取數(shù)據(jù) */
i2c_Start();
/* 第7步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
i2c_SendByte(max30102_WR_address | I2C_RD);/* 此處是讀指令 */
/* 第8步:發(fā)送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail;/* EEPROM器件無應答 */
}
/* 第9步:讀取數(shù)據(jù) */
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個字節(jié)讀完后,CPU產(chǎn)生NACK信號(驅(qū)動SDA = 1) */
else
i2c_Ack();
Word_Data[i][1] = (((u16)data1 << 8) | data2);
no--;
i++;
}
/* 發(fā)送I2C總線停止信號 */
i2c_Stop();
cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
/* 發(fā)送I2C總線停止信號 */
i2c_Stop();
}
(4)MAX30102初始化(可根據(jù)自己的實際情況更改相應的配置)
void max30102_init()
{
max30102_Bus_Write(0x09, 0x0b); //mode configuration : temp_en[3] MODE[2:0]=010 HR only enabled 011 SP02 enabled
max30102_Bus_Write(0x01, 0xF0); //open all of interrupt
max30102_Bus_Write(INTERRUPT_REG, 0x00); //all interrupt clear
max30102_Bus_Write(0x03, 0x02); //DIE_TEMP_RDY_EN
max30102_Bus_Write(0x21, 0x01); //SET TEMP_EN
max30102_Bus_Write(0x0a, 0x47); //SPO2_SR[4:2]=001 100 per second LED_PW[1:0]=11 16BITS
max30102_Bus_Write(0x0c, 0x47);
max30102_Bus_Write(0x0d, 0x47);
}
(5)數(shù)據(jù)采集
此程序只演示讀取出溫度,讀取血氧數(shù)據(jù)需要通過max30102_FIFO_Read函數(shù)讀出;
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);
}
}
-
傳感器
+關(guān)注
關(guān)注
2551文章
51097瀏覽量
753526 -
芯片
+關(guān)注
關(guān)注
455文章
50812瀏覽量
423574 -
模塊
+關(guān)注
關(guān)注
7文章
2706瀏覽量
47468 -
pcb
+關(guān)注
關(guān)注
4319文章
23099瀏覽量
397846 -
MAX30102
+關(guān)注
關(guān)注
4文章
13瀏覽量
2602
發(fā)布評論請先 登錄
相關(guān)推薦
評論