OpenEdv-开源电子网

标题: 移植Arduino的max30100心率传感器模块函数 [打印本页]

作者: 空心杯    时间: 2016-10-20 18:56
标题: 移植Arduino的max30100心率传感器模块函数
我从网上找了Arduino的max30100模块的程序,想一直过来用STM32来做,结果卡在了millis函数这里,求助各位有过经验的大哥

作者: a514582920    时间: 2016-10-20 18:56
[C] 纯文本查看 复制代码
uint8_t MAX30102_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{

    IIC_Start();
    IIC_Send_Byte(0xAE); //·¢ËíÆ÷¼tμØÖ·+D′Ãüáî
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
    IIC_Send_Byte(REG_Address);         //D′¼Ä′æÆ÷μØÖ·
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
    IIC_Send_Byte(REG_data);        //·¢Ëíêy¾Y
    if(IIC_Wait_Ack())          //μè′yACK
    {
        goto RESTATE;;
    }

    IIC_Stop();
    return 1;
               
RESTATE:               
    IIC_Stop();
    return 0;
}


uint8_t MAX30102_ReadI2C(uint8_t REG_Address)
{
    uint8_t res;
    IIC_Start();
    IIC_Send_Byte(0xAE); //·¢ËíÆ÷¼tμØÖ·+D′Ãüáî
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
    IIC_Send_Byte(REG_Address);         //D′¼Ä′æÆ÷μØÖ·
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
          IIC_Start();   
    IIC_Send_Byte(0xAF); //·¢ËíÆ÷¼tμØÖ·+¶á
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
    res=IIC_Read_Byte(0);                //¶áêy¾Y,·¢ËínACK  
    IIC_Stop();                 //2úéúò»¸öí£Ö1ìõ¼t
    return res;
       
RESTATE:               
    IIC_Stop();
    return 0;
}


代码读写程序,IIC时序可参看原子哥的模拟IIC
作者: 正点原子    时间: 2016-10-20 20:35
帮顶
作者: 過路人一號    时间: 2016-10-20 21:43
millis函數是利用一個為1ms為基準的定時器,mcu
上電時會開始計算時間,寫個定時器就可以取代了
作者: 小小怪    时间: 2016-10-21 18:05
我也正在弄这个,SpO2出不来....
作者: a514582920    时间: 2016-10-24 10:48
顶!d=====( ̄▽ ̄*)b,我也在做这个的血氧。可以互相交流交流
作者: 空心杯    时间: 2016-10-25 13:10
過路人一號 发表于 2016-10-20 21:43
millis函數是利用一個為1ms為基準的定時器,mcu
上電時會開始計算時間,寫個定時器就可以取代了

哈哈,这个我查了一下,现在用定时器解决了这个milliis了
作者: 空心杯    时间: 2016-10-25 13:10
现在的问题就是都出来的都是零,很伤
作者: a514582920    时间: 2016-10-25 18:36
空心杯 发表于 2016-10-25 13:10
现在的问题就是都出来的都是零,很伤

Arduino程序要用什么软件打开工程啊?
作者: 空心杯    时间: 2016-10-27 20:59
a514582920 发表于 2016-10-25 18:36
Arduino程序要用什么软件打开工程啊?

我用的MDK,是想把代码移植成STM32的
作者: 空心杯    时间: 2016-10-27 21:00
各位你们的读写时序解决了吗??求助,我弄了两星期了,〒_〒
作者: 空心杯    时间: 2016-10-30 14:21
小小怪 发表于 2016-10-21 18:05
我也正在弄这个,SpO2出不来....

哥们你的读写解决了吗,我模拟的读写都是0和255,硬件读写的通不过,这搞得好郁闷啊
作者: 空心杯    时间: 2016-10-30 14:22
小小怪 发表于 2016-10-21 18:05
我也正在弄这个,SpO2出不来....

整个Ardunio的代码模块都移植完成了,发现基本的读写无法完成
作者: 空心杯    时间: 2016-10-30 14:22
a514582920 发表于 2016-10-24 10:48
顶!d=====( ̄▽ ̄*)b,我也在做这个的血氧。可以互相交流交流

哥们你的读写操作是怎么解决的?
作者: 過路人一號    时间: 2016-10-31 00:29
查一下手冊,調整一下iic讀寫時序吧,不然在sda和scl分別加個4.7k上拉電阻試試

作者: 空心杯    时间: 2016-10-31 10:28
過路人一號 发表于 2016-10-31 00:29
查一下手冊,調整一下iic讀寫時序吧,不然在sda和scl分別加個4.7k上拉電阻試試

现在找到了一个网友写的Arduino的Wire代码,正在根据他的时序来改
作者: a514582920    时间: 2016-10-31 12:02
芯片工作电压是1.8V,VDD是3.3v,我这样转换电路应该可以把?
QQ截图20161031113252.png

作者: a514582920    时间: 2016-10-31 14:07
空心杯 发表于 2016-10-30 14:22
哥们你的读写操作是怎么解决的?

我现在测试读写温度是可以了,但是感觉数据不太对。怀疑电平转换那有问题
作者: 空心杯    时间: 2016-10-31 17:46
a514582920 发表于 2016-10-31 14:07
我现在测试读写温度是可以了,但是感觉数据不太对。怀疑电平转换那有问题

哥们能给看看你代码的读写时序吗??这里我一直没解决掉
作者: 空心杯    时间: 2016-10-31 17:47
a514582920 发表于 2016-10-31 12:02
芯片工作电压是1.8V,VDD是3.3v,我这样转换电路应该可以把?

