elsaflower 发表于 2024-11-18 09:49

stm32血压计的设计

来一套stm32血压计的设计,使用示波法测量,下降趋势。测量周期为20s内,最好能够输出测量的波形

咕咕呱呱孤寡 发表于 2024-11-30 15:51

可以在外包板块找

gaochy1126 发表于 2024-11-30 21:17

stm32血压计的设计

#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;

//==== Circular buffers to pass into FIRfilterObject ===//
float signalBufferForBandpassFIRfilter;


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("pressbutton   ");
                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, lowPassFiltered);
                                                        FIRfilterPtByPt(BandpassFIRfilter, pressureArray, 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 = *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, lowPassFiltered);                                       
                                                        FIRfilterPtByPt(BandpassFIRfilter, pressureArray, bandPassFiltered);

                                       //=======================Update of buffers and variables values========================//
                                                        Last128SamplesBufferHead = (Last128SamplesBufferHead+1) & 127;
                                                        Last128SamplesBuffer = *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;
                }
        }
}

gaochy1126 发表于 2024-11-30 21:21

stm32血压计的设计

硬件和原理图,私信我。
页: [1]
查看完整版本: stm32血压计的设计