一. 簡介
MAX30102是一個集成的脈搏血氧儀和心率監測儀生物傳感器的模塊(芯片)。 它集成了一個660nm紅光LED、880nm紅外光LED、光電檢測器、光器件,以及帶環境光抑制的低噪聲電子電路。 可通過軟件關斷模塊,待機電流為零,實現電源始終維持供電狀態,可運用于低功耗產品中。
MAX30102采用一個1.8V電源和一個獨立的3.3V用于內部LED的電源,標準的I2C兼容的通信接口。 市面很多都將MAX30102芯片集成在一個PCB模塊上,內部增加一個1.8V和3.3V LDO穩壓電路,可對模塊單獨供5.0V電源,方便開發者進行開發。
二. 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) */
else
i2c_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 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)數據采集
此程序只演示讀取出溫度,讀取血氧數據需要通過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);
}
}
-
傳感器
+關注
關注
2550文章
51035瀏覽量
753068 -
芯片
+關注
關注
455文章
50714瀏覽量
423137 -
模塊
+關注
關注
7文章
2695瀏覽量
47431 -
pcb
+關注
關注
4319文章
23080瀏覽量
397494 -
MAX30102
+關注
關注
4文章
13瀏覽量
2599
發布評論請先 登錄
相關推薦
評論