找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3618|回复: 3
打印 上一主题 下一主题
收起左侧

stm32调用MAX30102传感器的实现程序

[复制链接]
跳转到指定楼层
楼主
ID:895059 发表于 2021-3-31 16:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "struct_all.h"
#include "delay.h"
#include "sys.h"
#include "usart1_dma.h"
#include "algorithm.h"
#include "max30102.h"
#include "myiic.h"
#include "key.h"

#define MAX_BRIGHTNESS 255

uint32_t aun_ir_buffer[500]; //infrared LED sensor data
uint32_t aun_red_buffer[500];  //red LED sensor data
int32_t n_ir_buffer_length; //data length
float  n_spo2;  //SPO2 value
int8_t ch_spo2_valid;  //indicator to show if the SPO2 calculation is valid
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;

int32_t hr_buf[16];
int32_t hrSum;
int32_t hrAvg;
float spo2_buf[16];
float spo2Sum;
float spo2Avg;
int32_t spo2BuffFilled;
int32_t hrBuffFilled;
int32_t hrValidCnt = 0;
int32_t spo2ValidCnt = 0;
int32_t hrThrowOutSamp = 0;
int32_t spo2ThrowOutSamp = 0;
int32_t spo2Timeout = 0;
int32_t hrTimeout = 0;
void Send_To_PC( int rate, float spo2 );
void Send_To_PC2( unsigned int red, unsigned int ir);
void Send_To_Robot( unsigned int rate, float spo2 );
void loop(void);


void gpio_init(void)
{
        
        GPIO_InitTypeDef GPIO_InitStructure;

         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);//

        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7;//
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
         GPIO_Init(GPIOB, &GPIO_InitStructure);//

        
}
int main(void)
{
    delay_init();                            //延时函数初始化
    NVIC_Configuration();
    USART1_DMA_Init(115200);    //PA9:TX  PA10:RX        接WIFI模块         与手机相连发送状态数据
    gpio_init();                                  //实际是  max30102的中断线
    bsp_InitI2C();
    maxim_max30102_reset(); //resets the MAX30102
    maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_dummy); //Reads/clears the interrupt status register
    maxim_max30102_init();  //initialize the MAX30102
    while(1)
    {
         loop();
    }
}


