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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8139|回復: 15
收起左側

STM32單片機+MAX30102心率血氧檢測代碼

  [復制鏈接]
ID:1022289 發(fā)表于 2022-5-15 09:47 | 顯示全部樓層 |閱讀模式
最近在做心率血氧檢測,用的是C8T6最小系統(tǒng)板和MAX30102代碼發(fā)送給大家
STM32F103-30102:
    VCC<->3.3V
    GND<->GND
    SCL<->PB7
    SDA<->PB8
    IM<->PB9
0.96inch OLED :
    VCC<->3.3V
    GND<->GND
    SCL<->PA5
    SDA<->PA6
    RST<->PA3
    DC<->PA4
    CS<->PA2
USB-TTL:
    5V<->5V
    GND<->GND
    RXD<->PA9
    TXD<->PA10
單片機源程序如下:
  1. #include "max30102.h"
  2. #include "myiic.h"
  3. #include "delay.h"

  4. u8 max30102_Bus_Write(u8 Register_Address, u8 Word_Data)
  5. {

  6.         /* 采用串行EEPROM隨即讀取指令序列,連續(xù)讀取若干字節(jié) */

  7.         /* 第1步:發(fā)起I2C總線啟動信號 */
  8.         IIC_Start();

  9.         /* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  10.         IIC_Send_Byte(max30102_WR_address | I2C_WR);        /* 此處是寫指令 */

  11.         /* 第3步:發(fā)送ACK */
  12.         if (IIC_Wait_Ack() != 0)
  13.         {
  14.                 goto cmd_fail;        /* EEPROM器件無應答 */
  15.         }

  16.         /* 第4步:發(fā)送字節(jié)地址 */
  17.         IIC_Send_Byte(Register_Address);
  18.         if (IIC_Wait_Ack() != 0)
  19.         {
  20.                 goto cmd_fail;        /* EEPROM器件無應答 */
  21.         }
  22.         
  23.         /* 第5步:開始寫入數(shù)據(jù) */
  24.         IIC_Send_Byte(Word_Data);

  25.         /* 第6步:發(fā)送ACK */
  26.         if (IIC_Wait_Ack() != 0)
  27.         {
  28.                 goto cmd_fail;        /* EEPROM器件無應答 */
  29.         }

  30.         /* 發(fā)送I2C總線停止信號 */
  31.         IIC_Stop();
  32.         return 1;        /* 執(zhí)行成功 */

  33. cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
  34.         /* 發(fā)送I2C總線停止信號 */
  35.         IIC_Stop();
  36.         return 0;
  37. }



  38. u8 max30102_Bus_Read(u8 Register_Address)
  39. {
  40.         u8  data;


  41.         /* 第1步:發(fā)起I2C總線啟動信號 */
  42.         IIC_Start();

  43.         /* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  44.         IIC_Send_Byte(max30102_WR_address | I2C_WR);        /* 此處是寫指令 */

  45.         /* 第3步:發(fā)送ACK */
  46.         if (IIC_Wait_Ack() != 0)
  47.         {
  48.                 goto cmd_fail;        /* EEPROM器件無應答 */
  49.         }

  50.         /* 第4步:發(fā)送字節(jié)地址, */
  51.         IIC_Send_Byte((uint8_t)Register_Address);
  52.         if (IIC_Wait_Ack() != 0)
  53.         {
  54.                 goto cmd_fail;        /* EEPROM器件無應答 */
  55.         }
  56.         

  57.         /* 第6步:重新啟動I2C總線。下面開始讀取數(shù)據(jù) */
  58.         IIC_Start();

  59.         /* 第7步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  60.         IIC_Send_Byte(max30102_WR_address | I2C_RD);        /* 此處是讀指令 */

  61.         /* 第8步:發(fā)送ACK */
  62.         if (IIC_Wait_Ack() != 0)
  63.         {
  64.                 goto cmd_fail;        /* EEPROM器件無應答 */
  65.         }

  66.         /* 第9步:讀取數(shù)據(jù) */
  67.         {
  68.                 data = IIC_Read_Byte(0);        /* 讀1個字節(jié) */

  69.                 IIC_NAck();        /* 最后1個字節(jié)讀完后,CPU產(chǎn)生NACK信號(驅動SDA = 1) */
  70.         }
  71.         /* 發(fā)送I2C總線停止信號 */
  72.         IIC_Stop();
  73.         return data;        /* 執(zhí)行成功 返回data值 */

  74. cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
  75.         /* 發(fā)送I2C總線停止信號 */
  76.         IIC_Stop();
  77.         return 0;
  78. }


  79. void max30102_FIFO_ReadWords(u8 Register_Address,u16 Word_Data[][2],u8 count)
  80. {
  81.         u8 i=0;
  82.         u8 no = count;
  83.         u8 data1, data2;
  84.         /* 第1步:發(fā)起I2C總線啟動信號 */
  85.         IIC_Start();

  86.         /* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  87.         IIC_Send_Byte(max30102_WR_address | I2C_WR);        /* 此處是寫指令 */

  88.         /* 第3步:發(fā)送ACK */
  89.         if (IIC_Wait_Ack() != 0)
  90.         {
  91.                 goto cmd_fail;        /* EEPROM器件無應答 */
  92.         }

  93.         /* 第4步:發(fā)送字節(jié)地址, */
  94.         IIC_Send_Byte((uint8_t)Register_Address);
  95.         if (IIC_Wait_Ack() != 0)
  96.         {
  97.                 goto cmd_fail;        /* EEPROM器件無應答 */
  98.         }
  99.         

  100.         /* 第6步:重新啟動I2C總線。下面開始讀取數(shù)據(jù) */
  101.         IIC_Start();

  102.         /* 第7步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  103.         IIC_Send_Byte(max30102_WR_address | I2C_RD);        /* 此處是讀指令 */

  104.         /* 第8步:發(fā)送ACK */
  105.         if (IIC_Wait_Ack() != 0)
  106.         {
  107.                 goto cmd_fail;        /* EEPROM器件無應答 */
  108.         }

  109.         /* 第9步:讀取數(shù)據(jù) */
  110.         while (no)
  111.         {
  112.                 data1 = IIC_Read_Byte(0);        
  113.                 IIC_Ack();
  114.                 data2 = IIC_Read_Byte(0);
  115.                 IIC_Ack();
  116.                 Word_Data[i][0] = (((u16)data1 << 8) | data2);  //

  117.                
  118.                 data1 = IIC_Read_Byte(0);        
  119.                 IIC_Ack();
  120.                 data2 = IIC_Read_Byte(0);
  121.                 if(1==no)
  122.                         IIC_NAck();        /* 最后1個字節(jié)讀完后,CPU產(chǎn)生NACK信號(驅動SDA = 1) */
  123.                 else
  124.                         IIC_Ack();
  125.                 Word_Data[i][1] = (((u16)data1 << 8) | data2);

  126.                 no--;        
  127.                 i++;
  128.         }
  129.         /* 發(fā)送I2C總線停止信號 */
  130.         IIC_Stop();

  131. cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
  132.         /* 發(fā)送I2C總線停止信號 */
  133.         IIC_Stop();
  134. }

  135. void max30102_FIFO_ReadBytes(u8 Register_Address,u8* Data)
  136. {        
  137.         max30102_Bus_Read(REG_INTR_STATUS_1);
  138.         max30102_Bus_Read(REG_INTR_STATUS_2);
  139.         
  140.         /* 第1步:發(fā)起I2C總線啟動信號 */
  141.         IIC_Start();

  142.         /* 第2步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  143.         IIC_Send_Byte(max30102_WR_address | I2C_WR);        /* 此處是寫指令 */

  144.         /* 第3步:發(fā)送ACK */
  145.         if (IIC_Wait_Ack() != 0)
  146.         {
  147.                 goto cmd_fail;        /* EEPROM器件無應答 */
  148.         }

  149.         /* 第4步:發(fā)送字節(jié)地址, */
  150.         IIC_Send_Byte((uint8_t)Register_Address);
  151.         if (IIC_Wait_Ack() != 0)
  152.         {
  153.                 goto cmd_fail;        /* EEPROM器件無應答 */
  154.         }
  155.         

  156.         /* 第6步:重新啟動I2C總線。下面開始讀取數(shù)據(jù) */
  157.         IIC_Start();

  158.         /* 第7步:發(fā)起控制字節(jié),高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  159.         IIC_Send_Byte(max30102_WR_address | I2C_RD);        /* 此處是讀指令 */

  160.         /* 第8步:發(fā)送ACK */
  161.         if (IIC_Wait_Ack() != 0)
  162.         {
  163.                 goto cmd_fail;        /* EEPROM器件無應答 */
  164.         }

  165.         /* 第9步:讀取數(shù)據(jù) */
  166.         Data[0] = IIC_Read_Byte(1);        
  167.         Data[1] = IIC_Read_Byte(1);        
  168.         Data[2] = IIC_Read_Byte(1);        
  169.         Data[3] = IIC_Read_Byte(1);
  170.         Data[4] = IIC_Read_Byte(1);        
  171.         Data[5] = IIC_Read_Byte(0);
  172.         /* 最后1個字節(jié)讀完后,CPU產(chǎn)生NACK信號(驅動SDA = 1) */
  173.         /* 發(fā)送I2C總線停止信號 */
  174.         IIC_Stop();

  175. cmd_fail: /* 命令執(zhí)行失敗后,切記發(fā)送停止信號,避免影響I2C總線上其他設備 */
  176.         /* 發(fā)送I2C總線停止信號 */
  177.         IIC_Stop();

  178. //        u8 i;
  179. //        u8 fifo_wr_ptr;
  180. //        u8 firo_rd_ptr;
  181. //        u8 number_tp_read;
  182. //        //Get the FIFO_WR_PTR
  183. //        fifo_wr_ptr = max30102_Bus_Read(REG_FIFO_WR_PTR);
  184. //        //Get the FIFO_RD_PTR
  185. //        firo_rd_ptr = max30102_Bus_Read(REG_FIFO_RD_PTR);
  186. //        
  187. //        number_tp_read = fifo_wr_ptr - firo_rd_ptr;
  188. //        
  189. //        //for(i=0;i<number_tp_read;i++){
  190. //        if(number_tp_read>0){
  191. //                IIC_ReadBytes(max30102_WR_address,REG_FIFO_DATA,Data,6);
  192. //        }
  193.         
  194.         //max30102_Bus_Write(REG_FIFO_RD_PTR,fifo_wr_ptr);
  195. }

  196. void max30102_init(void)
  197. {
  198.         GPIO_InitTypeDef GPIO_InitStructure;

  199.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);        
  200.         GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14;
  201.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  202.          GPIO_Init(GPIOB, &GPIO_InitStructure);
  203.         
  204.         IIC_Init();
  205.         
  206.         max30102_reset();
  207.         
  208. //        max30102_Bus_Write(REG_MODE_CONFIG, 0x0b);  //mode configuration : temp_en[3]      MODE[2:0]=010 HR only enabled    011 SP02 enabled
  209. //        max30102_Bus_Write(REG_INTR_STATUS_2, 0xF0); //open all of interrupt
  210. //        max30102_Bus_Write(REG_INTR_STATUS_1, 0x00); //all interrupt clear
  211. //        max30102_Bus_Write(REG_INTR_ENABLE_2, 0x02); //DIE_TEMP_RDY_EN
  212. //        max30102_Bus_Write(REG_TEMP_CONFIG, 0x01); //SET   TEMP_EN

  213. //        max30102_Bus_Write(REG_SPO2_CONFIG, 0x47); //SPO2_SR[4:2]=001  100 per second    LED_PW[1:0]=11  16BITS

  214. //        max30102_Bus_Write(REG_LED1_PA, 0x47);
  215. //        max30102_Bus_Write(REG_LED2_PA, 0x47);
  216.         
  217.         
  218.         
  219.         max30102_Bus_Write(REG_INTR_ENABLE_1,0xc0);        // INTR setting
  220.         max30102_Bus_Write(REG_INTR_ENABLE_2,0x00);
  221.         max30102_Bus_Write(REG_FIFO_WR_PTR,0x00);          //FIFO_WR_PTR[4:0]
  222.         max30102_Bus_Write(REG_OVF_COUNTER,0x00);          //OVF_COUNTER[4:0]
  223.         max30102_Bus_Write(REG_FIFO_RD_PTR,0x00);          //FIFO_RD_PTR[4:0]
  224.         max30102_Bus_Write(REG_FIFO_CONFIG,0x0f);          //sample avg = 1, fifo rollover=false, fifo almost full = 17
  225.         max30102_Bus_Write(REG_MODE_CONFIG,0x03);          //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
  226.         max30102_Bus_Write(REG_SPO2_CONFIG,0x27);          // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)  
  227.         max30102_Bus_Write(REG_LED1_PA,0x24);           //Choose value for ~ 7mA for LED1
  228.         max30102_Bus_Write(REG_LED2_PA,0x24);           // Choose value for ~ 7mA for LED2
  229.         max30102_Bus_Write(REG_PILOT_PA,0x7f);           // Choose value for ~ 25mA for Pilot LED


  230.         
  231. //        // Interrupt Enable 1 Register. Set PPG_RDY_EN (data available in FIFO)
  232. //        max30102_Bus_Write(0x2, 1<<6);

  233. //        // FIFO configuration register
  234. //        // SMP_AVE: 16 samples averaged per FIFO sample
  235. //        // FIFO_ROLLOVER_EN=1
  236. //        //max30102_Bus_Write(0x8,  1<<4);
  237. //        max30102_Bus_Write(0x8, (0<<5) | 1<<4);

  238. //        // Mode Configuration Register
  239. //        // SPO2 mode
  240. //        max30102_Bus_Write(0x9, 3);

  241. //        // SPO2 Configuration Register
  242. //        max30102_Bus_Write(0xa,
  243. //                        (3<<5)  // SPO2_ADC_RGE 2 = full scale 8192 nA (LSB size 31.25pA); 3 = 16384nA
  244. //                        | (1<<2) // sample rate: 0 = 50sps; 1 = 100sps; 2 = 200sps
  245. //                        | (3<<0) // LED_PW 3 = 411μs, ADC resolution 18 bits
  246. //        );

  247. //        // LED1 (red) power (0 = 0mA; 255 = 50mA)
  248. //        max30102_Bus_Write(0xc, 0xb0);

  249. //        // LED (IR) power
  250. //        max30102_Bus_Write(0xd, 0xa0);
  251.                                                                                        
  252. }

  253. void max30102_reset(void)
  254. {
  255.         max30102_Bus_Write(REG_MODE_CONFIG,0x40);
  256.         max30102_Bus_Write(REG_MODE_CONFIG,0x40);
  257. }






  258. void maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
  259. {
  260. //  char ach_i2c_data[2];
  261. //  ach_i2c_data[0]=uch_addr;
  262. //  ach_i2c_data[1]=uch_data;
  263. //        
  264. //  IIC_WriteBytes(I2C_WRITE_ADDR, ach_i2c_data, 2);
  265.         IIC_Write_One_Byte(I2C_WRITE_ADDR,uch_addr,uch_data);
  266. }

  267. void maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
  268. {
  269. //  char ch_i2c_data;
  270. //  ch_i2c_data=uch_addr;
  271. //  IIC_WriteBytes(I2C_WRITE_ADDR, &ch_i2c_data, 1);
  272. //        
  273. //  i2c.read(I2C_READ_ADDR, &ch_i2c_data, 1);
  274. //  
  275. //   *puch_data=(uint8_t) ch_i2c_data;
  276.         IIC_Read_One_Byte(I2C_WRITE_ADDR,uch_addr,puch_data);
  277. }

  278. void maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
  279. {
  280.         uint32_t un_temp;
  281.         unsigned char uch_temp;
  282.         char ach_i2c_data[6];
  283.         *pun_red_led=0;
  284.         *pun_ir_led=0;

  285.   
  286.   //read and clear status register
  287.   maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
  288.   maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
  289.   
  290.   IIC_ReadBytes(I2C_WRITE_ADDR,REG_FIFO_DATA,(u8 *)ach_i2c_data,6);
  291.   
  292.   un_temp=(unsigned char) ach_i2c_data[0];
  293.   un_temp<<=16;
  294.   *pun_red_led+=un_temp;
  295.   un_temp=(unsigned char) ach_i2c_data[1];
  296.   un_temp<<=8;
  297.   *pun_red_led+=un_temp;
  298.   un_temp=(unsigned char) ach_i2c_data[2];
  299.   *pun_red_led+=un_temp;
  300.   
  301.   un_temp=(unsigned char) ach_i2c_data[3];
  302.   un_temp<<=16;
  303.   *pun_ir_led+=un_temp;
  304.   un_temp=(unsigned char) ach_i2c_data[4];
  305.   un_temp<<=8;
  306.   *pun_ir_led+=un_temp;
  307.   un_temp=(unsigned char) ach_i2c_data[5];
  308.   *pun_ir_led+=un_temp;
  309.   *pun_red_led&=0x03FFFF;  //Mask MSB [23:18]
  310.   *pun_ir_led&=0x03FFFF;  //Mask MSB [23:18]
  311. }
