久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1672|回復: 0
打印 上一主題 下一主題
收起左側

STM32F103單片機使用MAX30102測量心率血氧源程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:910507 發表于 2024-4-28 10:15 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機源程序如下:
  1. #include "stm32f10x.h"                  // Device header
  2. #include "software_IIC.h"
  3. #include "MAX30102.h"
  4. #include "MAX30102_algorithm.h"
  5. #include "OLED.h"
  6. #include "Key.h"
  7. #include "Delay.h"
  8. #define MAX_BRIGHTNESS 255

  9. uint16_t fifo_red;
  10. uint16_t fifo_ir;



  11. void MAX30102_Init(void)
  12. {
  13.         IIC_GPIO_Init();                                                                        //先初始化底層的I2C
  14.        
  15.         /*MAX30102寄存器初始化,需要對照MAX30102手冊的寄存器描述配置,此處僅配置了部分重要的寄存器*/
  16.         IIC_WriteReg(MAX30102_ADDRESS,REG_MODE_CONFIG, 0x40);   //將RESET位設置為1,所有配置、閾值和數據寄存器通過上電復位復位復位到其上電狀態。
  17.         IIC_WriteReg(MAX30102_ADDRESS,REG_INTR_ENABLE_1, 0x00);        //不使用中斷       
  18.         IIC_WriteReg(MAX30102_ADDRESS,REG_INTR_ENABLE_2, 0x00);               
  19.         IIC_WriteReg(MAX30102_ADDRESS,REG_FIFO_WR_PTR,0x00);        //FIFO寫入指針為0               
  20.         IIC_WriteReg(MAX30102_ADDRESS,REG_OVF_COUNTER,0x00);    //溢出數據計數器為0
  21.         IIC_WriteReg(MAX30102_ADDRESS,REG_FIFO_RD_PTR,0x00);    //FIFO讀取指針為0
  22.         IIC_WriteReg(MAX30102_ADDRESS,REG_FIFO_CONFIG,0x0f);    //0x0f設置平均取樣為4,當FIFO完全充滿數據時,FIFO地址滾動到零并且FIFO繼續填充新數據。
  23.         IIC_WriteReg(MAX30102_ADDRESS,REG_MODE_CONFIG,0x03);    //SpO2模式
  24.         IIC_WriteReg(MAX30102_ADDRESS,REG_SPO2_CONFIG,0x27);    //0x45ADC量程為8192,采樣率為100/s,LED占空比118us,對應采樣精度16bit
  25.         IIC_WriteReg(MAX30102_ADDRESS,REG_LED1_PA,0x20);
  26.         IIC_WriteReg(MAX30102_ADDRESS,REG_LED2_PA,0x20);
  27.         IIC_WriteReg(MAX30102_ADDRESS,REG_PILOT_PA,0x7F);
  28.                
  29. }

  30. void MAX30102_IIC_ReadReg(uint8_t slave_ID,uint8_t RegAddress)  //讀取6個字節
  31. {
  32.     fifo_red=0;
  33.     fifo_ir=0;
  34.         uint16_t Data1,Data2,Data3,Data4,Data5,Data6;
  35.        
  36.         IIC_Start();                                                //I2C起始
  37.         IIC_SendByte(slave_ID);        //發送從機地址,讀寫位為0,表示即將寫入
  38.         IIC_ReceiveAck();                                        //接收應答
  39.         IIC_SendByte(RegAddress);                        //發送寄存器地址
  40.         IIC_ReceiveAck();                                        //接收應答
  41.        
  42.         IIC_Start();                                                //I2C重復起始
  43.         IIC_SendByte(slave_ID | 0x01);        //發送從機地址,讀寫位為1,表示即將讀取
  44.         IIC_ReceiveAck();                                        //接收應答
  45.         Data1 = IIC_ReceiveByte();                        //接收指定寄存器的數據
  46.         IIC_SendAck(0);                                        //發送應答,給從機非應答,終止從機的數據輸出
  47.         Data2 = IIC_ReceiveByte();
  48.         IIC_SendAck(0);       
  49.         Data3 = IIC_ReceiveByte();
  50.         IIC_SendAck(0);
  51.         Data4 = IIC_ReceiveByte();                        //接收指定寄存器的數據
  52.         IIC_SendAck(0);                                        //發送應答,給從機非應答,終止從機的數據輸出
  53.         Data5 = IIC_ReceiveByte();
  54.         IIC_SendAck(0);       
  55.         Data6 = IIC_ReceiveByte();
  56.         IIC_SendAck(1);
  57.         IIC_Stop();       
  58.         //I2C終止
  59.         Data1 <<= 14;
  60.     fifo_red+=Data1;
  61.         Data2 <<= 6;
  62.     fifo_red+=Data2;
  63.         Data3 >>= 2;
  64.     fifo_red+=Data3;
  65.        
  66.         Data4 <<= 14;
  67.     fifo_ir+=Data4;
  68.         Data5 <<= 6;
  69.     fifo_ir+=Data5;
  70.         Data6 >>= 2;
  71.     fifo_ir+=Data6;
  72.        
  73.         if(fifo_ir<=10000)
  74.         {
  75.                 fifo_ir=0;
  76.         }
  77.         if(fifo_red<=10000)
  78.         {
  79.                 fifo_red=0;
  80.         }
  81. }

  82. int8_t menu_Back_event(void)//菜單返回
  83. {
  84.         return Key_Back_Get();;                                //返回鍵接到PA2;
  85. }

  86. void SPO2_function(void)
  87. {
  88.        
  89.         OLED_Clear();
  90.         OLED_ShowChinese(46,0,"血");
  91.         OLED_ShowChinese(62,0,"氧");
  92.         OLED_ShowChinese(78,0,"檢");
  93.         OLED_ShowChinese(94,0,"測");
  94.         MAX30102_Init();                     //初始化MAX30102
  95.         OLED_ShowImage(0,0,22,8,qipaoup);    //顯示左上方固定的石頭塊
  96.         OLED_ShowImage(0,56,22,8,qipaodown); //顯示左下方固定的石頭塊
  97.         OLED_Update();
  98.         uint8_t j=128;                       //定義魚的起始X坐標
  99.         uint8_t ave_Count = 1;               //為了獲取10個最終得到的血氧值,設置計數器,(可以更改,值越大測量時間越長,獲取數據越多)
  100.         uint16_t cal_ave[10];                //定義長度為10的數組存儲10個檢測數據
  101.         uint16_t ave_Sum = 0;                //存儲10個數據的和
  102.         uint8_t cal_Sum_lock = 0;            //總和計算器鎖
  103.     while(1)
  104.    {
  105.                         /*-------------------------移動氣泡的程序邏輯------------------------------*/
  106.                 uint8_t i;
  107.                 for(i = 0;i <= 16;i++)
  108.                 {
  109.                         OLED_ClearArea(0,8,22,48);
  110.                         OLED_ShowImage(1,49-i,7,7,qipao);   
  111.                         OLED_ShowImage(1,33-i,7,7,qipao);
  112.         if(i<17)
  113.                 {
  114.                         OLED_ShowImage(1,17-i,7,7,qipao);
  115.                         OLED_ShowImage(0,0,22,8,qipaoup);
  116.                 }       
  117.                         OLED_ShowImage(13,56-i,7,7,qipao);
  118.                         OLED_ShowImage(13,40-i,7,7,qipao);
  119.                         OLED_ShowImage(13,24-i,7,7,qipao);
  120.                 /*-------------------------移動魚的程序邏輯------------------------------*/
  121.                 if(j<=0)
  122.                 {
  123.                         j = 128;
  124.                         OLED_ClearArea(22,49,106,15);    //清除小魚游過后的全屏尾跡
  125.                 }
  126.                         OLED_ShowImage(j,49,15,15,Fish);
  127.                         OLED_ClearArea(j+15,49,106,15);    //解除注釋可以實時清除小魚尾跡
  128.                         OLED_ShowImage(0,56,22,8,qipaodown); //刷新左下角石頭塊,讓小魚從石頭快后邊游過,注釋后會從石頭塊前方游過
  129.                         j--;
  130.                         Delay_ms(5);        //控制動畫移動速度
  131.                         OLED_Update();
  132.                 }
  133.                 if(ave_Count<=10)
  134.                 {
  135.                     blood_Loop();
  136.                         if(SPO2dataResult != 0)
  137.             {
  138.                         OLED_ClearArea(22,16,106,32);
  139.                         OLED_ShowChinese(54,17,"檢");
  140.                 OLED_ShowChinese(70,17,"測");
  141.                     OLED_ShowChinese(86,17,"中");                               
  142.                         cal_ave[ave_Count-1] = SPO2dataResult;
  143.                         ave_Count++;
  144.                         }else{
  145.                                     OLED_ClearArea(22,16,106,32);
  146.                                     OLED_ShowChinese(54,16,"請");
  147.                             OLED_ShowChinese(70,16,"正");
  148.                             OLED_ShowChinese(86,16,"確");
  149.                             OLED_ShowChinese(54,32,"佩");
  150.                             OLED_ShowChinese(70,32,"戴");
  151.                             OLED_ShowChar(90,32,'!',OLED_8X16);
  152.                              }
  153.                 }else
  154.                 {
  155.                     ave_Count = 11;   //得到10個數據后將計數器值固定到11防止溢出
  156.                         uint8_t i;
  157.                         uint16_t min;
  158.                         for(i = 0;i<9;i++)                   //取出最小值
  159.                         {
  160.                                 if(i == 0){min = cal_ave[0];}    //
  161.                           if(cal_ave[i+1]<min)
  162.                           {
  163.                           min = cal_ave[i+1];
  164.                           }
  165.                         }
  166.                         if(cal_Sum_lock == 0)
  167.                         {
  168.                                  for(i = 0;i<10;i++)
  169.                                  {
  170.                                       ave_Sum += cal_ave[i];    //計算0個數據的和
  171.                                  }  
  172.                                          cal_Sum_lock = 1;          //和計算一次后打開鎖,防止多次累加
  173.                     }
  174.                         OLED_ClearArea(22,17,106,32);
  175.                         OLED_ShowNum(49,17,(ave_Sum-min)/9 + 3,3,OLED_15X24);  //顯示最終結果
  176.                         OLED_ShowChar(96,17,0x3A,OLED_15X24);
  177.                 }
  178.             
  179.                 if(menu_Back_event())   //檢測按鍵按下
  180.         {
  181.                         break;
  182.                 }       
  183.    }
  184. }

  185. void Heart_function(void)
  186. {
  187.        
  188.         OLED_Clear();
  189.         OLED_ShowChinese(32,0,"心");
  190.         OLED_ShowChinese(48,0,"率");
  191.         OLED_ShowChinese(64,0,"檢");
  192.         OLED_ShowChinese(80,0,"測");
  193.         OLED_Update();
  194.         MAX30102_Init();
  195.        
  196.         uint8_t ave_Count = 1;               //為了獲取10個最終得到的心率,設置計數器
  197.         uint16_t cal_ave[10];                //定義長度為10的數組存儲測量的10個心率數據
  198.         uint16_t ave_Sum = 0;                //存儲10個數據的和
  199.         uint8_t cal_Sum_lock = 0;            //總和計算器鎖
  200.         while(1)
  201.         {
  202.                 OLED_ClearArea(0,20,64,44);
  203.                 OLED_ShowImage(0,20,54,49,Heart1);
  204.                 OLED_Update();
  205.                 Delay_ms(10);
  206.                 OLED_ClearArea(0,20,64,44);
  207.                 OLED_ShowImage(0,20,54,49,Heart2);
  208.                 OLED_Update();
  209.                 Delay_ms(10);
  210.                 OLED_ClearArea(0,20,64,44);
  211.                 OLED_ShowImage(0,20,54,49,Heart3);
  212.                 OLED_Update();
  213.                 Delay_ms(10);
  214.                 OLED_ClearArea(0,20,64,44);
  215.                 OLED_ShowImage(0,20,54,49,Heart4);
  216.                 OLED_Update();
  217.                 Delay_ms(10);
  218.                 OLED_ClearArea(0,20,64,44);
  219.                 OLED_ShowImage(0,20,54,49,Heart5);
  220.                 OLED_Update();
  221.                 Delay_ms(10);
  222.                 OLED_ClearArea(0,20,64,44);
  223.                 OLED_ShowImage(0,20,54,49,Heart6);
  224.                 OLED_Update();
  225.                 Delay_ms(10);
  226.                 OLED_ClearArea(0,20,64,44);
  227.                 OLED_ShowImage(0,20,54,49,Heart7);
  228.                 OLED_Update();
  229.                 Delay_ms(10);
  230.                 OLED_ClearArea(0,20,64,44);
  231.                 OLED_ShowImage(0,20,54,49,Heart8);
  232.                 OLED_Update();
  233.                 Delay_ms(10);
  234.                 OLED_ClearArea(0,20,64,44);
  235.                 OLED_ShowImage(0,20,54,49,Heart7);
  236.                 OLED_Update();
  237.                 Delay_ms(10);
  238.                 OLED_ClearArea(0,20,64,44);
  239.                 OLED_ShowImage(0,20,54,49,Heart6);
  240.                 OLED_Update();
  241.                 Delay_ms(10);
  242.                 OLED_ClearArea(0,20,64,44);
  243.                 OLED_ShowImage(0,20,54,49,Heart5);
  244.                 OLED_Update();
  245.                 Delay_ms(10);
  246.                 OLED_ClearArea(0,20,64,44);
  247.                 OLED_ShowImage(0,20,54,49,Heart4);
  248.                 OLED_Update();
  249.                 Delay_ms(10);
  250.                 OLED_ClearArea(0,20,64,44);
  251.                 OLED_ShowImage(0,20,54,49,Heart3);
  252.                 OLED_Update();
  253.                 Delay_ms(10);
  254.                 OLED_ClearArea(0,20,64,44);
  255.                 OLED_ShowImage(0,20,54,49,Heart2);
  256.                 OLED_Update();
  257.                 Delay_ms(10);
  258.                 OLED_ClearArea(0,20,64,44);
  259.                 OLED_ShowImage(0,20,54,49,Heart1);
  260.                 OLED_Update();
  261.                 //blood_Loop();
  262.                 OLED_ClearArea(64,20,64,44);
  263.         if(ave_Count<=10)
  264.                 {
  265.                     blood_Loop();
  266.                         if(SPO2dataResult != 0)
  267.             {
  268.                         OLED_ClearArea(64,16,64,44);
  269.                         OLED_ShowChinese(64,17,"測");
  270.                 OLED_ShowChinese(80,17,"量");
  271.                     OLED_ShowChinese(96,17,"中");
  272.             //OLED_ShowNum(64,17,HeartdataResult,3,OLED_13X24);                               
  273.                         cal_ave[ave_Count-1] = HeartdataResult;
  274.                         ave_Count++;
  275.                         }
  276.                         else
  277.                         {
  278.                                     OLED_ClearArea(64,16,64,44);
  279.                                     OLED_ShowChinese(64,16,"請");
  280.                             OLED_ShowChinese(80,16,"正");
  281.                             OLED_ShowChinese(96,16,"確");
  282.                             OLED_ShowChinese(64,32,"佩");
  283.                             OLED_ShowChinese(80,32,"戴");
  284.                             OLED_ShowChar(100,32,'!',OLED_8X16);
  285.                          }
  286.                 }
  287.                 else
  288.                 {
  289.                     ave_Count = 11;   //得到10個數據后將計數器固定到11防止溢出
  290.                         uint8_t i;
  291.                         uint16_t max;
  292.                         for(i = 0;i<9;i++)                   //取出最大值
  293.                         {
  294.                                 if(i == 0){max = cal_ave[0];}    //
  295.                           if(cal_ave[i+1]>max)
  296.                           {
  297.                           max = cal_ave[i+1];
  298.                           }
  299.                         }
  300.                         if(cal_Sum_lock == 0)
  301.                         {
  302.                                  for(i = 0;i<10;i++)
  303.                                  {
  304.                                       ave_Sum += cal_ave[i];    //計算10個數據的和
  305.                                  }  
  306.                                          cal_Sum_lock = 1;          //和計算一次后打開鎖,防止多次計算
  307.                     }
  308.                         OLED_ClearArea(22,17,106,32);
  309.                         OLED_ShowNum(64,17,(ave_Sum-max)/9,3,OLED_15X24);  //顯示最終結果
  310.                         Delay_ms(200);
  311.       }
  312.                 if(menu_Back_event())   //檢測按鍵按下
  313.         {
  314.                  break;
  315.                 }
  316.     }
  317. }