这个ANT应该是INT把?
作者: a514582920    时间: 2016-11-1 09:08
之前温度不对的问题已经解决了,是iic时序不对;现在的主要问题是如何设置红灯和红外灯控制寄存器,采集血氧数据。还有我用的是max30102,不过这两款芯片应该差不多
作者: 空心杯    时间: 2016-11-2 21:20
a514582920 发表于 2016-11-1 09:08
之前温度不对的问题已经解决了,是iic时序不对;现在的主要问题是如何设置红灯和红外灯控制寄存器,采集血 ...

确实这芯片的采集时序跟整点原子的不太一样,我的之前直接用,根本什么都读不到
作者: 空心杯    时间: 2016-11-2 21:20
a514582920 发表于 2016-11-1 09:08
之前温度不对的问题已经解决了,是iic时序不对;现在的主要问题是如何设置红灯和红外灯控制寄存器,采集血 ...

你现在操作改成什么样的时序合适呢?

作者: 空心杯    时间: 2016-11-2 21:25
a514582920 发表于 2016-11-1 09:04
[mw_shl_code=c,true]uint8_t MAX30102_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{

看那芯片的时序图是真心麻烦
作者: a514582920    时间: 2016-11-3 09:31
空心杯 发表于 2016-11-2 21:20
你现在操作改成什么样的时序合适呢?

[C] 纯文本查看 复制代码
int maxim_MAX30102_ReadI2C_FIFO(uint8_t REG_Address,uint8_t  *Word_Data,uint8_t count)
{
                uint8_t i=0;
                uint8_t no=count;
                uint8_t data1, data2;
       
    IIC_Start();
    IIC_Send_Byte(I2C_WRITE_ADDR); //·¢ËíÆ÷¼tμØÖ·+D′Ãüáî
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
    IIC_Send_Byte(REG_Address);         //D′¼Ä′æÆ÷μØÖ·
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
          IIC_Start();   
    IIC_Send_Byte(I2C_READ_ADDR); //·¢ËíÆ÷¼tμØÖ·+¶á
    if(IIC_Wait_Ack())          //μè′yó|′e
    {
        goto RESTATE;
    }
                while(no)
                {
                        if(1==no)               
                        Word_Data=IIC_Read_Byte(0);
                        else
                        Word_Data=IIC_Read_Byte(1);
               
                        no--;
                        i++;
                }
                IIC_Stop();
                return 1;
RESTATE:               
    IIC_Stop();
                return 0;
}
int maxim_max30102_read_fifo(uint32_t *un_red_led, uint32_t *un_ir_led)
/**
* \brief        Read a set of samples from the MAX30102 FIFO register
* \par          Details
*               This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out]   *un_red_led   - pointer that stores the red LED reading data
* \param[out]   *un_ir_led    - pointer that stores the IR LED reading data
*
* \retval       true on success
*/
{
  uint32_t un_temp;
  unsigned char uch_temp;
  *un_red_led=0;
  *un_ir_led=0;
  unsigned char ch_i2c_data[6];
  
  //read and clear status register
  un_temp=MAX30102_ReadI2C(REG_INTR_STATUS_1);
  un_temp=MAX30102_ReadI2C(REG_INTR_STATUS_2);
  un_temp=0;
  if(maxim_MAX30102_ReadI2C_FIFO(REG_FIFO_DATA, ch_i2c_data, 6)!=1)
  {
    return false;
  }
  un_temp =(unsigned char) ch_i2c_data[0];
  un_temp<<=16;
  *un_red_led+=un_temp;
  un_temp =(unsigned char) ch_i2c_data[1];
  un_temp<<=8;
  *un_red_led+=un_temp;
  un_temp =(unsigned char) ch_i2c_data[2];
  *un_red_led+=un_temp;
  
        un_temp=0;
  un_temp=(unsigned char) ch_i2c_data[3];
  un_temp<<=16;
  *un_ir_led+=un_temp;
  un_temp=(unsigned char) ch_i2c_data[4];
  un_temp<<=8;
  *un_ir_led+=un_temp;
  un_temp=(unsigned char) ch_i2c_data[5];
  *un_ir_led+=un_temp;
  *un_red_led&=0x03FFFF;  //Mask MSB [23:18]
  *un_ir_led&=0x03FFFF;  //Mask MSB [23:18]
  
  return true;
}

作者: a514582920    时间: 2016-11-3 09:33
上面那个是连续读写FIFO程序,后面就是研究算法的问题了
作者: 空心杯    时间: 2016-11-3 11:46
真是感叹这个论坛的方便
作者: 空心杯    时间: 2016-11-3 11:46

谢谢原子哥帮顶
作者: 小小怪    时间: 2016-11-6 11:49
空心杯 发表于 2016-10-30 14:21
哥们你的读写解决了吗,我模拟的读写都是0和255,硬件读写的通不过,这搞得好郁闷啊

你的时序没有弄好吧,注意标准IIC的地址哦。我的脉搏和血氧都出来了。
作者: 小小怪    时间: 2016-11-6 11:50
空心杯 发表于 2016-10-30 14:22
整个Ardunio的代码模块都移植完成了,发现基本的读写无法完成

我之前也是移植Ardunio的,后来测试不对头,现在我把底层驱动剥离出来自己写脉搏和血氧的部分。
作者: 空心杯    时间: 2016-11-6 18:13
小小怪 发表于 2016-11-6 11:50
我之前也是移植Ardunio的,后来测试不对头,现在我把底层驱动剥离出来自己写脉搏和血氧的部分。

求工程文件我得冷静冷静
作者: 小小怪    时间: 2016-11-6 20:21
空心杯 发表于 2016-11-6 18:13
求工程文件我得冷静冷静

我的平台不是在STM32上的,工程附上太繁琐。把IIC和MAX30100的驱动加载到你的工程里就行了。
while(MAX30100_ReadID()){
     //wait for....
    ;
}
IIC.zip (2.25 KB, 下载次数: 351)