我正在使用 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);
}
最佳答案
将中断输出引脚(引脚 13 低电平有效)连接到 cpu 上的中断控制引脚。
设置你的CPU在设备指示某些事件准备就绪时被中断
然后,仍然在中断处理函数中,读取寄存器 0 并确定哪些数据已准备好。
引用数据表,大约第 14 页列出了所需通信事件的顺序。请注意,发布的代码不遵循指定的通信事件顺序
第 16 页,寄存器 7,指示如何初始化 SPO2 以实现所需的操作模式
关于c - 如何使用STM32F4从MAX30100读取FIFO数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58976747/