復制代碼

Keil5代碼下載:
代碼.7z (214.85 KB, 下載次數(shù): 287)

評分

參與人數(shù) 2威望 +15 黑幣 +80 收起 理由
wpppmlah + 15 + 30 共享資料的黑幣獎勵!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:1039983 發(fā)表于 2022-8-19 17:09 | 顯示全部樓層
7針OLED怎么改4針OLED啊
回復

使用道具 舉報

ID:1043634 發(fā)表于 2022-10-13 16:44 | 顯示全部樓層
這么好的帖子,必須頂起,支持樓主
回復

使用道具 舉報

ID:1043634 發(fā)表于 2022-10-30 15:16 | 顯示全部樓層
這么好的帖子,必須頂起,支持樓主
回復

使用道具 舉報

ID:875451 發(fā)表于 2023-2-3 17:30 | 顯示全部樓層
這個可以下載進C8T6嗎
回復

使用道具 舉報

ID:504443 發(fā)表于 2023-3-8 07:38 | 顯示全部樓層
請問定義的IM是接哪個引腳?
回復

使用道具 舉報

ID:291668 發(fā)表于 2023-3-8 13:34 | 顯示全部樓層
辛苦了。頂起
回復

使用道具 舉報

ID:940352 發(fā)表于 2023-3-13 13:13 | 顯示全部樓層
移植完成后 不出現(xiàn)心率值 一直顯示----- 的原因是什么 求解
回復

