Yuworm 2024-06-08 22:49 采纳率: 20%
浏览 26
已结题

MAX30102完成初始化和寄存器配置后,读值异常

在STM32F103上使用MAX30102,使用模拟IIC进行通讯,GPIO口已成功初始化,30102的寄存器也已成功配置之后,在调用读取FIFO寄存器的函数max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);时,读到的数组temp每个元素一直都是255。
代码如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "usart.h"
#include "mlx90614.h"
#include "YW03.h"
#include "SD01.h"
#include "max30102.h"
#include "algorithm.h"
#include "YW01.h"
#include "usart2.h"
#include "common.h"
#include "wifista.h"
#include "malloc.h"
#include "stdlib.h"
//ALIENTEK miniSTM32?????1
//????:www.openedv.com
//?????????????



extern u16 TIM3CH1_CAPTURE_STA; //输入捕获状态 
extern u16 TIM2CH1_CAPTURE_VAL;//输入捕获值


uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length;    //data length
uint32_t aun_red_buffer[500];    //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid;   //指示器,用于显示 SP02 计算是否  有效
int32_t n_heart_rate;   //heart rate value
int8_t  ch_hr_valid;    //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
 
void dis_DrawCurve(u32* data,u8 x);

int main(void)
{    


    /*******************************************************************************
    *
    * 辅助变量
    *
    *******************************************************************************/
//    u8* msg;
    /*******************************************************************************
    *
    * MAX30102采样变量
    *
    *******************************************************************************/
 //variables to calculate the on-board LED brightness that reflects the heartbeats
    uint32_t un_min, un_max, un_prev_data;  
    int i;
    int32_t n_brightness;
    float f_temp;
//    u8 temp_num=0;
    u8 temp[6];
    u8 statue1;
    u8 m;
//    u8 str[100];
//    u8 dis_hr=0,dis_spo2=0;

  /*******************************************************************************
    *
    * 采样数据
    * 
    *******************************************************************************/
//    u8 blood_oxygen = 50;        //血氧
//    u8 heart_rate = 87;            //心率
    float temperature = 38.5;    //体温
//    u8 drip_rate =40;                //滴速
//    u8 liquid_level = 78;        //液位

    /*******************************************************************************
    *
    * 初始化函数
    * 
    *******************************************************************************/
    delay_init();             //延时函数    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组
    uart_init(9600);       //电脑串口通信
    
    //传感器初始化
//    SD01_Init();         //滴速检测模块
    mlx90614_Init();         //体温检测模块
//    YW01_Init();                 //液位检测模块
//    USART2_Init(115200); //wifi模块通信串口初始化
//    atk_8266_test();         //检查wifi模块
//    atk_8266_at_response(1);//检查ATK-ESP8266模块发送过来的数据,及时上传给电脑
//    atk_8266_wifista_test();//连接阿里云物联网
    
//    msg = malloc(180);
    statue1 = max30102_init();
    printf("\nsuccess?%u\n",statue1);
 /*******************************************************************************
    *
    * max30102准备
    * 
    *******************************************************************************/
    un_min=0x3FFFF;
    un_max=0;
    
    n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
    
    //read the first 500 samples, and determine the signal range
    for(i=0;i<n_ir_buffer_length;i++)
    {
            while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) ==1);   //wait until the interrupt pin asserts
            
            max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
            aun_red_buffer[i] =  (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2];    // Combine values to get the actual number
            aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5];   // Combine values to get the actual number
            
            if(un_min>aun_red_buffer[i])
                    un_min=aun_red_buffer[i];    //update signal min
            if(un_max<aun_red_buffer[i])
                    un_max=aun_red_buffer[i];    //update signal max
    }
    un_prev_data=aun_red_buffer[i];
    //calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
    maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);

    while(1)
    {
        i=0;
        un_min=0x3FFFF;
        un_max=0;
        
        //将前 100 组样本转储到内存中,并将最后 400 组样本移到顶部
        for(i=100;i<500;i++)
        {
                aun_red_buffer[i-100]=aun_red_buffer[i];
                aun_ir_buffer[i-100]=aun_ir_buffer[i];
                
                //update the signal min and max
                if(un_min>aun_red_buffer[i])
                un_min=aun_red_buffer[i];
                if(un_max<aun_red_buffer[i])
                un_max=aun_red_buffer[i];
        }
        //在计算心率之前取100组样本。
        for(i=400;i<500;i++)
        {
            un_prev_data=aun_red_buffer[i-1];
            while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) ==1);
            max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
            printf("\n");
            for(m=0;m<6;m++)
            {
                printf("temp[%u]:%u,",m,temp[m]);
            }
            aun_red_buffer[i] =  (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2];    // 组合值以获得 这实际数量
            aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5];   // Combine values to get the actual number
      
            printf("\naun_red_buffer[%u]=%u,aun_ir_buffer[%u]=%u",i,aun_red_buffer[i],i,aun_ir_buffer[i]);
            
            if(aun_red_buffer[i]>un_prev_data)
            {
                    f_temp=aun_red_buffer[i]-un_prev_data;
                    f_temp/=(un_max-un_min);
                    f_temp*=MAX_BRIGHTNESS;
                    n_brightness-=(int)f_temp;
                    if(n_brightness<0)
                            n_brightness=0;
            }
            else
            {
                    f_temp=un_prev_data-aun_red_buffer[i];
                    f_temp/=(un_max-un_min);
                    f_temp*=MAX_BRIGHTNESS;
                    n_brightness+=(int)f_temp;
                    if(n_brightness>MAX_BRIGHTNESS)
                            n_brightness=MAX_BRIGHTNESS;
            }
            //通过UART将样品和计算结果发送到终端程序
