#include "Main.h"
#include "stm32f10x_conf.h"
#include "DataType.h"
#include "NVIC.h"
#include "SysTick.h"
#include "RCC.h"
#include "Timer.h"
#include "UART1.h"
#include "LED.h"
#include "PackUnpack.h"
#include "SendDataToHost.h"
#include "ADC.h"
#include "DAC.h"
#include "Wave.h"
#include "ProcHostCmd.h"
#include "Filter.h"
#include "Frequency.h"
#include "SPO2.h"
#include<stdio.h>
static void InitSoftware(void); //初始化软件相关的模块
static void InitHardware(void); //初始化硬件相关的模块
static void Proc2msTask(void); //2ms处理任务
static void Proc1SecTask(void); //1s处理任务
//KalmanFilter Kalman;
//NotchFilter Notch;
IIRNotchFilter filter;
SecondOrderLPF f;
static uint8_t direction=0;
static uint8_t index=0;
static uint8_t heartrate;
static float last_wave=0;
static float peak;
static void InitSoftware(void)
{
InitPackUnpack(); //初始化PackUnpack模块
InitSendDataToHost(); //初始化SendDataToHost模块
InitProcHostCmd(); //初始化ProcHostCmd模块
IIRNotch_Init(&filter) ;
initFilter(&f,500, 100) ;
// Kalman_Init(&Kalman ,0.01,0.5,0);
}
static void InitHardware(void)
{
SystemInit(); //系统初始化
InitRCC(); //初始化RCC模块
InitNVIC(); //初始化NVIC模块
InitUART1(115200); //初始化UART模块
InitTimer(); //初始化Timer模块
InitLED(); //初始化LED模块
InitSysTick(); //初始化SysTick模块
InitADC(); //初始化ADC模块
InitDAC(); //初始化DAC模块
}
static void Proc2msTask(void)
{
u16 adcData; //队列数据
u16 waveData; //波形数据
u8 uart1RecData; //串口数据
static u8 s_iCnt4 = 0; //计数器
static u8 s_iPointCnt = 0; //波形数据包的点计数器
static u8 s_arrWaveData[5] = {0}; //初始化数组
if(Get2msFlag()) //判断2ms标志状态
{
// if(ReadUART1(&uart1RecData, 1)) //读串口接收数据
// {
// ProcHostCmd(uart1RecData); //处理命令
// }
s_iCnt4++; //计数增加
if(s_iCnt4 >= 2) //达到2ms
{
if(ReadADCBuf(&adcData)) //从缓存队列中取出1个数据
{
waveData = (adcData * 5)/ 4095; //计算获取点的位置
waveData = IIRNotch_Update(&filter, waveData);
waveData = filterSample(&f, waveData) ;
s_arrWaveData[s_iPointCnt] = waveData; //存放到数组
// waveData = notchFilter(&Notch,waveData);
// waveData = Kalman_FIlter(&Kalman,waveData);
// CalHeartRate(waveData,&last_wave,&peak,&index,100,&heartrate,&direction);
// printf("[[2,%d Hz]]\r\n",heartrate);
printf("%d\r\n",waveData);
s_iPointCnt++; //波形数据包的点计数器加1操作
if(s_iPointCnt >= 5) //接收到5个点
{
s_iPointCnt = 0; //计数器清零
SendWaveToHost(s_arrWaveData); //发送波形数据包
}
}
s_iCnt4 = 0; //准备下次的循环
}
LEDFlicker(250);//调用闪烁函数
Clr2msFlag(); //清除2ms标志
}
}
static void Proc1SecTask(void)
{
if(Get1SecFlag()) //判断1s标志状态
{
Clr1SecFlag(); //清除1s标志
}
}
int main(void)
{
InitSoftware(); //初始化软件相关函数
InitHardware(); //初始化硬件相关函数
// InitNotchFilter(&Notch,500.0,0.99);
// printf("Init System has been finished.\r\n" ); //打印系统状态
printf("{{2,Rate}}\r\n");
while(1)
{
Proc2msTask(); //2ms处理任务
Proc1SecTask(); //1s处理任务
}
}
#include "stm32f10x_conf.h"
#include "Filter.h"
#include<math.h>
#define PI 3.1415926535f
#define FS 500.0f // 采样频率200Hz
#define F0 50.0f // 陷波频率50Hz
#define Q 1.0f // Q因子
//void Kalman_Init(KalmanFilter *KL ,float Q_pra,float R_pra,float Init_x)
//{
// //预测
// KL->Q = Q_pra;
// KL->R = R_pra;
// KL->x = Init_x;
// KL->K = 1.5f;
//}
//float Kalman_FIlter( KalmanFilter *kl,float Value)
//{
// float x_pred,p_pred;
// x_pred = kl->x;
// p_pred = kl->P +kl->Q;
// kl->K = p_pred/(p_pred+kl->R);
// kl->x = x_pred + kl->K*(Value-x_pred);
// kl->P = (1-kl->K)*p_pred;
// return kl->x;
//}
//void InitNotchFilter(NotchFilter *f,float Fs,float r)
//{
// const float f0 = 50.0;
// const float W0 = 2*(float)(PI*f0/Fs);
// const float cos0 = cosf(W0);
//
// f->b0 = 1.0f;
// f->b1 = -2*cos0;
// f->b2 = 1.0f;
// f->a0 = 2*cos0*r;
// f->a1 = -r*r;
//
// f->x1 = 0.0f;
// f->x2 = 0.0f;
// f->y1 = 0.0f;
// f->y2 = 0.0f;
//}
//float notchFilter(NotchFilter *f,float x)
//{
// float y;
// y = f->b0*x+f->b1*f->x1+f->b2*f->x2+f->a0*f->y1-f->a1*f->y2;
// f->x2 = f->x1;
// f->x1 = x;
// f->y2 = f->y1;
// f->y1 = y;
// return y;
//}
void IIRNotch_Init(IIRNotchFilter *filt)
{
float w0;
float alpha;
float a0;
w0 = 2 * PI * F0 / FS;
alpha = sinf(w0) / (2 * Q);
a0 = 1 + alpha;
filt->b0 = 1 / a0;
filt->b1 = -2 * cosf(w0) / a0;
filt->b2 = 1 / a0;
filt->a1 = -2 * cosf(w0) / a0;
filt->a2 = (1 - alpha) / a0;
filt->x1 = 0; filt->x2 = 0; filt->y1 = 0; filt->y2 = 0; // 初始化状态
}
float IIRNotch_Update(IIRNotchFilter *filt, float input)
{
float output = filt->b0 * input + filt->b1 * filt->x1 + filt->b2 * filt->x2
- filt->a1 * filt->y1 - filt->a2 * filt->y2;
// 更新状态
filt->x2 = filt->x1;
filt->x1 = input;
filt->y2 = filt->y1;
filt->y1 = output;
return output;
}
// 初始化滤波器系数 (基于Butterworth设计)
void initFilter(SecondOrderLPF *f, float fs, float fc)
{
// 计算归一化截止频率
float omega;
float k ; // 双线性变换预扭曲
float k_sq;
float sqrt2;
// 计算Butterworth二阶低通系数
float denom ;
omega = 2 * PI * fc / fs;
k = tanf(omega / 2);
sqrt2 = sqrtf(2.0f);
k_sq = k * k;
denom = 1 + sqrt2 * k + k_sq;
f->b0 = 1 / denom;
f->b1 = 2 * f->b0;
f->b2 = f->b0;
f->a1 = 2 * f->b0 * (1 - k_sq);
f->a2 = f->b0 * (1 - sqrt2 * k + k_sq);
// 初始化状态变量
f->w1 = 0;
f->w2 = 0;
}
// 处理单样本输入 (ADC数据)
float filterSample(SecondOrderLPF *f, float input)
{
// 直接形式II实现: w0 = input - a1*w1 - a2*w2
float w0;
// 输出 = b0*w0 + b1*w1 + b2*w2
float output ;
w0 = input - f->a1 * f->w1 - f->a2 * f->w2;
output = f->b0 * w0 + f->b1 * f->w1 + f->b2 * f->w2;
// 更新状态变量
f->w2 = f->w1; // 移动历史值
f->w1 = w0;
return output;
}
#ifndef _FILTER_H_
#define _FILTER_H_
typedef struct
{
float x; // 状态估计值(滤波结果)
float P; // 估计协方差
float Q; // 过程噪声协方差
float R; // 测量噪声协方差
float K; // 卡尔曼增益
} KalmanFilter;
//typedef struct
//{
// float x1;
// float x2;
// float y1;
// float y2;
// float b0,b1,b2;
// float a0,a1;
//}NotchFilter;
// 定义滤波器结构体(使用定点数优化)
typedef struct {
float b0, b1, b2, a1, a2;
float x1, x2, y1, y2; // 状态变量(x[n-1], x[n-2], y[n-1], y[n-2])
} IIRNotchFilter;
// 定义二阶低通滤波器结构体
typedef struct
{
float b0, b1, b2; // 分子系数
float a1, a2; // 分母系数 (a0 默认为1)
float w1, w2; // 状态变量 (存储历史值)
} SecondOrderLPF;
void IIRNotch_Init(IIRNotchFilter *filt) ;
float IIRNotch_Update(IIRNotchFilter *filt, float input) ;
void initFilter(SecondOrderLPF *f, float fs, float fc) ;
float filterSample(SecondOrderLPF *f, float input) ;
//float Kalman_FIlter( KalmanFilter *kl,float Value);
//void Kalman_Init(KalmanFilter *KL ,float Q_pra,float R_pra,float Init_x);
//void InitNotchFilter(NotchFilter *f,float Fs,float r);
//float notchFilter(NotchFilter *f,float x);
#endif
进行对ECG信号的心率的计算
最新发布