找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19316|回复: 20
收起左侧

MAX30102+stm32测心率血氧源码

  [复制链接]
ID:309165 发表于 2018-4-16 12:55 | 显示全部楼层 |阅读模式
MAX30102+stm32测心率血氧

只留下MAX30102、main、I2C、算法、四个文件就行,在I2C中改一下IO


单片机源程序如下:
  1. /** \file max30102.cpp ******************************************************
  2. *
  3. * Project: MAXREFDES117#
  4. * Filename: max30102.cpp
  5. * Description: This module is an embedded controller driver for the MAX30102
  6. *
  7. * Revision History:
  8. *\n 1-18-2016 Rev 01.00 GL Initial release.
  9. *\n
  10. */

  11. #include "max30102.h"
  12. #include "myiic.h"

  13. #define max30102_WR_address 0xAE
  14. bool maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
  15. /**
  16. * \brief        Write a value to a MAX30102 register
  17. * \par          Details
  18. *               This function writes a value to a MAX30102 register
  19. *
  20. * \param[in]    uch_addr    - register address
  21. * \param[in]    uch_data    - register data
  22. *
  23. * \retval       true on success
  24. */
  25. {
  26.     /* 第1步:发起I2C总线启动信号 */
  27.     i2c_Start();

  28.     /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
  29.     i2c_SendByte(max30102_WR_address | I2C_WR);        /* 此处是写指令 */

  30.     /* 第3步:发送ACK */
  31.     if (i2c_WaitAck() != 0)
  32.     {
  33.         goto cmd_fail;        /* EEPROM器件无应答 */
  34.     }

  35.     /* 第4步:发送字节地址 */
  36.     i2c_SendByte(uch_addr);
  37.     if (i2c_WaitAck() != 0)
  38.     {
  39.         goto cmd_fail;        /* EEPROM器件无应答 */
  40.     }

  41.     /* 第5步:开始写入数据 */
  42.     i2c_SendByte(uch_data);

  43.     /* 第6步:发送ACK */
  44.     if (i2c_WaitAck() != 0)
  45.     {
  46.         goto cmd_fail;        /* EEPROM器件无应答 */
  47.     }

  48.     /* 发送I2C总线停止信号 */
  49.     i2c_Stop();
  50.     return true;        /* 执行成功 */

  51. cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
  52.     /* 发送I2C总线停止信号 */
  53.     i2c_Stop();
  54.     return false;
  55. }

  56. bool maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
  57. /**
  58. * \brief        Read a MAX30102 register
  59. * \par          Details
  60. *               This function reads a MAX30102 register
  61. *
  62. * \param[in]    uch_addr    - register address
  63. * \param[out]   puch_data    - pointer that stores the register data
  64. *
  65. * \retval       true on success
  66. */
  67. {
  68.     /* 第1步:发起I2C总线启动信号 */
  69.     i2c_Start();

  70.     /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
  71.     i2c_SendByte(max30102_WR_address | I2C_WR);        /* 此处是写指令 */

  72.     /* 第3步:发送ACK */
  73.     if (i2c_WaitAck() != 0)
  74.     {
  75.         goto cmd_fail;        /* EEPROM器件无应答 */
  76.     }

  77.     /* 第4步:发送字节地址, */
  78.     i2c_SendByte((uint8_t)uch_addr);
  79.     if (i2c_WaitAck() != 0)
  80.     {
  81.         goto cmd_fail;        /* EEPROM器件无应答 */
  82.     }


  83.     /* 第6步:重新启动I2C总线。下面开始读取数据 */
  84.     i2c_Start();

  85.     /* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
  86.     i2c_SendByte(max30102_WR_address | I2C_RD);        /* 此处是读指令 */

  87.     /* 第8步:发送ACK */
  88.     if (i2c_WaitAck() != 0)
  89.     {
  90.         goto cmd_fail;        /* EEPROM器件无应答 */
  91.     }

  92.     /* 第9步:读取数据 */
  93.     {
  94.         *puch_data = i2c_ReadByte();        /* 读1个字节 */

  95.         i2c_NAck();        /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
  96.     }
  97.     /* 发送I2C总线停止信号 */
  98.     i2c_Stop();
  99.     return true;        /* 执行成功 返回data值 */

  100. cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
  101.     /* 发送I2C总线停止信号 */
  102.     i2c_Stop();
  103.     return false;
  104. }

  105. bool maxim_max30102_init(void)
  106. /**
  107. * \brief        Initialize the MAX30102
  108. * \par          Details
  109. *               This function initializes the MAX30102
  110. *
  111. * \param        None
  112. *
  113. * \retval       true on success
  114. */
  115. {
  116.     if(!maxim_max30102_write_reg(REG_INTR_ENABLE_1, 0xc0)) // INTR setting
  117.         return false;
  118.     if(!maxim_max30102_write_reg(REG_INTR_ENABLE_2, 0x00))
  119.         return false;
  120.     if(!maxim_max30102_write_reg(REG_FIFO_WR_PTR, 0x00)) //FIFO_WR_PTR[4:0]
  121.         return false;
  122.     if(!maxim_max30102_write_reg(REG_OVF_COUNTER, 0x00)) //OVF_COUNTER[4:0]
  123.         return false;
  124.     if(!maxim_max30102_write_reg(REG_FIFO_RD_PTR, 0x00)) //FIFO_RD_PTR[4:0]
  125.         return false;
  126.     if(!maxim_max30102_write_reg(REG_FIFO_CONFIG, 0x6f)) //sample avg = 8, fifo rollover=false, fifo almost full = 17
  127.         return false;
  128.     if(!maxim_max30102_write_reg(REG_MODE_CONFIG, 0x03))  //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
  129.         return false;
  130.     if(!maxim_max30102_write_reg(REG_SPO2_CONFIG, 0x2F)) // SPO2_ADC range = 4096nA, SPO2 sample rate (400 Hz), LED pulseWidth (411uS)
  131.         return false;

  132.     if(!maxim_max30102_write_reg(REG_LED1_PA, 0x17))  //Choose value for ~ 4.5mA for LED1
  133.         return false;
  134.     if(!maxim_max30102_write_reg(REG_LED2_PA, 0x17))  // Choose value for ~ 4.5mA for LED2
  135.         return false;
  136.     if(!maxim_max30102_write_reg(REG_PILOT_PA, 0x7f))  // Choose value for ~ 25mA for Pilot LED
  137.         return false;
  138.     return true;
  139. }

  140. bool maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)

  141. /**
  142. * \brief        Read a set of samples from the MAX30102 FIFO register
  143. * \par          Details
  144. *               This function reads a set of samples from the MAX30102 FIFO register
  145. *
  146. * \param[out]   *pun_red_led   - pointer that stores the red LED reading data
  147. * \param[out]   *pun_ir_led    - pointer that stores the IR LED reading data
  148. *
  149. * \retval       true on success
  150. */
  151. {
  152.     uint32_t un_temp;
  153.     uint8_t uch_temp;
  154.     *pun_ir_led = 0;
  155.     *pun_red_led = 0;
  156.     maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
  157.     maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);



  158.     /* 第1步:发起I2C总线启动信号 */
  159.     i2c_Start();

  160.     /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
  161.     i2c_SendByte(max30102_WR_address | I2C_WR);        /* 此处是写指令 */

  162.     /* 第3步:发送ACK */
  163.     if (i2c_WaitAck() != 0)
  164.     {
  165.         printf("read fifo failed");
  166.         goto cmd_fail;        /* EEPROM器件无应答 */
  167.     }

  168.     /* 第4步:发送字节地址, */
  169.     i2c_SendByte((uint8_t)REG_FIFO_DATA);
  170.     if (i2c_WaitAck() != 0)
  171.     {
  172.         goto cmd_fail;        /* EEPROM器件无应答 */
  173.     }


  174.     /* 第6步:重新启动I2C总线。下面开始读取数据 */
  175.     i2c_Start();

  176.     /* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
  177.     i2c_SendByte(max30102_WR_address | I2C_RD);        /* 此处是读指令 */

  178.     /* 第8步:发送ACK */
  179.     if (i2c_WaitAck() != 0)
  180.     {
  181.         goto cmd_fail;        /* EEPROM器件无应答 */
  182.     }

  183.     un_temp = i2c_ReadByte();
  184.     i2c_Ack();
  185.     un_temp <<= 16;
  186.     *pun_red_led += un_temp;
  187.     un_temp = i2c_ReadByte();
  188.     i2c_Ack();
  189.     un_temp <<= 8;
  190.     *pun_red_led += un_temp;
  191.     un_temp = i2c_ReadByte();
  192.     i2c_Ack();
  193.     *pun_red_led += un_temp;

  194.     un_temp = i2c_ReadByte();
  195.     i2c_Ack();
  196.     un_temp <<= 16;
  197.     *pun_ir_led += un_temp;
  198.     un_temp = i2c_ReadByte();
  199.     i2c_Ack();
  200.     un_temp <<= 8;
  201.     *pun_ir_led += un_temp;
  202.     un_temp = i2c_ReadByte();
  203.     i2c_Ack();
  204.     *pun_ir_led += un_temp;
  205. ……………………

  206. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
