標(biāo)題: stm32調(diào)用MAX30102傳感器的實(shí)現(xiàn)程序 [打印本頁]

作者: huangj990802    時(shí)間: 2021-3-31 16:25
標(biāo)題: stm32調(diào)用MAX30102傳感器的實(shí)現(xiàn)程序
#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; //設(shè)置成上拉輸入
         GPIO_Init(GPIOB, &GPIO_InitStructure);//

        
}
int main(void)
{
    delay_init();                            //延時(shí)函數(shù)初始化
    NVIC_Configuration();
    USART1_DMA_Init(115200);    //PA9:TX  PA10:RX        接WIFI模塊         與手機(jī)相連發(fā)送狀態(tài)數(shù)據(jù)
    gpio_init();                                  //實(shí)際是  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的緩沖區(qū)長度存儲(chǔ)了以50sps運(yùn)行的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 連續(xù)從MAX30102取樣。心率和SpO2每1秒計(jì)算一次
    while(1)
    {
        i = 0;
        un_min = 0x3FFFF;
        un_max = 0;

        //將前100組樣本轉(zhuǎn)儲(chǔ)到內(nèi)存中,并將最后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  更新信號(hào)的最小值和最大值
            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];
        }

        //計(jì)算心率之前取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 計(jì)算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個(gè)有效樣本中就有1個(gè)是古怪的
            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, 下載次數(shù): 60, 下載積分: 黑幣 -5


作者: 123456LV    時(shí)間: 2022-5-15 09:34
樓主有帶操作系統(tǒng)的代碼嗎
作者: 123456LV    時(shí)間: 2022-5-15 09:39
樓主有帶操作系統(tǒng)的程序嗎
作者: 大臉盤子    時(shí)間: 2022-6-11 23:33
可以用proteus嗎?




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1