久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4596|回復: 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, 下載次數: 60, 下載積分: 黑幣 -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 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九色九九 | 久久这里只有 | 激情五月综合网 | 国产视频在线观看一区二区三区 | 天堂中文在线观看 | 成人久久| 亚洲欧美中文日韩在线v日本 | 羞羞视频在线观看免费观看 | 波多野结衣在线观看一区二区三区 | 国产一区二区三区色淫影院 | 亚洲精品成人在线 | 欧美黄色一区 | 黑人久久久 | 亚洲精品一 | 成人午夜影院 | 国产一区二区在线免费播放 | 国产成人亚洲精品 | 国产美女视频黄a视频免费 国产精品福利视频 | 91av在线免费播放 | 久久精品一区二区三区四区 | 久草在线在线精品观看 | 成人在线小视频 | 久久精品国产一区二区电影 | 超碰人人人人 | 欧美一区二区三区在线看 | 亚洲精品久久久蜜桃 | 欧美日本高清 | 污污的网站在线观看 | 久久成人免费 | 久久久久亚洲精品中文字幕 | 精品国产视频 | 操久久 | 精品国产一区二区三区成人影院 | 久久久久亚洲 | 久久婷婷色 | 免费精品| 影视一区 | 久久影音先锋 | 成年人在线观看 | 超碰在线人 | 中文二区 |