视频链接:MCU-366-基于STM32单片机的蓝牙智能手表心率血氧体温时间监测蓝牙上传手机APP设计_哔哩哔哩_bilibili本设计由STM32f103c8t6单片机+0.96OLED显示+蜂鸣器报警电路+mpu6050计步模块+max301002心率血氧监测模块+18b20温度检测电路+按键电路+jdy-33蓝牙模块+电源电路
功能如下:
1、实现OLED液晶作为显示屏幕,显示时间、血氧心率等信息;
2、检测心率血氧功能;
3、检测室温和体温功能;
4、显示当前日期时间功能;
5、检测佩戴手表时的步数、运动距离;
6、通过按键控制检测数据的上下限;
7、超过阈值时,蜂鸣器报警提醒
8、将屏幕上的数据通过蓝牙实时的2上传到app中
9、可以通过APP发送指令修改阈值设置时间
10、所有数据可以保存在APP中
指令如下:
A设置
B增加
C减少
D检测
程序设计
/***********************************************************************************
*** 技术QQ:1761879647
*** B站名:单片机爱好者之家
***********************************************************************************/
#include "MAX30102/max30102.h"
MAX30102_TypeDef MAX30102;
/******************************************心率*********************************************************************/
uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length; //data length
uint32_t aun_red_buffer[500]; //Red LED sensor data 红色发光二极管传感器数据
int32_t n_sp02; //SPO2 value SPO2值
int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid 指示SP02计算是否有效的指示器
int32_t n_heart_rate; //heart rate value 心率值
int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid 显示心率计算是否有效的指示器
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
uint32_t un_min, un_max; // 用于计算反映心跳的车载发光二极管亮度的变量
uint8_t temp[6];
/****************************************GSM*****************************************************************************/
u8 max30102_Bus_Write(u8 Register_Address, u8 Word_Data)
{
/* 采用串行EEPROM随即读取指令序列,连续读取若干字节 */
/* 第1步:发起I2C总线启动信号 */
IIC_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_WR); /* 此处是写指令 */
/* 第3步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第4步:发送字节地址 */
IIC_Send_Byte(Register_Address);
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第5步:开始写入数据 */
IIC_Send_Byte(Word_Data);
/* 第6步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 发送I2C总线停止信号 */
IIC_Stop();
return 1; /* 执行成功 */
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
IIC_Stop();
return 0;
}
u8 max30102_Bus_Read(u8 Register_Address)
{
u8 data;
/* 第1步:发起I2C总线启动信号 */
IIC_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_WR); /* 此处是写指令 */
/* 第3步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第4步:发送字节地址, */
IIC_Send_Byte((uint8_t)Register_Address);
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第6步:重新启动I2C总线。下面开始读取数据 */
IIC_Start();
/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_RD); /* 此处是读指令 */
/* 第8步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第9步:读取数据 */
{
data = IIC_Read_Byte(0); /* 读1个字节 */
IIC_NAck(); /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
}
/* 发送I2C总线停止信号 */
IIC_Stop();
return data; /* 执行成功 返回data值 */
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
IIC_Stop();
return 0;
}
void max30102_FIFO_ReadWords(u8 Register_Address,u16 Word_Data[][2],u8 count)
{
u8 i=0;
u8 no = count;
u8 data1, data2;
/* 第1步:发起I2C总线启动信号 */
IIC_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_WR); /* 此处是写指令 */
/* 第3步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第4步:发送字节地址, */
IIC_Send_Byte((uint8_t)Register_Address);
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第6步:重新启动I2C总线。下面开始读取数据 */
IIC_Start();
/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_RD); /* 此处是读指令 */
/* 第8步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第9步:读取数据 */
while (no)
{
data1 = IIC_Read_Byte(0);
IIC_Ack();
data2 = IIC_Read_Byte(0);
IIC_Ack();
Word_Data[i][0] = (((u16)data1 << 8) | data2); //
data1 = IIC_Read_Byte(0);
IIC_Ack();
data2 = IIC_Read_Byte(0);
if(1==no)
IIC_NAck(); /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
else
IIC_Ack();
Word_Data[i][1] = (((u16)data1 << 8) | data2);
no--;
i++;
}
/* 发送I2C总线停止信号 */
IIC_Stop();
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
IIC_Stop();
}
void max30102_FIFO_ReadBytes(u8 Register_Address,u8* Data)
{
max30102_Bus_Read(REG_INTR_STATUS_1);
max30102_Bus_Read(REG_INTR_STATUS_2);
/* 第1步:发起I2C总线启动信号 */
IIC_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_WR); /* 此处是写指令 */
/* 第3步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第4步:发送字节地址, */
IIC_Send_Byte((uint8_t)Register_Address);
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第6步:重新启动I2C总线。下面开始读取数据 */
IIC_Start();
/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
IIC_Send_Byte(max30102_WR_address | I2C_RD); /* 此处是读指令 */
/* 第8步:发送ACK */
if (IIC_Wait_Ack() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第9步:读取数据 */
Data[0] = IIC_Read_Byte(1);
Data[1] = IIC_Read_Byte(1);
Data[2] = IIC_Read_Byte(1);
Data[3] = IIC_Read_Byte(1);
Data[4] = IIC_Read_Byte(1);
Data[5] = IIC_Read_Byte(0);
/* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
/* 发送I2C总线停止信号 */
IIC_Stop();
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
IIC_Stop();
// u8 i;
// u8 fifo_wr_ptr;
// u8 firo_rd_ptr;
// u8 number_tp_read;
// //Get the FIFO_WR_PTR
// fifo_wr_ptr = max30102_Bus_Read(REG_FIFO_WR_PTR);
// //Get the FIFO_RD_PTR
// firo_rd_ptr = max30102_Bus_Read(REG_FIFO_RD_PTR);
//
// number_tp_read = fifo_wr_ptr - firo_rd_ptr;
//
// //for(i=0;i<number_tp_read;i++){
// if(number_tp_read>0){
// IIC_ReadBytes(max30102_WR_address,REG_FIFO_DATA,Data,6);
// }
//max30102_Bus_Write(REG_FIFO_RD_PTR,fifo_wr_ptr);
}
void max30102_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
IIC_Init();
max30102_reset();
// max30102_Bus_Write(REG_MODE_CONFIG, 0x0b); //mode configuration : temp_en[3] MODE[2:0]=010 HR only enabled 011 SP02 enabled
// max30102_Bus_Write(REG_INTR_STATUS_2, 0xF0); //open all of interrupt
// max30102_Bus_Write(REG_INTR_STATUS_1, 0x00); //all interrupt clear
// max30102_Bus_Write(REG_INTR_ENABLE_2, 0x02); //DIE_TEMP_RDY_EN
// max30102_Bus_Write(REG_TEMP_CONFIG, 0x01); //SET TEMP_EN
// max30102_Bus_Write(REG_SPO2_CONFIG, 0x47); //SPO2_SR[4:2]=001 100 per second LED_PW[1:0]=11 16BITS
// max30102_Bus_Write(REG_LED1_PA, 0x47);
// max30102_Bus_Write(REG_LED2_PA, 0x47);
max30102_Bus_Write(REG_INTR_ENABLE_1,0xc0); // INTR setting
max30102_Bus_Write(REG_INTR_ENABLE_2,0x00);
max30102_Bus_Write(REG_FIFO_WR_PTR,0x00); //FIFO_WR_PTR[4:0]
max30102_Bus_Write(REG_OVF_COUNTER,0x00); //OVF_COUNTER[4:0]
max30102_Bus_Write(REG_FIFO_RD_PTR,0x00); //FIFO_RD_PTR[4:0]
max30102_Bus_Write(REG_FIFO_CONFIG,0x0f); //sample avg = 1, fifo rollover=false, fifo almost full = 17
max30102_Bus_Write(REG_MODE_CONFIG,0x03); //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
max30102_Bus_Write(REG_SPO2_CONFIG,0x27); // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
max30102_Bus_Write(REG_LED1_PA,0x24); //Choose value for ~ 7mA for LED1
max30102_Bus_Write(REG_LED2_PA,0x24); // Choose value for ~ 7mA for LED2
max30102_Bus_Write(REG_PILOT_PA,0x7f); // Choose value for ~ 25mA for Pilot LED
// // Interrupt Enable 1 Register. Set PPG_RDY_EN (data available in FIFO)
// max30102_Bus_Write(0x2, 1<<6);
// // FIFO configuration register
// // SMP_AVE: 16 samples averaged per FIFO sample
// // FIFO_ROLLOVER_EN=1
// //max30102_Bus_Write(0x8, 1<<4);
// max30102_Bus_Write(0x8, (0<<5) | 1<<4);
// // Mode Configuration Register
// // SPO2 mode
// max30102_Bus_Write(0x9, 3);
// // SPO2 Configuration Register
// max30102_Bus_Write(0xa,
// (3<<5) // SPO2_ADC_RGE 2 = full scale 8192 nA (LSB size 31.25pA); 3 = 16384nA
// | (1<<2) // sample rate: 0 = 50sps; 1 = 100sps; 2 = 200sps
// | (3<<0) // LED_PW 3 = 411μs, ADC resolution 18 bits
// );
// // LED1 (red) power (0 = 0mA; 255 = 50mA)
// max30102_Bus_Write(0xc, 0xb0);
// // LED (IR) power
// max30102_Bus_Write(0xd, 0xa0);
}
void max30102_reset(void)
{
max30102_Bus_Write(REG_MODE_CONFIG,0x40);
max30102_Bus_Write(REG_MODE_CONFIG,0x40);
}
void maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
{
// char ach_i2c_data[2];
// ach_i2c_data[0]=uch_addr;
// ach_i2c_data[1]=uch_data;
//
// IIC_WriteBytes(I2C_WRITE_ADDR, ach_i2c_data, 2);
IIC_Write_One_Byte(I2C_WRITE_ADDR,uch_addr,uch_data);
}
void maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
{
// char ch_i2c_data;
// ch_i2c_data=uch_addr;
// IIC_WriteBytes(I2C_WRITE_ADDR, &ch_i2c_data, 1);
//
// i2c.read(I2C_READ_ADDR, &ch_i2c_data, 1);
//
// *puch_data=(uint8_t) ch_i2c_data;
IIC_Read_One_Byte(I2C_WRITE_ADDR,uch_addr,puch_data);
}
void maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
{
uint32_t un_temp;
unsigned char uch_temp;
char ach_i2c_data[6];
*pun_red_led=0;
*pun_ir_led=0;
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
IIC_ReadBytes(I2C_WRITE_ADDR,REG_FIFO_DATA,(u8 *)ach_i2c_data,6);
un_temp=(unsigned char) ach_i2c_data[0];
un_temp<<=16;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[1];
un_temp<<=8;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[2];
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[3];
un_temp<<=16;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[4];
un_temp<<=8;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[5];
*pun_ir_led+=un_temp;
*pun_red_led&=0x03FFFF; //Mask MSB [23:18]
*pun_ir_led&=0x03FFFF; //Mask MSB [23:18]
}
int32_t get_heart_rate(void)
{
int i;
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=500; //100的缓冲长度存储5秒钟以100sps速度运行的样本
for(i=0;i<n_ir_buffer_length;i++) //读取前500个样本,并确定信号范围
{
while(MAX30102_INT==1); //等到中断产生
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // 组合值以获得实际数字
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5];
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //更新信号最小值
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
if(n_sp02<0)n_sp02=99;
MAX30102.xinlv = n_heart_rate;
MAX30102.SP02 = n_sp02;
if(MAX30102.SP02>99)MAX30102.SP02=99;
return n_sp02;
}
电路设计
基于STM32单片机的蓝牙智能手表设计论文
摘要
本文介绍了一款基于STM32f103c8t6单片机的蓝牙智能手表设计,具备多项功能,包括OLED液晶显示、心率血氧监测、温度检测、步数统计等。通过蓝牙模块,手表可以实时上传数据至手机APP,并支持通过APP进行阈值设置和数据查询。设计在实际佩戴中,能够提供全面的健康监测和智能控制。
1. 引言
近年来,随着人们健康意识的提高,智能穿戴设备成为关注的焦点。本设计以STM32单片机为核心,集成了OLED显示、心率血氧监测、温度检测等多种功能,通过蓝牙模块实现与手机APP的连接,为用户提供全方位的健康监测服务。
1.1 国内研究背景
在国内,随着人们生活水平的提高和健康意识的增强,智能穿戴设备逐渐成为人们关注的焦点。许多研究致力于开发具有多功能的智能手表,以满足人们对健康监测和智能化生活的需求。国内研究主要关注于硬件和软件的结合,以提高设备的功能性和用户体验。
1.2 国外研究背景
在国外,智能手表的研究早已走在前沿,各大科技公司推出的智能手表产品层出不穷。这些产品不仅仅局限于时间显示,还包括健康监测、运动追踪、通讯等多个方面。国外研究注重于用户体验、数据精准性以及设备的智能互联性,推动了智能手表领域的快速发展。在国外,基于STM32单片机的蓝牙智能手表设计涉及了嵌入式系统、智能穿戴设备以及物联网技术等多个领域。以下是国外研究背景的详细介绍:
1. 嵌入式系统与微控制器技术
微控制器应用广泛: 国外研究注重嵌入式系统的设计,微控制器作为核心控制单元的应用广泛,STM32系列因其性能卓越、低功耗等特点成为研究的热门选择。
实时数据处理: 国外的研究倾向于充分利用STM32单片机的实时数据处理能力,以提高智能手表对生理指标、运动数据等信息的精准监测和处理能力。
2. 智能穿戴设备与健康监测
多功能智能穿戴设备: 国外研究智能手表注重设计多功能的健康监测装置,例如心率血氧监测、步数计算等,以满足用户对全面健康监测的需求。
用户体验与界面设计: 设备的用户体验、界面设计以及对不同用户需求的灵活适应是国外研究的关键点,注重提供更直观、友好的用户界面。
3. 物联网技术应用
蓝牙连接与互联性: 国外研究在蓝牙技术的应用上较为深入,注重实现设备与手机、其他智能设备的高效互联,以提供更广泛的数据传输和远程控制功能。
云端数据存储与分析: 国外的研究强调将智能手表采集到的数据上传至云端,通过云端服务进行数据存储、分析,以实现更全面的健康管理和个性化建议。
4. 用户定制与开放性设计
开放性设计: 国外的研究强调开放性设计,使得智能手表可以支持第三方应用的扩展,提供更加个性化的用户体验。
可定制化: 设备的硬件和软件设计注重可定制化,以满足不同用户群体的特定需求,推动智能手表的个性化发展。
综上所述,国外研究在基于STM32单片机的蓝牙智能手表设计中注重嵌入式系统技术、智能穿戴设备功能的多样性、物联网技术的应用以及用户体验和开放性设计等方面。这些研究方向在提高设备性能、用户体验和应用广泛性上都取得了显著的进展。
2. 研究意义
2.1 促进健康管理
智能手表作为可穿戴设备,具备多项健康监测功能,有助于个体实时监测生理指标,提高对健康状况的了解。通过实时数据的监测,可以及时采取措施,促进个体的健康管理。1. 科技发展背景
技术进步与市场需求: 随着科技的不断进步和人们对健康管理需求的增加,智能穿戴设备(如智能手表)成为连接人体生理数据和数字世界的重要桥梁。
物联网与健康关注: 物联网技术的兴起推动了智能穿戴设备的发展,国内用户对健康数据的关注度不断提高,需要一款能够全面监测生理指标的便携式设备。
2. 健康意识与市场竞争
健康意识抬头: 近年来,国内普遍关注健康生活方式,人们更加重视个体的健康状况和数据监测,促使了智能手表等健康监测设备的需求增加。
市场竞争与产品多样性: 各大科技公司和创业企业纷纷投入智能穿戴设备市场,推出了多款功能丰富、款式多样的智能手表产品,致力于满足不同用户群体的需求。
3. 科研与产业发展
科研助推产业进步: 国内多所高校、研究机构开展智能穿戴设备的相关研究,涉及硬件、软件、数据处理等多个领域,推动了相关产业的创新发展。
产业链拓展: 智能穿戴设备的生产、研发以及相关的软硬件开发形成了完整的产业链,涉及传感器、芯片、算法开发、应用软件等多个领域。
4. 政策支持与消费市场
政策扶持新技术: 国内政府出台了一系列支持新技术发展的政策,鼓励创新,提升了智能穿戴设备领域的技术水平。
消费市场潜力: 中国庞大的消费市场对智能穿戴设备有着巨大的潜力,用户数量庞大,需求多样化,这为智能手表等产品提供了广阔的市场空间。
总的来说,国内智能穿戴设备的研究背景主要围绕着科技发展、健康意识提升、市场竞争激烈、科研推动产业发展、政策支持和消费市场潜力等方面。这些因素共同推动了智能手表等智能穿戴设备在国内市场的蓬勃发展和持续研究。
2.2 提升生活品质
智能手表不仅仅是时间工具,更是生活助手。通过整合多种功能,如心率血氧监测、步数统计等,能够为用户提供全面的健康数据和运动信息,帮助用户科学合理地安排生活和运动,提升生活品质。
2.3 推动技术发展
研究基于STM32单片机的蓝牙智能手表,涉及硬件、软件、通信等多个领域的融合。通过该研究,不仅可以推动智能手表领域的技术发展,还有助于相关领域的创新和进步。这对于智能穿戴设备行业的未来发展具有积极意义。
2.4 适应市场需求
随着社会的快速发展,人们对于健康、智能化生活的需求不断增加。研究基于STM32单片机的蓝牙智能手表,有助于满足市场对多功能智能手表的需求,促使相关产业更好地适应市场变化。
综上所述,基于STM32单片机的蓝牙智能手表的研究不仅具备良好的国内外市场前景,而且对个体健康管理、生活品质提升以及相关技术的发展都具有深远的研究意义。
2. 系统硬件设计
2.1 主要硬件组成
STM32f103c8t6单片机
0.96寸OLED显示屏
蜂鸣器报警电路
MPU6050计步模块
MAX301002心率血氧监测模块
18B20温度检测电路
按键电路
JDY-33蓝牙模块
电源电路
1. STM32F103C8T6单片机
描述: ARM Cortex-M3内核的32位微控制器。
功能: 控制整个系统,处理各种传感器数据、显示控制、蓝牙通信以及实现各项功能的逻辑控制。
2. 0.96英寸OLED显示屏
描述: OLED液晶显示屏,用于展示时间、血氧、心率、温度和其他监测数据。
功能: 显示时间、血氧、心率、温度以及其他监测数据,提供用户界面。
3. 蜂鸣器报警电路
描述: 小型蜂鸣器模块。
功能: 用于报警提醒,当监测数据超过预设阈值时发出声音提醒用户。
4. MPU6050计步模块
描述: 6轴传感器,包括三轴加速度计和三轴陀螺仪。
功能: 检测手表佩戴时的步数和运动距离,用于计步和运动追踪功能。
5. MAX30100心率血氧监测模块
描述: 集成了红外发光二极管、光电检测器和信号处理电路的模块。
功能: 实现心率和血氧监测功能,检测用户的心率和血氧饱和度。
6. 18B20温度检测电路
描述: 数字温度传感器模块。
功能: 检测室温和体温,提供温度数据。
7. 按键电路
描述: 物理按键模块。
功能: 用于手表的用户交互,可能用于设置阈值、切换功能或进行其他操作。
8. JDY-33蓝牙模块
描述: 蓝牙4.0模块。
功能: 通过蓝牙与手机通信,实现数据传输和与手机APP的连接。
9. 电源电路
描述: 电池供电管理和充电电路。
功能: 提供稳定的电源,管理充电和供电需求。
功能实现:
显示功能: 使用OLED显示时间、监测数据(如血氧、心率、温度)以及日期时间等信息。
监测功能: 包括心率、血氧、室温/体温的监测。
计步功能: 使用MPU6050模块检测佩戴手表时的步数和运动距离。
按键控制: 通过按键电路控制数据的上下限设置。
报警功能: 当监测数据超过预设阈值时,蜂鸣器报警提醒。
蓝牙通信: 将手表数据通过JDY-33蓝牙模块实时上传到手机APP中,并且能够通过APP发送指令修改阈值设置和时间。
数据存储: 在手机APP中保存所有监测数据,实现数据的长期存储和查看。
这些硬件组件和功能整合使得智能手表具备了多项健康监测和用户交互的功能,能够通过蓝牙与手机APP实现数据传输和远程控制。
1. STM32F103C8T6单片机
电源供应: 连接到电源电路,确保稳定的电源供应。
晶体振荡器: 配置外部晶体振荡器,提供STM32的时钟。
引脚连接: 连接到其他硬件模块,如OLED显示屏、蜂鸣器、MPU6050、MAX30100、18B20、按键、蓝牙模块等。
2. 0.96英寸OLED显示屏
连接到STM32: 使用I2C或SPI接口与STM32单片机通信。
电源管理: 连接到电源电路,确保适当的电源供应。
3. 蜂鸣器报警电路
连接到STM32: 通过数字引脚连接到STM32,以触发报警。
电源管理: 连接到电源电路,确保适当的电源供应。
4. MPU6050计步模块
连接到STM32: 通过I2C或SPI接口与STM32通信。
电源管理: 连接到电源电路,确保适当的电源供应。
5. MAX30100心率血氧监测模块
连接到STM32: 通过I2C或SPI接口与STM32通信。
电源管理: 连接到电源电路,确保适当的电源供应。
6. 18B20温度检测电路
连接到STM32: 通过数字引脚(一般是单总线协议)与STM32通信。
电源管理: 连接到电源电路,确保适当的电源供应。
7. 按键电路
连接到STM32: 通过数字引脚连接到STM32,用于检测按键的状态。
电源管理: 连接到电源电路,确保适当的电源供应。
8. JDY-33蓝牙模块
连接到STM32: 通过UART接口与STM32通信。
电源管理: 连接到电源电路,确保适当的电源供应。
9. 电源电路
供电给其他硬件: 连接到其他硬件模块,如STM32、显示屏、传感器等。
2.2 功能模块详述
3.2 数据上传与指令控制
通过蓝牙模块将监测到的数据实时上传至手机APP。APP支持指令发送,包括设置阈值、增加、减少、数据检测等功能。
指令列表:
- A:设置
- B:增加
- C:减少
- D:检测
1. 主控程序设计(STM32F103C8T6单片机)
初始化: 包括配置时钟、GPIO引脚、外设(如I2C、SPI、UART)、中断等。
主循环(Main Loop):
获取传感器数据: 通过I2C、SPI等协议获取传感器(如MPU6050、MAX30100、18B20)数据。
数据处理: 对传感器数据进行处理和解析,获取心率、血氧、温度、步数等信息。
OLED显示: 更新OLED显示屏上的时间、监测数据等信息。
按键检测: 监测按键状态,根据按键输入控制功能或设置阈值。
超过阈值检测: 检查数据是否超过预设阈值,触发蜂鸣器报警。
蓝牙数据传输: 通过UART与JDY-33蓝牙模块通信,将数据传输到手机APP。
2. OLED显示模块程序设计
初始化: 初始化OLED显示屏,配置显示参数。
数据更新: 接收主控发送的数据并在屏幕上显示时间、监测数据等。
3. 传感器模块程序设计
MPU6050模块:
初始化: 配置MPU6050传感器。
数据获取: 通过I2C通信获取加速度和陀螺仪数据。
步数计算: 根据数据计算步数和运动距离。
MAX30100模块:
初始化: 初始化MAX30100模块。
心率和血氧监测: 获取红外和光电信号,并处理以计算心率和血氧饱和度。
18B20模块:
初始化: 配置18B20模块。
温度获取: 通过单总线协议获取温度数据。
4. 按键模块程序设计
按键扫描: 定时扫描按键状态。
按键功能处理: 根据按键状态执行相应的功能,如修改阈值、功能切换等。
5. 蓝牙模块程序设计(JDY-33蓝牙模块)
初始化: 配置UART通信参数。
数据传输: 通过UART与主控进行双向通信,接收数据并将数据上传至手机APP。
4. 实验结果与讨论
设计经过实际测试,显示准确、监测数据稳定。蓝牙连接稳定,能够实时上传数据至手机APP。用户可通过APP进行阈值设置和实时数据查询,提高了设备的智能化水平。
5. 结论
本设计基于STM32单片机的蓝牙智能手表集成了多项健康监测功能,通过蓝牙实现与手机APP的连接,为用户提供了便捷的健康管理方案。未来的工作可以进一步优化算法和扩展功能,提升设备的全面性和用户体验。
关键词: STM32, 智能手表, 健康监测, 蓝牙通信, OLED显示, 心率血氧监测, 温度检测, 步数统计.