一、硬件组成
- STM32F103RCT6mini为主芯片
1.TFTlcd屏幕
2.有源蜂鸣器
3.max30102心率监测模块
4.HC-05蓝牙模块
5.dsb18b20温度模块
6.MQ2
二、 实现效果
手指放在心率传感器上可检测心跳放到温度传感器可以测量温度并上传蓝牙手机APP
HC-05蓝牙模块:
相关参数讲解
6根引脚,名称与功能如下;
VCC 接电源的正极,电压的范围为3.3v到5.0v
GND 地线
TXD:模块串口发送引脚(TTL电平,不能直接接RS232电平),可直接接单片机的RXD引脚
RXD:模块串口接收引脚(TTL电平,不能直接接RS232电平),可直接接单片机的TXD引脚
EN:用于进入AT状态:
STATE:这个引脚是用来检测蓝牙模块是否已经连接上了其他蓝牙设备
通讯方式(tx、rx)
HC-05通过TX和RX引脚,支持使用标准AT命令。为此,用户必须在设备启动时进入特殊命令模式。启动进入数据模式,这样它就可以与其他设备进行无线通信
常见的AT指令
AT指令不区分大小写,但是都要以回车符结尾,下面是常用的AT指令
部分核心代码
int main(void)
{
u8 x=0;
u16 air_adcx=0;
short temperature;
//variables to calculate the on-board LED brightness that reflects the heartbeats
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
u8 temp_num=0;
u8 temp[6];
u8 str[100];
u8 dis_hr=0,dis_spo2=0;
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为9600
USART2_Init(36,9600);
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init();
DS18B20_Init();
Adc_Init(); //ADC初始化
POINT_COLOR=BLACK;
BEEP_Init();
LCD_ShowString(30,40,200,24,24,"Health system");
LCD_ShowString(30,150,200,16,16,"Temp: . C");
LCD_ShowString(30,90,200,16,16,"HR: ");
LCD_ShowString(30,110,200,16,16,"SpO2: ");
LCD_ShowString(30,130,200,16,16,"Air: ");
Chinese_Show_one(90,70,0,16,0);
Chinese_Show_one(110,70,1,16,0);
Chinese_Show_one(130,70,2,16,0);
max30102_init();
printf("\r\n MAX30102 init done\r\n");
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
//read the first 500 samples, and determine the signal range
for(i=0;i<n_ir_buffer_length;i++)
{
while(MAX30102_INT==1); //wait until the interrupt pin asserts
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]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //update signal min
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i]; //update signal max
}
un_prev_data=aun_red_buffer[i];
//calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
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);
while(1)
{
i=0;
un_min=0x3FFFF;
un_max=0;
//-------------------温度显示----------------------------------
temperature=DS18B20_Get_Temp();
if(temperature<0)
{
LCD_ShowChar(30+40,150,'-',16,0); //显示负号
temperature=-temperature; //转为正数
}
else
LCD_ShowChar(30+40,150,' ',16,0); //去掉负号
//printf("temp : %d.%d\r\n",temperature/10,temperature%10);
LCD_ShowNum(30+40+8,150,temperature/10,2,16); //显示正数部分
LCD_ShowNum(30+40+32,150,temperature%10,1,16); //显示小数部分
//u2_printf("temperature %d\r\n", temperature);
//-------------------血氧心率计算----------------------------------
//dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
for (i = 100; i < 500; i++)
{
aun_red_buffer[i - 100] = aun_red_buffer[i];
aun_ir_buffer[i - 100] = aun_ir_buffer[i];
//update the signal min and max
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];
}
//take 100 sets of samples before calculating the heart rate.
for(i=400;i<500;i++)
{
un_prev_data=aun_red_buffer[i-1];
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]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(aun_red_buffer[i]>un_prev_data)
{
f_temp=aun_red_buffer[i]-un_prev_data;
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness-=(int)f_temp;
if(n_brightness<0)
n_brightness=0;
}
else
{
f_temp=un_prev_data-aun_red_buffer[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness+=(int)f_temp;
if(n_brightness>MAX_BRIGHTNESS)
n_brightness=MAX_BRIGHTNESS;
}
//send samples and calculation result to terminal program through UART
if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
{
dis_hr = n_heart_rate;
dis_spo2 = n_sp02;
}
else
{
dis_hr = 0;
dis_spo2 = 0;
}
printf("HR=%i, ", n_heart_rate);
printf("HRvalid=%i, ", ch_hr_valid);
printf("SpO2=%i, ", n_sp02);
printf("SPO2Valid=%i\r\n", ch_spo2_valid);
//u2_printf("n_heart_rate %d\r\n", n_heart_rate);
//u2_printf("n_sp02 %d\r\n", n_sp02);
}