stm32 max30102上传整数型数据.zip (366.15 KB, 下载次数: 815)

评分

参与人数 2黑币 +51 收起 理由
if巴黎不缺氧 + 1 共享资料的黑币奖励!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:313983 发表于 2018-5-10 21:23 | 显示全部楼层
全是导航车?,用导航车的文件改的吗?
回复

使用道具 举报

ID:404915 发表于 2018-10-11 21:02 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

ID:400629 发表于 2018-10-11 22:10 来自手机 | 显示全部楼层
好东西!
回复

使用道具 举报

ID:460004 发表于 2019-1-2 13:52 | 显示全部楼层
课程设计需要
回复

使用道具 举报

ID:302106 发表于 2019-2-18 10:23 | 显示全部楼层
感谢分享~~~
回复

使用道具 举报

ID:289148 发表于 2019-3-1 17:31 | 显示全部楼层
我想问一下,在algorithm.c中an_x[k]引发#68整数转换引发符号更改的的警告是否会对程序有影响
回复

使用道具 举报

ID:116773 发表于 2019-3-1 21:27 | 显示全部楼层
正需要这方面的资料,但我的芯片型号不一样,不知道有参考作用么。
回复

使用道具 举报

ID:482998 发表于 2019-3-1 22:25 | 显示全部楼层
谢谢,学习一下
回复

