单片机源程序如下:
- #include "struct_all.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart1_dma.h"
- #include "algorithm.h"
- #include "max30102.h"
- #include "myiic.h"
- #include "key.h"
- #define MAX_BRIGHTNESS 255
- uint32_t aun_ir_buffer[150]; //infrared LED sensor data
- uint32_t aun_red_buffer[150]; //red LED sensor data
- int32_t n_ir_buffer_length; //data length
- int32_t n_spo2; //SPO2 value
- int8_t ch_spo2_valid; //indicator to show if the SPO2 calculation is valid
- 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;
- int32_t hr_buf[16];
- int32_t hrSum;
- int32_t hrAvg;
- int32_t spo2_buf[16];
- int32_t spo2Sum;
- int32_t spo2Avg;
- int32_t spo2BuffFilled;
- int32_t hrBuffFilled;
- int32_t hrValidCnt = 0;
- int32_t spo2ValidCnt = 0;
- int32_t hrThrowOutSamp = 0;
- int32_t spo2ThrowOutSamp = 0;
- int32_t spo2Timeout = 0;
- int32_t hrTimeout = 0;
- void Send_To_PC( int rate, int spo2 );
- void Send_To_PC2( unsigned int red, unsigned int ir);
- void loop(void);
- int main(void)
- {
- uart1_tx.buf[0] = 0x55;
- uart1_tx.buf[1] = 0xAA;
- uart1_tx.buf[10] = 0x0D;
- delay_init(); //延时函数初始化
- NVIC_Configuration();
- USART1_DMA_Init(115200); //PA9:TX PA10:RX 接WIFI模块 与手机相连发送状态数据
- KEY_Init(); //实际是 max30102的中断线
- bsp_InitI2C();
- maxim_max30102_reset(); //resets the MAX30102
- //pinMode(2, INPUT); //pin D2 connects to the interrupt output pin of the MAX30102
- maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_dummy); //Reads/clears the interrupt status register
- maxim_max30102_init(); //initialize the MAX30102
- while(1)
- {
- loop();
- }
- }
- // the loop routine runs over and over again forever:
- void loop(void)
- {
- uint32_t un_min, un_max, un_prev_data, un_brightness; //variables to calculate the on-board LED brightness that reflects the heartbeats
- int32_t i;
- float f_temp;
- un_brightness = 0;
- un_min = 0x3FFFF;
- un_max = 0;
- n_ir_buffer_length = 150; //buffer length of 150 stores 3 seconds of samples running at 50sps
- //read the first 150 samples, and determine the signal range
- for(i = 0; i < n_ir_buffer_length; i++)
- {
- while(KEY0 == 1); //wait until the interrupt pin asserts
- maxim_max30102_read_fifo((aun_red_buffer + i), (aun_ir_buffer + i)); //read from MAX30102 FIFO
- 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
- /*SerialUSB.print(F("red="));
- SerialUSB.print(aun_red_buffer[i], DEC);
- SerialUSB.print(F(", ir="));
- SerialUSB.println(aun_ir_buffer[i], DEC);*/
- //Send_To_PC2(aun_red_buffer[i],aun_ir_buffer[i]);
- }
- un_prev_data = aun_red_buffer[i];
- //calculate heart rate and SpO2 after first 150 samples (first 3 seconds of samples)
- maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
- //Continuously taking samples from MAX30102. Heart rate and SpO2 are calculated every 1 second
- while(1)
- {
- i = 0;
- un_min = 0x3FFFF;
- un_max = 0;
- //dumping the first 50 sets of samples in the memory and shift the last 100 sets of samples to the top
- for(i = 50; i < 150; i++)
- {
- aun_red_buffer[i - 50] = aun_red_buffer[i];
- aun_ir_buffer[i - 50] = 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 50 sets of samples before calculating the heart rate.
- for(i = 100; i < 150; i++)
- {
- un_prev_data = aun_red_buffer[i - 1];
- while(KEY0 == 1);
- maxim_max30102_read_fifo((aun_red_buffer + i), (aun_ir_buffer + i));
- //calculate the brightness of the LED
- 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;
- f_temp = un_brightness - f_temp;
- if(f_temp < 0)
- un_brightness = 0;
- else
- un_brightness = (int)f_temp;
- }
- else
- {
- f_temp = un_prev_data - aun_red_buffer[i];
- f_temp /= (un_max - un_min);
- f_temp *= MAX_BRIGHTNESS;
- un_brightness += (int)f_temp;
- if(un_brightness > MAX_BRIGHTNESS)
- un_brightness = MAX_BRIGHTNESS;
- }
- //Send_To_PC2( aun_red_buffer[i], aun_ir_buffer[i] );
- //send samples and calculation result to terminal program through UART
- /*SerialUSB.print(F("red="));
- SerialUSB.print(aun_red_buffer[i], DEC);
- SerialUSB.print(F(", ir="));
- SerialUSB.print(aun_ir_buffer[i], DEC);
- SerialUSB.print(F(", HR="));
- SerialUSB.print(n_heart_rate, DEC);
- SerialUSB.print(F(", HRvalid="));
- SerialUSB.print(ch_hr_valid, DEC);
- SerialUSB.print(F(", SPO2="));
- SerialUSB.print(n_spo2, DEC);
- SerialUSB.print(F(", SPO2Valid="));
- SerialUSB.println(ch_spo2_valid, DEC);*/
- // SerialUSB.println(aun_ir_buffer[i], DEC);
- }
- maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
- if ((ch_hr_valid == 1) && (n_heart_rate < 190) && (n_heart_rate > 40))
- {
- hrTimeout = 0;
- // Throw out up to 1 out of every 5 valid samples if wacky
- if (hrValidCnt == 4)
- {
- hrThrowOutSamp = 1;
- hrValidCnt = 0;
- for (i = 12; i < 16; i++)
- {
- if (n_heart_rate < hr_buf[i] + 10)
- {
- hrThrowOutSamp = 0;
- hrValidCnt = 4;
- }
- }
- }
- else
- {
- hrValidCnt = hrValidCnt + 1;
- }
- if (hrThrowOutSamp == 0)
- {
- // Shift New Sample into buffer
- for(i = 0; i < 15; i++)
- {
- hr_buf[i] = hr_buf[i + 1];
- }
- hr_buf[15] = n_heart_rate;
- // Update buffer fill value
- if (hrBuffFilled < 16)
- {
- hrBuffFilled = hrBuffFilled + 1;
- }
- // Take moving average
- hrSum = 0;
- if (hrBuffFilled < 2)
- {
- hrAvg = 0;
- }
- else if (hrBuffFilled < 4)
- {
- for(i = 14; i < 16; i++)
- {
- hrSum = hrSum + hr_buf[i];
- }
- hrAvg = hrSum >> 1;
- }
- else if (hrBuffFilled < 8)
- {
- for(i = 12; i < 16; i++)
- {
- hrSum = hrSum + hr_buf[i];
- }
- hrAvg = hrSum >> 2;
- }
- else if (hrBuffFilled < 16)
- {
- for(i = 8; i < 16; i++)
- {
- hrSum = hrSum + hr_buf[i];
- }
- hrAvg = hrSum >> 3;
- }
- else
- {
- for(i = 0; i < 16; i++)
- {
- hrSum = hrSum + hr_buf[i];
- }
- hrAvg = hrSum >> 4;
- }
- }
- hrThrowOutSamp = 0;
- }
- else
- {
- hrValidCnt = 0;
- if (hrTimeout == 4)
- {
- hrAvg = 0;
- hrBuffFilled = 0;
- }
- else
- {
- hrTimeout++;
- }
- }
- if ((ch_spo2_valid == 1) && (n_spo2 > 59))
- {
- spo2Timeout = 0;
- // Throw out up to 1 out of every 5 valid samples if wacky
- if (spo2ValidCnt == 4)
- {
- spo2ThrowOutSamp = 1;
- spo2ValidCnt = 0;
- for (i = 12; i < 16; i++)
- {
- if (n_spo2 > spo2_buf[i] - 10)
- {
- spo2ThrowOutSamp = 0;
- spo2ValidCnt = 4;
- }
- }
- }
- else
- {
- spo2ValidCnt = spo2ValidCnt + 1;
- }
- if (spo2ThrowOutSamp == 0)
- {
- // Shift New Sample into buffer
- for(i = 0; i < 15; i++)
- {
- spo2_buf[i] = spo2_buf[i + 1];
- }
- spo2_buf[15] = n_spo2;
- // Update buffer fill value
- if (spo2BuffFilled < 16)
- {
- spo2BuffFilled = spo2BuffFilled + 1;
- }
- // Take moving average
- spo2Sum = 0;
- if (spo2BuffFilled < 2)
- {
- spo2Avg = 0;
- }
- else if (spo2BuffFilled < 4)
- {
- for(i = 14; i < 16; i++)
- {
- spo2Sum = spo2Sum + spo2_buf[i];
- }
- spo2Avg = spo2Sum >> 1;
- }
- else if (spo2BuffFilled < 8)
- {
- for(i = 12; i < 16; i++)
- {
- spo2Sum = spo2Sum + spo2_buf[i];
- }
- spo2Avg = spo2Sum >> 2;
- }
- else if (spo2BuffFilled < 16)
- {
- for(i = 8; i < 16; i++)
- {
- spo2Sum = spo2Sum + spo2_buf[i];
- }
- spo2Avg = spo2Sum >> 3;
- }
- else
- {
- for(i = 0; i < 16; i++)
- {
- spo2Sum = spo2Sum + spo2_buf[i];
- }
- spo2Avg = spo2Sum >> 4;
- }
- }
- spo2ThrowOutSamp = 0;
- }
- else
- {
- spo2ValidCnt = 0;
- if (spo2Timeout == 4)
- {
- spo2Avg = 0;
- spo2BuffFilled = 0;
- }
- else
- {
- spo2Timeout++;
- }
- }
- Send_To_PC(hrAvg, spo2Avg);
- }
- }
- /**
- * @Description: wifi发送到手机APP的数据,连接在uart1上
- * @param encoder_left - 左轮编码器值
- * @param encoder_right- 右轮编码器值
- * @note1 :数据协议 0xFFD8 左轮速度double型(8位) 右轮速度double型(8)位 数据个数 0xFFD9
- */
- union INT_CHAR
- {
- char char_buf[4];
- signed int int_buf; //车轮的实际速度 单位:脉冲/s
- }int_char;
- void Send_To_PC( int rate, int spo2 )
- {
- u8 i;
- uart1_tx.buf[0] = 0xFF;
- uart1_tx.buf[1] = 0xD8;
- int_char.int_buf = rate;
- for (i=0;i<4;i++)
- {
- uart1_tx.buf[i+2] = int_char.char_buf[3-i]; //注意需要倒着发送
- }
- int_char.int_buf = spo2;
- for (i=0;i<4;i++)
- {
- uart1_tx.buf[i+6] = int_char.char_buf[3-i]; //注意需要倒着发送
- }
- uart1_tx.buf[10] = 0xFF;
- uart1_tx.buf[11] = 0xD9;
- USART1_DMA_Send_Once_Data( uart1_tx.buf, 12 );
- }
- union UNINT_CHAR
- {
- char char_buf[4];
- unsigned int unint_buf; //车轮的实际速度 单位:脉冲/s
- }unint_char;
- void Send_To_PC2( unsigned int red, unsigned int ir)
- {
- u8 i;
- uart1_tx.buf[0] = 0xFF;
- uart1_tx.buf[1] = 0xD8;
- unint_char.unint_buf = red;
- for (i=0;i<4;i++)
- {
- uart1_tx.buf[i+2] = unint_char.char_buf[3-i]; //注意需要倒着发送
- }
- unint_char.unint_buf = ir;
- for (i=0;i<4;i++)
- {
- uart1_tx.buf[i+6] = unint_char.char_buf[3-i]; //注意需要倒着发送
- }
- uart1_tx.buf[10] = 0xFF;
- uart1_tx.buf[11] = 0xD9;
- USART1_DMA_Send_Once_Data( uart1_tx.buf, 12 );
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
stm32 max30102上传整数型数据.rar
(337.99 KB, 下载次数: 22)
|