使用道具 舉報

ID:1069607 發(fā)表于 2023-4-3 10:13 | 顯示全部樓層
請問這個代碼下載了是不是直接能用了?
回復

使用道具 舉報

ID:1069607 發(fā)表于 2023-4-3 12:26 | 顯示全部樓層
543545 發(fā)表于 2022-8-19 17:09
7針OLED怎么改4針OLED啊

請問解決了嗎
回復

使用道具 舉報

ID:291668 發(fā)表于 2023-4-3 13:51 | 顯示全部樓層
好東西,頂起,太有幫助了
回復

使用道具 舉報

ID:1073560 發(fā)表于 2023-4-25 14:48 來自手機 | 顯示全部樓層
請問有proteus仿真電路圖嗎?
回復

使用道具 舉報

ID:948914 發(fā)表于 2023-5-4 10:01 | 顯示全部樓層
543545 發(fā)表于 2022-8-19 17:09
7針OLED怎么改4針OLED啊

好xd,改成功了么
回復

使用道具 舉報

ID:1074282 發(fā)表于 2023-5-10 14:22 | 顯示全部樓層
悟道劍 發(fā)表于 2023-3-13 13:13
移植完成后 不出現(xiàn)心率值 一直顯示----- 的原因是什么 求解

我也是一致顯示----,兄弟解決了嗎
回復

