找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4183|回复: 4
收起左侧

基于stm32f03的心率血样算法 MAX30102模块 源程序

  [复制链接]
ID:450941 发表于 2021-3-1 15:36 | 显示全部楼层 |阅读模式
这是基于STM32F103的心率血氧算法 用的是MAX30102的模块  仅供参考

单片机源程序如下:
  1. /*************************************************************************************
  2. HXDZ-30102:
  3.         VCC<->3.3V
  4.         GND<->GND
  5.         SCL<->PB7
  6.         SDA<->PB8
  7.         IM<->PB9
  8. 0.96inch OLED :
  9.         VCC<->3.3V
  10.         GND<->GND
  11.         SCL<->PA5
  12.         SDA<->PA6
  13.         RST<->PA3
  14.         DC<->PA4
  15.         CS<->PA2
  16. USB-TTL:
  17.         5V<->5V
  18.         GND<->GND
  19.         RXD<->PA9
  20.         TXD<->PA10
  21. **************************************************************************************/
  22. #include "led.h"
  23. #include "delay.h"
  24. #include "sys.h"
  25. #include "usart.h"
  26. #include "max30102.h"
  27. #include "myiic.h"
  28. #include "algorithm.h"
  29. #include "oled.h"

  30. uint32_t aun_ir_buffer[500]; //IR LED sensor data
  31. int32_t n_ir_buffer_length;    //data length
  32. uint32_t aun_red_buffer[500];    //Red LED sensor data
  33. int32_t n_sp02; //SPO2 value
  34. int8_t ch_spo2_valid;   //indicator to show if the SP02 calculation is valid
  35. int32_t n_heart_rate;   //heart rate value
  36. int8_t  ch_hr_valid;    //indicator to show if the heart rate calculation is valid
  37. uint8_t uch_dummy;

  38. #define MAX_BRIGHTNESS 255

  39. void dis_DrawCurve(u32* data,u8 x);

  40. int main(void)
  41. {
  42.         //variables to calculate the on-board LED brightness that reflects the heartbeats
  43.         uint32_t un_min, un_max, un_prev_data;  
  44.         int i;
  45.         int32_t n_brightness;
  46.         float f_temp;
  47.         u8 temp_num=0;
  48.         u8 temp[6];
  49.         u8 str[100];
  50.         u8 dis_hr=0,dis_spo2=0;

  51.         NVIC_Configuration();
  52.         delay_init();                     //延时函数初始化         
  53.         uart_init(115200);                 //串口初始化为115200
  54.         LED_Init();
  55.         
  56.         //OLED
  57.         OLED_Init();
  58.         OLED_ShowString(0,0,"  initializing  ",16);
  59.         OLED_Refresh_Gram();//更新显示到OLED         

  60.         max30102_init();

  61.         printf("\r\n MAX30102  init  \r\n");

  62.         un_min=0x3FFFF;
  63.         un_max=0;
  64.         
  65.         n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
  66.         //read the first 500 samples, and determine the signal range
  67.     for(i=0;i<n_ir_buffer_length;i++)
  68.     {
  69.         while(MAX30102_INT==1);   //wait until the interrupt pin asserts
  70.         
  71.                 max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
  72.                 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
  73.                 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
  74.             
  75.         if(un_min>aun_red_buffer[i])
  76.             un_min=aun_red_buffer[i];    //update signal min
  77.         if(un_max<aun_red_buffer[i])
  78.             un_max=aun_red_buffer[i];    //update signal max
  79.     }
  80.         un_prev_data=aun_red_buffer[i];
  81.         //calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
  82.     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);
  83.         
  84.         while(1)
  85.         {
  86.                 i=0;
  87.         un_min=0x3FFFF;
  88.         un_max=0;
  89.                
  90.                 //dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
  91.         for(i=100;i<500;i++)
  92.         {
  93.             aun_red_buffer[i-100]=aun_red_buffer[i];
  94.             aun_ir_buffer[i-100]=aun_ir_buffer[i];
  95.             
  96.             //update the signal min and max
  97.             if(un_min>aun_red_buffer[i])
  98.             un_min=aun_red_buffer[i];
  99.             if(un_max<aun_red_buffer[i])
  100.             un_max=aun_red_buffer[i];
  101.         }
  102.                 //take 100 sets of samples before calculating the heart rate.
  103.         for(i=400;i<500;i++)
  104.         {
  105.             un_prev_data=aun_red_buffer[i-1];
  106.             while(MAX30102_INT==1);
  107.             max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
  108.                         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
  109.                         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
  110.         
  111.             if(aun_red_buffer[i]>un_prev_data)
  112.             {
  113.                 f_temp=aun_red_buffer[i]-un_prev_data;
  114.                 f_temp/=(un_max-un_min);
  115.                 f_temp*=MAX_BRIGHTNESS;
  116.                 n_brightness-=(int)f_temp;
  117.                 if(n_brightness<0)
  118.                     n_brightness=0;
  119.             }
  120.             else
  121.             {
  122.                 f_temp=un_prev_data-aun_red_buffer[i];
  123.                 f_temp/=(un_max-un_min);
  124.                 f_temp*=MAX_BRIGHTNESS;
  125.                 n_brightness+=(int)f_temp;
  126.                 if(n_brightness>MAX_BRIGHTNESS)
  127.                     n_brightness=MAX_BRIGHTNESS;
  128.             }
  129.                         //send samples and calculation result to terminal program through UART
  130.                         if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
  131.                         {
  132.                                 dis_hr = n_heart_rate;
  133.                                 dis_spo2 = n_sp02;
  134.                         }
  135.                         else
  136.                         {
  137.                                 dis_hr = 0;
  138.                                 dis_spo2 = 0;
  139.                         }
  140.                                 printf("HR=%i, ", n_heart_rate);
  141.                                 printf("HRvalid=%i, ", ch_hr_valid);
  142.                                 printf("SpO2=%i, ", n_sp02);
  143.                                 printf("SPO2Valid=%i\r\n", ch_spo2_valid);
  144.                 }
  145.         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);
  146.                
  147.                 //显示刷新
  148.                 LED0=0;
  149.                 if(dis_hr == 0)  //**dis_hr == 0 && dis_spo2 == 0
  150.                 {
  151.                         sprintf((char *)str,"HR:---        ");//**HR:--- SpO2:---
  152.                 }
  153.                 else{
  154.                         sprintf((char *)str,"HR:%3d        ",dis_hr);//**HR:%3d SpO2:%3d
  155.                 }
  156.                 OLED_ShowString(0,0,str,16);
  157.                 OLED_Fill(0,23,127,63,0);
  158.                 //红光在上,红外在下
  159.                 dis_DrawCurve(aun_red_buffer,20);
  160.                 dis_DrawCurve(aun_ir_buffer,0);
  161.                 OLED_Refresh_Gram();//更新显示到OLED         
  162.         }
  163. }

  164. void dis_DrawCurve(u32* data,u8 x)
  165. {
  166.         u16 i;
  167.         u32 max=0,min=262144;
  168.         u32 temp;
  169.         u32 compress;
  170.         
  171.         for(i=0;i<128*2;i++)
  172.         {
  173.                 if(data[i]>max)
  174.                 {
  175.                         max = data[i];
  176.                 }
  177.                 if(data[i]<min)
  178.                 {
  179.                         min = data[i];
  180.                 }
  181.         }
  182.         
  183.         compress = (max-min)/20;
  184.         
  185.         for(i=0;i<128;i++)
  186.         {
  187.                 temp = data[i*2] + data[i*2+1];
  188.                 temp/=2;
  189.                 temp -= min;
  190.                 temp/=compress;
  191.                 if(temp>20)temp=20;
  192.                 OLED_DrawPoint(i,63-x-temp,1);
  193.         }
  194. }
复制代码

所有资料51hei提供下载:
MAX30102资料.7z (1.07 MB, 下载次数: 126)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:946272 发表于 2022-4-19 21:07 | 显示全部楼层
可以看一下实验结果马?数据结果准确吗
回复

使用道具 举报

ID:1013883 发表于 2022-4-20 11:01 | 显示全部楼层
学习一下,谢谢楼主分享,可以直接移植到STM32103的主程序里嘛?
回复

使用道具 举报

ID:1016608 发表于 2022-5-4 22:59 | 显示全部楼层
为什么数据都是-999
回复

使用道具 举报

ID:245053 发表于 2023-1-2 17:07 | 显示全部楼层
hjf123HJF 发表于 2022-5-4 22:59
为什么数据都是-999

程序有问题吗,我已经下载了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表