stm32f103c8t6使用max30102并测出血氧和心率,用标准库实现代码展示
时间: 2023-09-03 14:09:55 浏览: 130
MAX30102是一款集成了红外和可见光光学传感器的心率传感器模块,可以用来测量血氧和心率。下面是使用STM32F103C8T6和MAX30102测量血氧和心率并输出结果的标准库实现代码示例:
```
#include "stm32f10x.h"
#include "i2c.h"
#include "stdio.h"
#define MAX30102_ADDR 0xAE
#define IR_LED_PA4 GPIO_Pin_4
void MAX30102_Init(void)
{
I2C_Start();
I2C_SendByte(MAX30102_ADDR << 1);
I2C_SendByte(0x06); // 指向配置寄存器1
I2C_SendByte(0x7F); // 使能红外和可见光传感器
I2C_Stop();
}
void MAX30102_Read(uint8_t reg, uint8_t *buf, uint8_t len)
{
I2C_Start();
I2C_SendByte(MAX30102_ADDR << 1);
I2C_SendByte(reg);
I2C_Start();
I2C_SendByte(MAX30102_ADDR << 1 | 1);
for (int i = 0; i < len; i++)
{
buf[i] = I2C_ReadByte();
if (i == len - 1)
{
I2C_SendACK(0);
}
else
{
I2C_SendACK(1);
}
}
I2C_Stop();
}
void MAX30102_Write(uint8_t reg, uint8_t data)
{
I2C_Start();
I2C_SendByte(MAX30102_ADDR << 1);
I2C_SendByte(reg);
I2C_SendByte(data);
I2C_Stop();
}
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = IR_LED_PA4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
int main(void)
{
I2C_Init();
MAX30102_Init();
GPIO_Init();
uint32_t irValue;
uint32_t redValue;
uint32_t lastBeatTime = 0;
uint32_t sampleCounter = 0;
uint32_t lastFifoOverflow = 0;
float beatsPerMinute;
int beatDetected = 0;
uint32_t beatAvg = 0;
uint32_t spO2Value = 0;
while (1)
{
uint8_t buf[6];
MAX30102_Read(0x00, buf, 6); // 读取FIFO数据
irValue = (buf[0] << 16) | (buf[1] << 8) | buf[2];
redValue = (buf[3] << 16) | (buf[4] << 8) | buf[5];
// 计算心率
if (irValue > 50000)
{
if (beatDetected == 0)
{
beatDetected = 1;
uint32_t delta = sampleCounter - lastBeatTime;
lastBeatTime = sampleCounter;
if (delta > 250 && delta < 2000)
{
beatsPerMinute = 60.0 / delta * 1000;
beatAvg = (beatAvg * 3 + beatsPerMinute) / 4;
}
}
}
else
{
beatDetected = 0;
}
// 计算血氧
uint32_t average = (irValue + redValue) / 2;
if (average < 50000)
{
spO2Value = 0;
}
else if (average > 100000)
{
spO2Value = 100;
}
else
{
spO2Value = (-45.060 * 100.0 + 30.354 * (float)average / (float)redValue * 100.0) / 10.0;
}
// 控制红外LED亮度,避免光干扰
if (sampleCounter % 100 == 0)
{
GPIO_SetBits(GPIOA, IR_LED_PA4);
}
else if (sampleCounter % 100 == 50)
{
GPIO_ResetBits(GPIOA, IR_LED_PA4);
}
sampleCounter++;
// 输出结果
printf("BPM: %d, SpO2: %d\r\n", beatAvg, spO2Value);
}
}
```
需要注意的是,此示例中使用了I2C总线来与MAX30102进行通信,因此还需要实现I2C总线的初始化和读写函数。同时,为了避免光干扰,需要控制红外LED的亮度。在此示例中,使用了PA4口控制红外LED的亮灭。