基于STM32 Pulse sensor心率模块测试 上位机显示心跳数据
一. 实现功能
上电后上位机显示心跳脉冲线条和心率数据,如图
二. 硬件清单
- Pulse sensor心率模块
- STM32F103C8T6/STC89C52RC(此单片机无AD故没法使用)
- SWD或JLINK仿真器(直接用CH340串口模块烧录也行,不过注意配置BOOT)
- 杜邦线若干
三. 资料清单
程序代码
文档资料
四. 模块简介
1.基本参数
详情看这两份文档就好
2.引脚说明
五. 接线
基于STM32 +模块接线
模块--------- ------------------------ STM32
VCC-----------------------------------3.3V
GND-----------------------------------GND
S----------------- ---------------- - GPIOA_0(AD1通道0)
六.代码说明
以下以32代码为例, OLED相关链接:
1. AD1通道0配置
static void ADCx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(ADC_PORT, &GPIO_InitStructure);
}
static void ADCx_Mode_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE ;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADCx, &ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1,
ADC_SampleTime_55Cycles5);
ADC_Cmd(ADCx, ENABLE);
ADC_ResetCalibration(ADCx);
while(ADC_GetResetCalibrationStatus(ADCx));
ADC_StartCalibration(ADCx);
while(ADC_GetCalibrationStatus(ADCx));
ADC_SoftwareStartConvCmd(ADCx, ENABLE);
}
2. 定时器TIM3初始化函数
static void GENERAL_TIM_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = GENERAL_TIM_IRQ ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void GENERAL_TIM_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK, ENABLE);
TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period;
TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);
TIM_ClearFlag(GENERAL_TIM, TIM_FLAG_Update);
TIM_ITConfig(GENERAL_TIM,TIM_IT_Update,ENABLE);
TIM_Cmd(GENERAL_TIM, ENABLE);
}
3. 获取AD值并滤波,心率计算函数
注:,此函数放在定时器中断中
void GENERAL_TIM_IRQHandler()
{
unsigned int runningTotal;
int i;
if (ADC_GetFlagStatus(ADCx,ADC_FLAG_EOC)==SET)
{
Signal = ADC_GetConversionValue(ADCx)>>2;
}
ADC_ClearFlag(ADCx,ADC_FLAG_EOC);
sampleCounter += 2;
Num = sampleCounter - lastBeatTime;
if(Signal < thresh && Num > (IBI/5)*3)
{
if (Signal < T)
{
T = Signal;
}
}
if(Signal > thresh && Signal > P)
{
P = Signal;
}
if (Num > 250)
{
if ( (Signal > thresh) && (Pulse == false) && (Num > (IBI/5)*3) )
{
Pulse = true;
IBI = sampleCounter - lastBeatTime;
lastBeatTime = sampleCounter;
if(secondBeat)
{
secondBeat = false;
for( i=0; i<=9; i++)
{
rate[i] = IBI;
}
}
if(firstBeat)
{
firstBeat = false;
secondBeat = true;
return;
}
runningTotal = 0;
for( i=0; i<=8; i++)
{
rate[i] = rate[i+1];
runningTotal += rate[i];
}
rate[9] = IBI;
runningTotal += rate[9];
runningTotal /= 10;
BPM = 60000/runningTotal;
QS = true;
}
if (Signal < thresh && Pulse == true)
{
Pulse = false;
amp = P - T;
thresh = amp/2 + T;
P = thresh;
T = thresh;
}
if (Num > 2500)
{
thresh = 512;
P = 512;
T = 512;
lastBeatTime = sampleCounter;
firstBeat = true;
secondBeat = false;
}
}
TIM_ClearITPendingBit(GENERAL_TIM , TIM_FLAG_Update);
}
4. 主函数
int main(void)
{
USART_Config();
GENERAL_TIM_Init();
ADCx_Init();
DelayInit();
while (1)
{
sendDataToProcessing('S', Signal);
if (QS == true)
{
sendDataToProcessing('B',BPM);
sendDataToProcessing('Q',IBI);
QS = false;
}
DelayMs(20);
}
}
七.资料获取
加群私聊群主可免费获得,也可加群学习交流 群号:1041406448。
|