问答

汇集网友智慧,解决技术难题

21ic问答首页 - stm32血压计的设计

STM32 血压计 设计 输出 使用

stm32血压计的设计 赏2000家园币

elsaflower2024-11-18
来一套stm32血压计的设计,使用示波法测量,下降趋势。测量周期为20s内,最好能够输出测量的波形
回答 +关注 0
2507人浏览 3人回答问题 分享 举报
3 个回答
  • #include "stm32f4xx.h"                  // Device header
    #include "Handlers.h"
    #include "LCDHD44780NonBlocking.h"
    #include "BloodPressureMeterFunctions.h"
    #include "PressureSensorABPMANN005PG2A3.h"
    #include "FIRbandpass_3_10_Hz_Coeff.h"
    #include "FIRfilterPtByPt.h"
    #include "IIRfilterPtByPt.h"

    /*=================================
    Formula for pressure calculation:

    pressure = ((Output - 1638) * 5)/(14745 - 1638)

    1 psi = 51.7149326 mmHg
    3.480619445 psi = 180 mmHg

    10762 = 180 mmHg
    //================================*/

    //===  Instances of structures and pointers to structures  ===//
    pulseWave_  _pulseWave;
    pulseWave_* pulseWave = &_pulseWave;

    FIRfilterObject _BandpassFIRfilter;
    FIRfilterObject* BandpassFIRfilter = &_BandpassFIRfilter;
    IIR4thOrderFilterObj _LowpassIIRfilter;
    IIR4thOrderFilterObj* LowpassIIRfilter = &_LowpassIIRfilter;

    //=== Extern variables enabling calculations and display  ===//
    extern volatile uint8_t calculate;
    extern volatile uint8_t displayOnLCDevery1sec;
    extern volatile uint8_t displayOnLCDevery250milisec;

    //===========  FIR filter coefficients  ===========//
    extern float FIRbandpass_3_10_Hz_Coeff[166];

    //==== Circular buffers to pass into FIRfilterObject ===//
    float signalBufferForBandpassFIRfilter[256];


    int main()
    {
                    RCCClockConfiguration();
                    /* FPU initialization */
                    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

                    PumpValveButtonConfiguration();
                    LCDInitialize();
                    TimersInitialization();

                    LCDLocateXY(0,0);
                    LCDSendText("Put cuff on arm ");
                    LCDLocateXY(0,1);
                    LCDSendText("press  button   ");
                    PressureSensorInitialize();
                   
        //====== Initialization of pointers ======//
                    float LPFiltered;
                    float BPFiltered;
                    float* lowPassFiltered;       
                    float* bandPassFiltered;
                    lowPassFiltered = &LPFiltered;
                    bandPassFiltered = &BPFiltered;
                    //==============================//
                   
                    volatile float previousValue, derivative, previousDerivative;                // Variables for determining change of 1st derivative sign of lowpass filtered output
                    volatile float previousValueBP, derivativeBP, previousDerivativeBP;  // Variables for determining change of 1st derivative sign of bandpass filtered output

                    _BandpassFIRfilter = CreateFIRfilterObject(256, signalBufferForBandpassFIRfilter, 166, FIRbandpass_3_10_Hz_Coeff);
                    _LowpassIIRfilter = IIR_4thOrderSignalFilteringPtByPtInitialize(IIRforwardCoeffLowpass_20Hz, IIRreverseCoeffLowpass_20Hz);

                    unsigned int BPfilterDelay = (unsigned int) (_BandpassFIRfilter.coefficientsLength - 1) / 2;     //  Length of bandpass FIR filter group delay
                   
                    volatile uint8_t displayHeart = 0;      //  Variable controlling display of heart character on LCD
                    volatile uint8_t clearHeart = 0;         //  Variable controlling clear of heart character on LCD
                    volatile uint8_t calculateMAP = 0;    //  Variable controlling start of MAP evaluation
                   

            while(1)
            {
                            if(calculate)
                            {
                                            if( pressureArrayHead != pressureArrayTail)
                                            {               
                                                    //=======================   Filtration of data from pressure sensor   ========================//
                                                      IIR_4thOrderSignalFilteringPtByPt(LowpassIIRfilter, pressureArray[pressureArrayTail], lowPassFiltered);
                                                            FIRfilterPtByPt(BandpassFIRfilter, pressureArray[pressureArrayTail], bandPassFiltered);
                                                   
                                                    //=======================  Update of buffers and variables values  ========================//
                                                            pulseWave->currentPressure = ((*lowPassFiltered- 1638.0f) * 5.0f) / (14745.0f - 1638.0f) * 52.0f;
                                                            pulseWave->numberOfSamples++;
                                                            Last128SamplesBufferHead = (Last128SamplesBufferHead+1) & 127;
                                                      Last128SamplesBuffer[Last128SamplesBufferHead] = *lowPassFiltered;
                                                      pressureArrayTail = (pressureArrayTail + 1) & pressureArrayMask;

                                                   
                                                            //=======  New derivative value calculation  =======//                       
                                                            derivative = *lowPassFiltered - previousValue;
                                                            derivativeBP = *bandPassFiltered - previousValueBP;
                                                   
                                                      //======================   Peak detection   ======================//
                                                            if( ((derivative * previousDerivative) < 0) && ((derivative - previousDerivative) < 0) )
                                                            {
                                                                            if((pulseWave->numberOfSamples - pulseWave->previousPeakXcoordinate ) > 64)  // if two Peaks distance > approximate 250 ms
                                                                            {
                                                                                            displayHeart = 1;
                                                                                            pulseWave->previousPeakXcoordinate = pulseWave->numberOfSamples;
                                                                            }
                                                                           
                                                                            if( ! pulseWave->systolicPressure )
                                                                            {
                                                                                            calculateMAP = 1;    // if Systolic peak detected start evaluating MAP
                                                                                            pulseWave->systolicPressure = pulseWave->currentPressure;  
                                                                            }
                                                            }                                       

                                                            //========================   MAP calculation   =========================//
                                                            if( calculateMAP )
                                                            {
                                                                            if( ((derivativeBP * previousDerivativeBP) < 0) && ((derivativeBP - previousDerivativeBP) < 0) )
                                                                            {
                                                                                            if( *bandPassFiltered > pulseWave->workingMAPpressure )
                                                                                            {
                                                                                                            pulseWave->MAPpressure = ((Last128SamplesBuffer[(Last128SamplesBufferHead - BPfilterDelay) & 127] - 1638.0f) * 5.0f) / (14745.0f - 1638.0f) * 52.0f;
                                                                                                            pulseWave->workingMAPpressure = *bandPassFiltered;
                                                                                            }
                                                                            }
                                                            }
                                                           
                                                            //============  Variables update  =============//
                                                            previousDerivative = derivative;
                                                            previousValue = *lowPassFiltered;       
                                                            previousDerivativeBP = derivativeBP;
                                                            previousValueBP = *bandPassFiltered;         
                                                                   
                                                            //============  Ending calculations  ==============//
                                                            if( pulseWave->currentPressure < 50 )
                                                            {        
                                                                            LCDLocateXY(0,0);
                                                                            LCDSendText("SYS:");
                                                                            LCDLocateXY(7,0);
                                                                            LCDSendData(' ');
                                                                            LCDLocateXY(8,0);
                                                                            LCDSendText("DIA:");
                                                                   
                                                                            calculate = 0;
                                                                            calculateMAP = 0;
                                                                            TIM4->CR1 &= ~TIM_CR1_CEN;  // Turn off Timer controlling displaying on LCD
                                                                            displayOnLCDevery1sec = 0;
                                                                            displayOnLCDevery250milisec = 0;
                                                                            pulseWave->diastolicPressure = ( pulseWave->MAPpressure * 3 - pulseWave->systolicPressure ) / 2 ;  
                                                                   
                                                                            LCDLocateXY(4,0);
                                                                            LCDSend8bitInteger((uint8_t) pulseWave->systolicPressure);
                                                   
                                                                            LCDLocateXY(12,0);
                                                                            LCDSend8bitInteger((uint8_t) pulseWave->diastolicPressure);
                                   
                                                                            LCDLocateXY(0,1);
                                                                            LCDSendText("MAP:  ");
                                   
                                                                            LCDLocateXY(6,1);
                                                                            LCDSend8bitInteger((uint8_t) pulseWave->MAPpressure);
                                   
                                                                            LCDLocateXY(12,1);
                                                                            LCDSendText("    ");
                                                            }
                                    }                       
                    }
                    else
                    {
                                    if( pressureArrayHead != pressureArrayTail)
                                    {
                                                    //=======================   Filtration of data from pressure sensor   ========================//
                  IIR_4thOrderSignalFilteringPtByPt(LowpassIIRfilter, pressureArray[pressureArrayTail], lowPassFiltered);                                       
                                                            FIRfilterPtByPt(BandpassFIRfilter, pressureArray[pressureArrayTail], bandPassFiltered);

                                             //=======================  Update of buffers and variables values  ========================//
                                                            Last128SamplesBufferHead = (Last128SamplesBufferHead+1) & 127;
                                                            Last128SamplesBuffer[Last128SamplesBufferHead] = *lowPassFiltered;
                                                pressureArrayTail = (pressureArrayTail + 1) & pressureArrayMask;

                                                      pulseWave->currentPressure = ((*lowPassFiltered- 1638.0f) * 5.0f) / (14745.0f - 1638.0f) * 52.0f;
                                                      previousDerivative = *lowPassFiltered - previousValue;
                                                      previousDerivativeBP = *bandPassFiltered - previousValueBP;
                                                      previousValue = *lowPassFiltered;
                                                      previousValueBP = *bandPassFiltered;
                                    }
                    }

                    if(displayOnLCDevery250milisec)
                    {
                                    if(clearHeart)
                                    {
                                                    LCDLocateXY(8,0);
                                                    LCDSendData(' ');
                                                    clearHeart = 0;
                                    }
                                   
                                    if(displayHeart)
                                    {
                                                    LCDLocateXY(8,0);
                                                    LCDSendData(heart);
                                                    displayHeart = 0;
                                                    clearHeart = 1;
                                    }
                                   
                                    displayOnLCDevery250milisec = 0;
                    }
                   
                    if(displayOnLCDevery1sec)
                    {
                                    LCDLocateXY(12,1);
                                    LCDSend8bitInteger((uint8_t) pulseWave->currentPressure);
                           
                                    displayOnLCDevery1sec = 0;
                    }
            }
    }

  • 硬件和原理图,私信我。
  • 可以在外包板块找

您需要登录后才可以回复 登录 | 注册