一、电路设计
此电路有STM32最小系统板、TFT液晶屏、MAX30102传感器和蜂鸣器电路组成。
硬件资料
MAX30102是一个集成的脉搏血氧仪和心率监测模块。它包括内部发光二极管,光电探测器,光学元件,以及低噪音的电子设备。MAX30102提供了一个完整的系统解决方案来简化移动和可穿戴设备的设计过程。
MAX30102运行在一个1.8V电源和一个单独的5.0V电源的内部发光二极管。通信是通过一个标准的i2c兼容接口。该模块可以通过零备用电流的软件关闭,使电力轨道始终保持供电。
二、运行效果图
三、部分代码
/*--Include-start-------------------------------------------------------------*/
#include "MAX30100.h"
#include "IICcom.h"
/*define ---------------------------------------------------------------------*/
#define max30100_WR_address 0xAE
#define I2C_WR 0 /* д¿ØÖÆbit */
#define I2C_RD 1 /* ¶Á¿ØÖÆbit */
/*Global data space ----------------------------------------------------------*/
uint8_t max30100_Bus_Write(uint8_t Register_Address, uint8_t Word_Data)
{
/* ²ÉÓô®ÐÐEEPROMËæ¼´¶ÁÈ¡Ö¸ÁîÐòÁУ¬Á¬Ðø¶ÁÈ¡Èô¸É×Ö½Ú */
/* µÚ1²½£º·¢ÆðI2C×ÜÏßÆô¶¯ÐźŠ*/
I2C_Start();
/* µÚ2²½£º·¢Æð¿ØÖÆ×Ö½Ú£¬¸ß7bitÊǵØÖ·£¬bit0ÊǶÁд¿ØÖÆ룬0±íʾд£¬1±íʾ¶Á */
I2C_SendByte(max30100_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;
}
uint8_t max30100_Bus_Read(uint8_t Register_Address)
{
uint8_t data;
/* µÚ1²½£º·¢ÆðI2C×ÜÏßÆô¶¯ÐźŠ*/
I2C_Start();
/* µÚ2²½£º·¢Æð¿ØÖÆ×Ö½Ú£¬¸ß7bitÊǵØÖ·£¬bit0ÊǶÁд¿ØÖÆ룬0±íʾд£¬1±íʾ¶Á */
I2C_SendByte(max30100_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(max30100_WR_address | I2C_RD); /* ´Ë´¦ÊǶÁÖ¸Áî */
/* µÚ8²½£º·¢ËÍACK */
if (I2C_WaitAck() != 0)
{
goto cmd_fail; /* EEPROMÆ÷¼þÎÞÓ¦´ð */
}
/* µÚ9²½£º¶ÁÈ¡Êý¾Ý */
{
data = I2C_RadeByte(); /* ¶Á1¸ö×Ö½Ú */
I2C_NoAck(); /* ×îºó1¸ö×Ö½Ú¶ÁÍêºó£¬CPU²úÉúNACKÐźÅ(Çý¶¯SDA = 1) */
}
/* ·¢ËÍI2C×ÜÏßÍ£Ö¹ÐźŠ*/
I2C_Stop();
return data; /* Ö´Ðгɹ¦ ·µ»ØdataÖµ */
cmd_fail: /* ÃüÁîÖ´ÐÐʧ°Üºó£¬ÇмǷ¢ËÍÍ£Ö¹Ðźţ¬±ÜÃâÓ°ÏìI2C×ÜÏßÉÏÆäËûÉ豸 */
/* ·¢ËÍI2C×ÜÏßÍ£Ö¹ÐźŠ*/
I2C_Stop();
return 0;
}
void max30100_FIFO_Read(uint8_t Register_Address,uint16_t Word_Data[][2],uint8_t count)
{
uint8_t i=0;
uint8_t no = count;
uint8_t data1, data2;
/* µÚ1²½£º·¢ÆðI2C×ÜÏßÆô¶¯ÐźŠ*/
I2C_Start();
/* µÚ2²½£º·¢Æð¿ØÖÆ×Ö½Ú£¬¸ß7bitÊǵØÖ·£¬bit0ÊǶÁд¿ØÖÆ룬0±íʾд£¬1±íʾ¶Á */
I2C_SendByte(max30100_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(max30100_WR_address | I2C_RD); /* ´Ë´¦ÊǶÁÖ¸Áî */
/* µÚ8²½£º·¢ËÍACK */
if (I2C_WaitAck() != 0)
{
goto cmd_fail; /* EEPROMÆ÷¼þÎÞÓ¦´ð */
}
/* µÚ9²½£º¶ÁÈ¡Êý¾Ý */
while (no)
{
data1 = I2C_RadeByte();
I2C_Ack();
data2 = I2C_RadeByte();
I2C_Ack();
Word_Data[i][0] = (((uint16_t)data1 << 8) | data2); //
data1 = I2C_RadeByte();
I2C_Ack();
data2 = I2C_RadeByte();
if(1==no)
I2C_NoAck(); /* ×îºó1¸ö×Ö½Ú¶ÁÍêºó£¬CPU²úÉúNACKÐźÅ(Çý¶¯SDA = 1) */
else
I2C_Ack();
Word_Data[i][1] = (((uint16_t)data1 << 8) | data2);
no--;
i++;
}
/* ·¢ËÍI2C×ÜÏßÍ£Ö¹ÐźŠ*/
I2C_Stop();
cmd_fail: /* ÃüÁîÖ´ÐÐʧ°Üºó£¬ÇмǷ¢ËÍÍ£Ö¹Ðźţ¬±ÜÃâÓ°ÏìI2C×ÜÏßÉÏÆäËûÉ豸 */
/* ·¢ËÍI2C×ÜÏßÍ£Ö¹ÐźŠ*/
I2C_Stop();
}
void max30100_init(void)
{
max30100_Bus_Write(0x06, 0x0b); //mode configuration : temp_en[3] MODE[2:0]=010 HR only enabled 011 SP02 enabled
//max30100_Bus_Write(0x06, 0x0a); //MODE[2:0]=010 HR only enabled when used is mode ,the red led is not used.
max30100_Bus_Write(0x01, 0xF0); //open all of interrupt
max30100_Bus_Write(INTERRUPT_REG, 0x00); //all interrupt clear
max30100_Bus_Write(0x09, 0x33); //r_pa=3,ir_pa=3
#if (SAMPLES_PER_SECOND == 50)
max30100_Bus_Write(0x07, 0x43); //SPO2_SR[4:2]=000 50 per second LED_PW[1:0]=11 16BITS
#elif (SAMPLES_PER_SECOND == 100)
max30100_Bus_Write(0x07, 0x47); //SPO2_SR[4:2]=001 100 per second LED_PW[1:0]=11 16BITS
#elif (SAMPLES_PER_SECOND == 200)
max30100_Bus_Write(0x07, 0x4F);
#elif (SAMPLES_PER_SECOND == 400)
max30100_Bus_Write(0x07, 0x53);
#endif
max30100_Bus_Write(0x02, 0x00); //set FIFO write Pointer reg = 0x00 for clear it
max30100_Bus_Write(0x03, 0x00); //set Over Flow Counter reg = 0x00 for clear it
max30100_Bus_Write(0x04, 0x0F); //set FIFO Read Pointer reg = 0x0f for
//waitting write pointer eq read pointer to interrupts INTERRUPT_REG_A_FULL
}