打印

stm32血压计的设计

[复制链接]
3023|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
elsaflower|  楼主 | 2024-11-18 09:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
咕咕呱呱孤寡| | 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[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;
                }
        }
}

使用特权

评论回复
地板
gaochy1126| | 2024-11-30 21:21 | 只看该作者

stm32血压计的设计

硬件和原理图,私信我。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

1297

帖子

0

粉丝