使用道具 举报

ID:357051 发表于 2019-3-15 10:04 | 显示全部楼层
哈哈,导航车改编,学习学习
回复

使用道具 举报

ID:479101 发表于 2019-4-18 09:53 | 显示全部楼层
为什么Spo2全是-999,好奇怪
回复

使用道具 举报

ID:229016 发表于 2019-5-16 12:27 | 显示全部楼层
Abc_zh 发表于 2019-4-18 09:53
为什么Spo2全是-999,好奇怪

请问你解决这个问题了ma?
回复

使用道具 举报

ID:229016 发表于 2019-5-16 14:21 | 显示全部楼层
Abc_zh 发表于 2019-4-18 09:53
为什么Spo2全是-999,好奇怪

解决了吗?
回复

使用道具 举报

ID:564698 发表于 2019-6-17 15:52 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:472280 发表于 2019-8-15 16:27 | 显示全部楼层
根本用不了,这个算法不知道怎么回事,一直弄不对
回复

使用道具 举报

ID:472280 发表于 2019-8-15 16:34 | 显示全部楼层
有稳定的值但是算法后出来是不行的red=107909, ir=94091
回复

使用道具 举报

ID:397287 发表于 2019-11-11 14:49 | 显示全部楼层
有元器件清单和原理图吗
回复

使用道具 举报

ID:589541 发表于 2020-3-21 20:40 | 显示全部楼层
下载一次扣一次吗?谢谢楼主共享
回复

使用道具 举报

ID:185372 发表于 2020-4-15 16:25 | 显示全部楼层
这个支持,我这里只有c
回复

使用道具 举报

ID:185372 发表于 2020-4-15 16:26 | 显示全部楼层
坚决支持,我这里只有c++,晕乎着呢。
回复

使用道具 举报

ID:725664 发表于 2020-5-29 16:10 | 显示全部楼层
很好,谢谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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