使用道具 舉報

ID:1073980 發(fā)表于 2023-11-22 14:24 | 顯示全部樓層
帶顯示器嗎
回復

使用道具 舉報

ID:1106925 發(fā)表于 2023-12-29 11:05 | 顯示全部樓層
IM到底是什么引腳??
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级在线观看 | 91 在线| 日本在线黄色 | 91久久久久 | 在线日韩中文字幕 | 欧美极品少妇xxxxⅹ免费视频 | 91精品国产高清久久久久久久久 | 男女免费在线观看视频 | 欧美一区二区三区在线观看视频 | 精品二区视频 | 青青草一区二区 | 三级视频在线观看电影 | 精品视频在线免费观看 | 成人国产精品免费观看 | 在线观看av中文字幕 | 天天色综网 | 欧美三级电影在线播放 | 在线播放一区二区三区 | 四虎伊人 | 亚洲欧洲日韩精品 中文字幕 | 精品国产不卡一区二区三区 | 午夜男人的天堂 | 国产免费视频 | av资源中文在线 | 精品国产一区久久 | 激情av | 国产伦精品一区二区三区在线 | 精品国产乱码一区二区三 | 91精品国产自产精品男人的天堂 | 亚洲av毛片 | 亚洲精品一区二区三区中文字幕 | 色综合久久久 | 在线视频亚洲 | 久久久一区二区三区 | 高清亚洲 | 黄网站免费在线 | 欧美一级三级在线观看 | 国产精品a久久久久 | 99免费 | 日韩av在线中文字幕 | 精品久久久久一区二区国产 |