// the loop routine runs over and over again forever:
void loop(void)
{
    uint32_t un_min, un_max, un_prev_data, un_brightness;  //variables to calculate the on-board LED brightness that reflects the heartbeats
    int32_t i;
    float f_temp;

    un_brightness = 0;
    un_min = 0x3FFFF;
    un_max = 0;

    n_ir_buffer_length = 150; //buffer length of 150 stores 3 seconds of samples running at 50sps  150的缓冲区长度存储了以50sps运行的3秒的样本

    //read the first 150 samples, and determine the signal range
    for(i = 0; i < n_ir_buffer_length; i++)
    {
        while(KEY0 == 1); //wait until the interrupt pin asserts
        maxim_max30102_read_fifo((aun_red_buffer + i), (aun_ir_buffer + i)); //read from MAX30102 FIFO

        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 150 samples (first 3 seconds of samples)
    maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);

    //Continuously taking samples from MAX30102.  Heart rate and SpO2 are calculated every 1 second 连续从MAX30102取样。心率和SpO2每1秒计算一次
    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(KEY0 == 1);
            maxim_max30102_read_fifo((aun_red_buffer + i), (aun_ir_buffer + i));

            //calculate the brightness of the LED 计算LED的亮度
            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;
                f_temp = un_brightness - f_temp;
                if(f_temp < 0)
                    un_brightness = 0;
                else
                    un_brightness = (int)f_temp;
            }
            else
            {
                f_temp = un_prev_data - aun_red_buffer[ i];
                f_temp /= (un_max - un_min);
                f_temp *= MAX_BRIGHTNESS;
                un_brightness += (int)f_temp;
                if(un_brightness > MAX_BRIGHTNESS)
                    un_brightness = MAX_BRIGHTNESS;
            }
                        
        }

        maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);

        if ((ch_hr_valid == 1) && (n_heart_rate < 190) && (n_heart_rate > 40))
        {
            hrTimeout = 0;

            // Throw out up to 1 out of every 5 valid samples if wacky  每5个有效样本中就有1个是古怪的
            if (hrValidCnt == 4)
            {
                hrThrowOutSamp = 1;
                hrValidCnt = 0;
                for (i = 12; i < 16; i++)
                {
                    if (n_heart_rate < hr_buf[ i] + 10)
                    {
                        hrThrowOutSamp = 0;
                        hrValidCnt   = 4;
                    }
                }
            }
            else
            {
                hrValidCnt = hrValidCnt + 1;
            }

            if (hrThrowOutSamp == 0)
            {

                // Shift New Sample into buffer
                for(i = 0; i < 15; i++)
                {
                    hr_buf[ i] = hr_buf[i + 1];
                }
                hr_buf[15] = n_heart_rate;

                // Update buffer fill value
                if (hrBuffFilled < 16)
                {
                    hrBuffFilled = hrBuffFilled + 1;
                }

                // Take moving average
                hrSum = 0;
                if (hrBuffFilled < 2)
                {
                    hrAvg = 0;
                }
                else if (hrBuffFilled < 4)
                {
                    for(i = 14; i < 16; i++)
                    {
                        hrSum = hrSum + hr_buf[ i];
                    }
                    hrAvg = hrSum >> 1;
                }
                else if (hrBuffFilled < 8)
                {
                    for(i = 12; i < 16; i++)
                    {
                        hrSum = hrSum + hr_buf[ i];
                    }
                    hrAvg = hrSum >> 2;
                }
                else if (hrBuffFilled < 16)
                {
                    for(i = 8; i < 16; i++)
                    {
                        hrSum = hrSum + hr_buf[ i];
                    }
                    hrAvg = hrSum >> 3;
                }
                else
                {
                    for(i = 0; i < 16; i++)
                    {
                        hrSum = hrSum + hr_buf[ i];
                    }
                    hrAvg = hrSum >> 4;
                }
            }
            hrThrowOutSamp = 0;
        }
        else
        {
            hrValidCnt = 0;
            if (hrTimeout == 4)
            {
                hrAvg = 0;
                hrBuffFilled = 0;
            }
            else
            {
                hrTimeout++;
            }
        }

        if ((ch_spo2_valid == 1) && (n_spo2 > 59))
        {
            spo2Timeout = 0;

            // Throw out up to 1 out of every 5 valid samples if wacky
            if (spo2ValidCnt == 4)
            {
                spo2ThrowOutSamp = 1;
                spo2ValidCnt = 0;
                for (i = 12; i < 16; i++)
                {
                    if (n_spo2 > spo2_buf[ i] - 10)
                    {
                        spo2ThrowOutSamp = 0;
                        spo2ValidCnt   = 4;
                    }
                }
            }
            else
            {
                spo2ValidCnt = spo2ValidCnt + 1;
            }

            if (spo2ThrowOutSamp == 0)
            {

                // Shift New Sample into buffer
                for(i = 0; i < 15; i++)
                {
                    spo2_buf[ i] = spo2_buf[i + 1];
                }
                spo2_buf[15] = n_spo2;

                // Update buffer fill value
                if (spo2BuffFilled < 16)
                {
                    spo2BuffFilled = spo2BuffFilled + 1;
                }

                // Take moving average
                spo2Sum = 0;
                if (spo2BuffFilled < 2)
                {
                    spo2Avg = 0;
                }
                else if (spo2BuffFilled < 4)
                {
                    for(i = 14; i < 16; i++)
                    {
                        spo2Sum = spo2Sum + spo2_buf[ i];
                    }
                    spo2Avg = spo2Sum/2.f;
                }
                else if (spo2BuffFilled < 8)
                {
                    for(i = 12; i < 16; i++)
                    {
                        spo2Sum = spo2Sum + spo2_buf[ i];
                    }
                    spo2Avg = spo2Sum/4.f;
                }
                else if (spo2BuffFilled < 16)
                {
                    for(i = 8; i < 16; i++)
                    {
                        spo2Sum = spo2Sum + spo2_buf[ i];
                    }
                    spo2Avg = spo2Sum /8.f;
                }
                else
                {
                    for(i = 0; i < 16; i++)
                    {
                        spo2Sum = spo2Sum + spo2_buf[ i];
                    }
                    spo2Avg = spo2Sum/16.f;
                }
            }
            spo2ThrowOutSamp = 0;
        }
        else
        {
            spo2ValidCnt = 0;
            if (spo2Timeout == 4)
            {
                spo2Avg = 0;
                spo2BuffFilled = 0;
            }
            else
            {
                spo2Timeout++;
            }
        }
                printf("hr:%d\r\n",hrAvg);
                printf("spo2Avg:%f\r\n",spo2Avg);
    }
}


stm32 max30102.7z

453.96 KB, 下载次数: 59, 下载积分: 黑币 -5

评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:1022289 发表于 2022-5-15 09:34 | 只看该作者
楼主有带操作系统的代码吗
回复

使用道具 举报

板凳
ID:1022289 发表于 2022-5-15 09:39 | 只看该作者
楼主有带操作系统的程序吗
回复

使用道具 举报

地板
ID:1018878 发表于 2022-6-11 23:33 | 只看该作者
可以用proteus吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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