如何使用STM32F4从MAX30100读取FIFO数据

时间:2019-11-21 14:02:12

标签: c fifo stm32f4

我正在使用MCU STM32F4通过MAX30100(https://img.filipeflop.com/files/download/Datasheet_MAX30100.pdf)监视心律。我正在尝试从FIFO读取IR和RED数据,但所有返回均为。方法MAX30100_Get_Num_Samples()返回 8 。我使用MAX30100数据手册中的伪代码对代码进行了建模。我针对自己的问题尝试了几种解决方案,但没有用。我不知道我是否遵循从FIFO获取数据的正确方法。我的代码:

I2C_HandleTypeDef hi2c3; //i2c used
uint16_t RED[50] = {0}, IR[50] = {0}; //buffers for RED and IR
uint8_t buffOximeter[5];
char buffer[32];

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C3_Init();
  MX_USB_DEVICE_Init();

  MAX30100_Init();

  while (1)
  {
    uint8_t numSamples = MAX30100_Get_Num_Samples();
    MAX30100_Read_HeartBeat(numSamples);

    for(int i = 0; i < numSamples; i++)
    {
        sprintf(buffer, "Amostra %d: %d / %d\n\r", i , IR[i], RED[i]);
        CDC_Transmit_FS((char*)buffer, 50);
    }
  }
}

static void MX_I2C3_Init(void)
{
  hi2c3.Instance = I2C3;
  hi2c3.Init.ClockSpeed = 400000;
  hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c3.Init.OwnAddress1 = 0;
  hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c3.Init.OwnAddress2 = 0;
  hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c3) != HAL_OK)
  {
    Error_Handler();
  }
}

void MAX30100_Init(void)
{
    HAL_I2C_Mem_Write(&hi2c3,0xAE,0x06,1,0x02,1,1000); //set heart rate mode
    HAL_I2C_Mem_Write(&hi2c3,0xAE,0x09,1,0xFF,1,1000); //i50 ledCurrent
    uint8_t sr = 0x01, pw = 0x3;
    HAL_I2C_Mem_Write(&hi2c3,0xAE,0x07,1,(sr<<2)|pw,1,1000); //sr100, pw1600
    HAL_Delay(50);
}

void MAX30100_Read_HeartBeat(uint8_t num)
{
    for(int i=0;i<num;i++)
    {
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0xAE,1,1000); //adress + write mode
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0x02,1,1000); //send fifo_wr_ptr
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0xAF,1,1000); //adress + read mode
        uint8_t data;
        HAL_I2C_Master_Receive(&hi2c3,0x57,&data,1,1000); //read fifo_wr_ptr
        HAL_Delay(100);                                   //STOP
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0xAE,1,1000); //adress + write mode
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0x05,1,1000); //send adress fifo data
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0xAF,1,1000); //adress + read mode
        HAL_I2C_Mem_Read(&hi2c3,0x57,0x05,1,&buffOximeter,4,1000); //read fifo data
        IR[i] = (buffOximeter[0] << 8) | buffOximeter[1];
        RED[i] = (buffOximeter[2] << 8) | buffOximeter[3];
        HAL_Delay(100);                                   //STOP
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0xAE,1,1000); //adress + write mode
        HAL_I2C_Master_Transmit(&hi2c3,0x57,0x04,1,1000); //send adress fifo_rd_ptr
        HAL_Delay(100);
    }
}

int MAX30100_Get_Num_Samples(void)
{
    uint8_t wrPtr, rdPtr;
    HAL_I2C_Mem_Read(&hi2c3,0x57,0x02,1,&wrPtr,1,1000);
    HAL_Delay(50);
    HAL_I2C_Mem_Read(&hi2c3,0x57,0x04,1,&rdPtr,1,1000);
    HAL_Delay(50);
    return (abs( 16 + wrPtr - rdPtr ) % 16);
}

1 个答案:

答案 0 :(得分:0)

将中断输出引脚(引脚13为低电平有效)连接到CPU上的中断控制引脚。

将设备设置为在设备指示某些事件就绪时将其中断

然后,仍在中断处理程序函数中,读取寄存器0并确定已准备好哪些数据。

参考的数据表,大约第14页列出了所需的通信事件的顺序。请注意,发布的代码未遵循指定的通信事件顺序

第16页的寄存器7指示如何为所需的操作模式初始化SPO2