一、项目介绍
当前文章介绍基于STM32设计的人体健康检测仪。设备采用STM32系列MCU作为主控芯片,配备血氧浓度传感器(使用MAX30102血氧浓度检测传感器)、OLED屏幕和电池供电等外设模块。设备可以广泛应用于医疗、健康等领域。可以帮助医生和病人更好地了解病情变化,提高治疗效果和生活质量。设备也可以用于健康管理、运动监测等场景,帮助用户了解自己的身体状况,保持健康的生活方式。
在项目中,使用了KEIL作为开发平台和工具,通过血氧模块采集人体的心跳和血氧浓度参数,并通过OLED屏幕显示现在的心跳和血氧浓度。同时,通过指标分析,提供采集到的数据与正常指标比对,分析被检测人员的健康状态。采集的数据可通过蓝牙或者WIFI传递给手机APP进行处理,方便用户随时了解自己的身体状况。
本设计采用STM32为主控芯片,搭配血氧浓度传感器和OLED屏幕,实现了人体健康数据的采集和展示,并对采集到的数据进行分析,判断被检测人员的健康状态。同时,设计使用蓝牙或WiFi将采集到的数据传递给手机APP进行处理。
二、项目设计思路
2.1 硬件设计
(1)主控芯片:STM32系列MCU,负责驱动其他外设模块;
(2)血氧浓度传感器:使用MAX30102血氧浓度检测传感器,用于采集人体的心跳和血氧浓度参数;
(3)OLED屏:用于显示现在的心跳和血氧浓度;
2.2 软件设计
(1) 通过血氧模块采集人体的心跳和血氧浓度参数;
(2) 通过OLED屏显示现在的心跳和血氧浓度;
(3) 对采集到的数据进行指标分析,将采集到的数据与正常指标比对,分析被检测人员的健康状态;
(4) 采集的数据可通过蓝牙或WiFi传递给手机APP进行处理。
2.3 威廉希尔官方网站 实现
(1)设计采用AD8232心电图(ECG)模块和MAX30102血氧模块采集心跳和血氧浓度参数,并通过I2C接口连接主控芯片STM32。
(2)OLED屏使用I2C接口与主控芯片STM32连接。
(3)采集到的数据通过算法进行指标分析,将采集到的数据与正常指标比对,判断被检测人员的健康状态。
(4)设备通过蓝牙或WiFi将采集到的数据传递给手机APP进行处理。
三、代码设计
3.1 MAX30102血氧模块代码
I2C协议代码:
#define MAX30102_I2C_ADDR 0xAE
void MAX30102_I2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* Enable I2C1 and I2C2 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);
// Configure I2C SCL and SDA pins
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open-drain output
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Configure I2C parameters
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000; // 100KHz
I2C_Init(I2C1, &I2C_InitStructure);
// Enable I2C
I2C_Cmd(I2C1, ENABLE);
}
void MAX30102_I2C_WriteReg(uint8_t reg, uint8_t value)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, reg);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, value);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
uint8_t MAX30102_I2C_ReadReg(uint8_t reg)
{
uint8_t value;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, reg);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_AcknowledgeConfig(I2C1, DISABLE);
value = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);
return value;
}
void MAX30102_I2C_ReadArray(uint8_t reg, uint8_t* data, uint8_t len)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, reg);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while(len > 1)
{
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
*data++ = I2C_ReceiveData(I2C1);
len--;
}
I2C_AcknowledgeConfig(I2C1, DISABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
*data++ = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);
}