找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9302|回复: 10
收起左侧

使用模拟iic_MAX30102_for_stm32源码

  [复制链接]
ID:402056 发表于 2018-9-25 10:59 | 显示全部楼层 |阅读模式
max30102程序 stm32

单片机源程序如下:
  1. #include "stm32f10x.h"
  2. #include "usart.h"
  3. #include "ultrasonic.h"
  4. #include "stm32f10x_gpio.h"
  5. #include "stm32f10x_i2c.h"
  6. #include "delay.h"//延时函数

  7. #include <stdio.h>
  8. #include <math.h>
  9. #include "bsp_i2c_gpio.h"

  10. //#define SAMPLE_50   //如果定义此宏就是50采样率   否则是100

  11. #define PYTHON_USED
  12. /*************************************************
  13. 函数: fputc(int ch, FILE *f)
  14. 功能: 重定向c库函数printf到USART1
  15. 参数: 无
  16. 返回: 无
  17. **************************************************/
  18. int fputc(int ch, FILE *f)
  19. {
  20.         USART_SendData(USART1, (unsigned char) ch);
  21.         while (!(USART1->SR & USART_FLAG_TXE));
  22.         return (ch);
  23. }


  24. /*************************************************
  25. 函数: void main_init(void)
  26. 功能: main初始化
  27. 参数: 无
  28. 返回: 无
  29. **************************************************/
  30. void main_init(void)
  31. {
  32.         Usart_Init();
  33.         //I2C1_GPIO_Config();
  34.         //I2C1_Mode_config();
  35.         //I2C1_Configuration();
  36.         bsp_InitI2C();
  37.         delay_init(72);            //延时初始化
  38. }

  39. extern void test_max30102_fun(void);
  40. extern u8 max30102_Bus_Read(u8 Register_Address);
  41. extern void max30102_init(void);

  42. /*************************************************
  43. 函数: int main(void)
  44. 功能: main主函数
  45. 参数: 无
  46. 返回: 无
  47. **************************************************/
  48. int main(void)
  49. {
  50.         u8 temp_num=0;
  51.         main_init();
  52.         
  53.         max30102_init();
  54.         
  55.         printf("\r\n MAX30102  init  \r\n");

  56.         
  57. #if 0        
  58.         while(1)
  59.         {
  60.                 delay_ms(1000);            
  61.                 max30102_init();
  62.                 temp_num = max30102_Bus_Read(0x1f);
  63.                 printf("当前温度 = %d\r\n",temp_num);
  64.         }
  65. #endif

  66.         while(1)
  67.         {        
  68.                 test_max30102_fun();
  69.         }
  70. }




  71. #define max30102_WR_address 0xAE

  72. u8 max30102_Bus_Write(u8 Register_Address, u8 Word_Data)
  73. {

  74.         /* 采用串行EEPROM随即读取指令序列,连续读取若干字节 */

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

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

  79.         /* 第3步:发送ACK */
  80.         if (i2c_WaitAck() != 0)
  81.         {
  82.                 goto cmd_fail;        /* EEPROM器件无应答 */
  83.         }

  84.         /* 第4步:发送字节地址 */
  85.         i2c_SendByte(Register_Address);
  86.         if (i2c_WaitAck() != 0)
  87.         {
  88.                 goto cmd_fail;        /* EEPROM器件无应答 */
  89.         }
  90.         
  91.         /* 第5步:开始写入数据 */
  92.         i2c_SendByte(Word_Data);

  93.         /* 第6步:发送ACK */
  94.         if (i2c_WaitAck() != 0)
  95.         {
  96.                 goto cmd_fail;        /* EEPROM器件无应答 */
  97.         }

  98.         /* 发送I2C总线停止信号 */
  99.         i2c_Stop();
  100.         return 1;        /* 执行成功 */

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



  106. u8 max30102_Bus_Read(u8 Register_Address)
  107. {
  108.         u8  data;


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

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

  113.         /* 第3步:发送ACK */
  114.         if (i2c_WaitAck() != 0)
  115.         {
  116.                 goto cmd_fail;        /* EEPROM器件无应答 */
  117.         }

  118.         /* 第4步:发送字节地址, */
  119.         i2c_SendByte((uint8_t)Register_Address);
  120.         if (i2c_WaitAck() != 0)
  121.         {
  122.                 goto cmd_fail;        /* EEPROM器件无应答 */
  123.         }
  124.         

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

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

  129.         /* 第8步:发送ACK */
  130.         if (i2c_WaitAck() != 0)
  131.         {
  132.                 goto cmd_fail;        /* EEPROM器件无应答 */
  133.         }

  134.         /* 第9步:读取数据 */
  135.         {
  136.                 data = i2c_ReadByte();        /* 读1个字节 */

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

  142. cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
  143.         /* 发送I2C总线停止信号 */
  144.         i2c_Stop();
  145.         return 0;
  146. }


  147. void max30102_FIFO_Read(u8 Register_Address,u32  Word_Data[][2],u8 count)
  148. {
  149.         u8 i=0;
  150.         u8 no = count;
  151.         u8 data1, data2,data3;
  152.         /* 第1步:发起I2C总线启动信号 */
  153.         i2c_Start();

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

  156.         /* 第3步:发送ACK */
  157.         if (i2c_WaitAck() != 0)
  158.         {
  159.                 goto cmd_fail;        /* EEPROM器件无应答 */
  160.         }

  161.         /* 第4步:发送字节地址, */
  162.         i2c_SendByte((uint8_t)Register_Address);
  163.         if (i2c_WaitAck() != 0)
  164.         {
  165.                 goto cmd_fail;        /* EEPROM器件无应答 */
  166.         }
  167.         

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

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

  172.         /* 第8步:发送ACK */
  173.         if (i2c_WaitAck() != 0)
  174.         {
  175.                 goto cmd_fail;        /* EEPROM器件无应答 */
  176.         }

  177.         /* 第9步:读取数据 */
  178.         while (no)
  179.         {
  180.                 data1 = i2c_ReadByte();        
  181.                 i2c_Ack();
  182.                 data2 = i2c_ReadByte();
  183.                 i2c_Ack();
  184.                 data3 = i2c_ReadByte();
  185.                 i2c_Ack();
  186.                 Word_Data[i][0] = ( (((u32)data1 << 16)&0X30000) | (((u16)data2 << 8)&0XFF00) | data3);  //

  187.                
  188.                 data1 = i2c_ReadByte();        
  189.                 i2c_Ack();
  190.                 data2 = i2c_ReadByte();
  191.                 i2c_Ack();
  192.                 data3 = i2c_ReadByte();
  193.                 if(1==no)
  194.                         i2c_NAck();        /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
  195.                 else
  196.                         i2c_Ack();
  197.                 Word_Data[i][1] = ( (((u32)data1 << 16)&0X30000) | (((u16)data2 << 8)&0XFF00) | data3);  //

  198.                 no--;        
  199.                 i++;
  200.         }
  201.         /* 发送I2C总线停止信号 */
  202.         i2c_Stop();

  203. cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
  204.         /* 发送I2C总线停止信号 */
  205.         i2c_Stop();
  206. }



  207. #define INTERRUPT_REG                                                          0X00
  208. #define INTERRUPT_REG_A_FULL                                  (0X01<<7)
  209. #define INTERRUPT_REG_PPG_RDY                                  (0X01<<6)
  210. #define INTERRUPT_REG_ALC_OVF                                  (0X01<<5)  
  211. #define INTERRUPT_REG_PROX_INT                                 (0X01<<4)
  212. #define INTERRUPT_REG_PWR_RDY                                  (0X01<<0)

  213. #define INTERRUPT_ENABLE_REG                                          0X02
  214. #define INTERRUPT_ENABLE_REG_A_FULL_EN                 (0X01<<7)
  215. #define INTERRUPT_ENABLE_REG_PPG_RDY_EN                (0X01<<6)
  216. #define INTERRUPT_ENABLE_REG_ALC_OVF_EN          (0X01<<5)  
  217. #define INTERRUPT_ENABLE_REG_PROX_INT_EN         (0X01<<4)

  218. #define INTERRUPT_DIE_TEMP_REG                                          0X03
  219. #define INTERRUPT_DIE_TEMP_REG_DIE_TEMP_EN                 (0X01<<1)

  220. #define INTERRUPT_FIFO_WR_PTR_REG                                          0X04
  221. #define INTERRUPT_OVF_COUNTER_REG                                          0X05
  222. #define INTERRUPT_RD_PTR_REG                                                  0X06
  223. #define INTERRUPT_FIF0_DATA_REG                                                  0X07

  224. #define INTERRUPT_FIFO_CONFIG_REG                                          0X08
  225. #define INTERRUPT_FIFO_CONFIG_REG_SMP_AVE                          (0X00<<5)  //SPM_AVE[2:0] = 000 不要 样本平均
  226. #define INTERRUPT_FIFO_CONFIG_REG_FIFO_ROLLOVER_EN (0X01<<4)  //  自动翻转fifo
  227. #define INTERRUPT_FIFO_CONFIG_REG_FIFO_ALL_FULL                (0X0F<<0)  // READ 17 data  for one  interrupt


  228. #define INTERRUPT_MODE_CONFIG_REG                                          0X09
  229. #define INTERRUPT_MODE_CONFIG_REG_SHDN                                 (0X00<<7)  // shutdown control
  230. #define INTERRUPT_MODE_CONFIG_REG_RESET                                (0X00<<6)  // reset  control
  231. #define INTERRUPT_MODE_CONFIG_REG_MODE                                (0X03<<0)  // Spo2  mode


  232. #define INTERRUPT_SPO2_CONFIG_REG                                          0X0a
  233. #define INTERRUPT_SPO2_CONFIG_REG_ADC_RGE                         (0X03<<5)  // SP02_ADC_RGE[1:0]=11

  234. #ifdef SAMPLE_50
  235. #define INTERRUPT_SPO2_CONFIG_REG_SR                                 (0X00<<2)  // SP02_SR[2:0]=000     Sample Rate = 50
  236. #else
  237. #define INTERRUPT_SPO2_CONFIG_REG_SR                                 (0X01<<2)  // SP02_SR[2:0]=001     Sample Rate = 100
  238. #endif

  239. #define INTERRUPT_SPO2_CONFIG_REG_LED_PW                        (0X03<<0)  // SP02_LED_PW[1:0]=11

  240. #define INTERRUPT_LED1_PA_REG                                          0X0C
  241. #define INTERRUPT_LED2_PA_REG                                          0X0D


  242. #define ONES_READ_DATA_BY_FIFO                (32-INTERRUPT_FIFO_CONFIG_REG_FIFO_ALL_FULL)  // READ NUM  data  for one  interrupt


  243. void max30102_init()
  244. {
  245.         max30102_Bus_Write(INTERRUPT_ENABLE_REG, INTERRUPT_ENABLE_REG_A_FULL_EN       |
  246.                                                                                                 INTERRUPT_ENABLE_REG_PPG_RDY_EN  |
  247.                                                                                                 INTERRUPT_ENABLE_REG_ALC_OVF_EN  |
  248.                                                                                                 INTERRUPT_ENABLE_REG_PROX_INT_EN); //all interrupt enable

  249.         max30102_Bus_Write(INTERRUPT_DIE_TEMP_REG, INTERRUPT_DIE_TEMP_REG_DIE_TEMP_EN); //DIE_TEMP_RDY_EN

  250.         max30102_Bus_Write(INTERRUPT_FIFO_WR_PTR_REG, 0x00);   //set FIFO write Pointer reg = 0x00 for clear it
  251.         max30102_Bus_Write(INTERRUPT_OVF_COUNTER_REG, 0x00);        //set Over Flow Counter  reg = 0x00 for clear it
  252.         max30102_Bus_Write(INTERRUPT_RD_PTR_REG, 0x00);        //set FIFO Read Pointer  reg = 0x00 for clear it

  253.         max30102_Bus_Write(INTERRUPT_FIFO_CONFIG_REG,  INTERRUPT_FIFO_CONFIG_REG_SMP_AVE|
  254.                                                                                                         INTERRUPT_FIFO_CONFIG_REG_FIFO_ROLLOVER_EN  |
  255.                                                                                                         INTERRUPT_FIFO_CONFIG_REG_FIFO_ALL_FULL);                                                                                         

  256.         max30102_Bus_Write(INTERRUPT_MODE_CONFIG_REG,  INTERRUPT_MODE_CONFIG_REG_SHDN |
  257.                                                                                                         INTERRUPT_MODE_CONFIG_REG_RESET  |
  258.                                                                                                         INTERRUPT_MODE_CONFIG_REG_MODE);         

  259.         max30102_Bus_Write(INTERRUPT_SPO2_CONFIG_REG,  INTERRUPT_SPO2_CONFIG_REG_ADC_RGE |
  260.                                                                                                         INTERRUPT_SPO2_CONFIG_REG_SR  |
  261.                                                                                                         INTERRUPT_SPO2_CONFIG_REG_LED_PW);         

  262.         
  263.         max30102_Bus_Write(INTERRUPT_LED1_PA_REG, 0xe0);        
  264.         max30102_Bus_Write(INTERRUPT_LED2_PA_REG, 0xe0);        

  265.         
  266. }

  267. #if  1

  268. void test_max30102_fun(void)
  269. {
  270.         u16 temp_num=0;
  271.         u32 fifo_word_buff[ONES_READ_DATA_BY_FIFO][2];
  272.         
  273.         while(1)
  274.         {
  275.                 temp_num = max30102_Bus_Read(INTERRUPT_REG);
  276. #ifdef        PYTHON_USED
  277.                 if( INTERRUPT_REG_PPG_RDY&temp_num )
  278.                 {
  279.                         max30102_FIFO_Read(INTERRUPT_FIF0_DATA_REG,fifo_word_buff, 1); //read the hr and spo2 data form fifo
  280.                         
  281.                         Usart1_PutChar(0xA0);
  282.                         Usart1_PutChar(0xE0);
  283.                         printf("%ld",fifo_word_buff[0][0]);
  284.                         Usart1_PutChar(0xDE);
  285.                         Usart1_PutChar(0xAF);
  286.                         
  287.                 }               
  288. #endif
  289.         }
  290. }
  291. #endif
复制代码

Keil代码下载:
使用模拟iic_MAX30102_for_stm32.rar (567.97 KB, 下载次数: 260)

评分

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

查看全部评分

回复

使用道具 举报

ID:414226 发表于 2018-10-23 19:44 | 显示全部楼层
能用不
回复

使用道具 举报

ID:93224 发表于 2019-1-5 21:18 | 显示全部楼层
fifo_word_buff[0][0] 这里的数据是血糖、心率中的哪一个?
回复

使用道具 举报

ID:165276 发表于 2019-1-6 09:24 | 显示全部楼层
你好,stm32的模拟IIC发送数据不用延时吗?之前用的51单片机做的时候需要延时,能说一下吗?刚接触stm32
回复

使用道具 举报

ID:538165 发表于 2019-6-1 18:11 | 显示全部楼层
你好,MAX30102 对里面的延时要求严格吗?
回复

使用道具 举报

ID:299263 发表于 2019-7-22 17:31 | 显示全部楼层
终于找到比较全的版本了
回复

使用道具 举报

ID:593548 发表于 2019-8-3 16:02 | 显示全部楼层
这代码有啥用。网上找的全是一个模板的拿来忽悠积分的吧
回复

使用道具 举报

ID:350895 发表于 2019-12-4 15:17 | 显示全部楼层
下载学习下   
回复

使用道具 举报

ID:257542 发表于 2020-12-12 22:14 | 显示全部楼层
大神,麻烦您给解释一下,那个数组里的数据怎么转换成心率跟血氧浓度呗,谢谢啦
回复

使用道具 举报

ID:118735 发表于 2021-12-19 15:03 | 显示全部楼层
都是资料没有项目文件
回复

使用道具 举报

ID:262 发表于 2021-12-19 21:17 | 显示全部楼层
王企鹅 发表于 2021-12-19 15:03
都是资料没有项目文件

项目文件在 MDK-ARM 目录
51hei.png
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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