復制代碼

原理圖: 無
仿真: 無
代碼: 心率血氧檢測.7z (198.14 KB, 下載次數: 30)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 贊一個!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品美女在线观看视频在线观看 | 中文字幕视频免费 | 免费精品 | 国产在线精品一区二区三区 | 久久久999免费视频 999久久久久久久久6666 | 亚洲色在线视频 | 伊人网伊人网 | 精品videossex高潮汇编 | 成年人免费在线视频 | 性国产丰满麻豆videosex | 琪琪午夜伦伦电影福利片 | 一级片在线免费播放 | 日日夜夜精品视频 | 国产精品久久久久久久久久免费看 | 国产丝袜一区二区三区免费视频 | 欧美精品国产精品 | 欧美日韩国产在线观看 | www成人免费视频 | 久久精品亚洲 | 91精品国产综合久久久久久 | 日韩精品一区二区三区免费视频 | 日韩在线看片 | 久久一区精品 | 夜夜久久 | 四虎影视1304t| 99精品99 | 日韩欧美国产成人一区二区 | 国产视频观看 | 日韩免费视频一区二区 | 精品免费国产一区二区三区四区介绍 | 亚洲 成人 av | 国产高清在线精品一区二区三区 | 欧美二区三区 | 久久久久久久国产精品视频 | 99re在线免费视频 | 久久免费精品视频 | 欧美一区二区小视频 | 中文字幕在线免费观看 | 亚洲一区二区在线视频 | 在线免费观看a级片 | 国内久久|