//            if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
//            {
//                dis_hr = n_heart_rate;
//                dis_spo2 = n_sp02;
//            }
//            else
//            {
//                dis_hr = 0;
//                dis_spo2 = 0;
//            }
                
        }    
        printf("HR=%i, ", n_heart_rate); 
        printf("HRvalid=%i, ", ch_hr_valid);
        printf("SpO2=%i, ", n_sp02);
        printf("SPO2Valid=%i\r\n", ch_spo2_valid);
        temperature = ReadTemp();
        printf("temperature=%f\r\n", temperature);
        maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
    }

//    while(1)
//    {
//        


////        heart_rate = read_heart_rate();
//        temperature = ReadTemp();
////        drip_rate = get_drip_rate();
////        liquid_level = Read_Level_Liquid();
//        
//        printf("speed:%u\n",drip_rate);
//        printf("heart rate:%u\n",heart_rate);
//        printf("temperature:%f\n",temperature);
//        printf("drip_rate:%u\n",drip_rate);
//        printf("level:%u\n",liquid_level);
//        
//        //发送数据并接收信息
////        sprintf((char*)msg, "AT+MQTTPUB=0,\"/k1bup6fRrSA/ESP8266/user/update\",\"{\\\"bloodOxygen\\\":%u\\,\\\"liquidResidue\\\":%u\\,\\\"heartRate\\\":%u\\,\\\"temperature\\\":%f\\,\\\"dripRate\\\":%u}\",1,0",blood_oxygen,liquid_level,heart_rate,temperature,drip_rate);
////        atk_wifista_communication(msg);//接收
//        printf("\n\n\n\n");
//        delay_ms(5000);
//        
//        
//    }
    
}



  • 写回答

25条回答 默认 最新

  • 阿里嘎多学长 2024-06-08 23:02
    关注
    获得0.15元问题酬金

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    在使用MAX30102进行数据读取时,如果发现读取到的数组temp中的每个元素始终是255,这通常意味着存在几个可能的问题:

    1. 硬件连接问题:请确保MAX30102与STM32F103之间的I2C连接是正确的,包括数据线SDA、时钟线SCL以及电源和地线。

    2. I2C通信故障:检查I2C通信是否正常。可以使用逻辑分析仪或者I2C调试工具来监测I2C总线上的通信情况。

    3. MAX30102初始化问题:确保MAX30102的初始化代码正确执行,包括设置正确的I2C地址和配置寄存器。

    4. 读取函数问题:检查max30102_FIFO_ReadBytes函数的实现,确保它能够正确地从MAX30102读取数据。特别是检查是否有可能在读取过程中发生溢出或错误。

    5. 寄存器配置问题:检查MAX30102的寄存器配置,确保没有错误的配置导致数据读取异常。

    6. 电源问题:确保MAX30102的电源供应稳定,因为不稳定的电源可能会影响其正常工作。

    7. 代码逻辑问题:检查代码逻辑,特别是循环和条件判断部分,确保没有逻辑错误导致读取失败。

    针对上述问题,以下是一些可能的解决方案:

    • 硬件检查:重新检查硬件连接,确保没有接触不良或接线错误。
    • I2C通信测试:使用STM32的HAL库或LL库中的I2C测试函数,发送和接收一些测试数据,以验证I2C通信是否正常。
    • 初始化代码检查:检查MAX30102的初始化代码,特别是I2C地址和寄存器设置。
    • 读取函数调试:在max30102_FIFO_ReadBytes函数中添加调试信息,打印出每一步的执行情况和返回值。
    • 寄存器配置验证:根据MAX30102的数据手册,检查并验证所有相关的寄存器配置。
    • 电源稳定性检查:使用电源测试工具检查MAX30102的电源供应是否稳定。

    如果需要具体的代码实现,可以参考MAX30102的官方数据手册和参考设计,以及STM32的I2C通信库的示例代码。

    至于参考资料,以下是一些可能有用的链接:

    请注意,上述链接可能需要根据实际情况进行访问和验证。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月16日
  • 赞助了问题酬金15元 6月8日
  • 创建了问题 6月8日

悬赏问题

  • ¥15 网络分析设施点无法识别
  • ¥15 状态图的并发态问题咨询
  • ¥15 PFC3D,plot
  • ¥15 VAE模型编程报错无法解决
  • ¥100 基于SVM的信息粒化时序回归预测,有偿求解!
  • ¥15 物体组批优化问题-数学建模求解答
  • ¥15 微信原生小程序tabBar编译报错
  • ¥350 麦克风声源定位坐标不准
  • ¥15 apifox与swagger使用
  • ¥15 egg异步请求返回404的问题