心率计设计
时间:10-02
整理:3721RD
点击:
采样频率确定为125H z。波峰是这样确定的:
首先设定门限。在每一数据段512个样本数据中, 寻找最大
值Max, 定义门限t= 0. 8M ax。
如果某点满足下面两个条件, 则认为此点为波峰。
( 1)此点及前后各5点, 共11个样本均值大于门限t。
( 2)此点为11个样本点中的局部最大值。
确定了波峰, 就可按上面的公式计算出脉率。
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="THE PAUSE RATE:";
sbit beep=P2^3;
sbit lcden=P3^4; //液晶使能端
sbit lcdrs=P3^5; //液晶数据命令选择端
sbit dula=P2^6; //申明U1锁存器的锁存端
sbit wela=P2^7; //申明U2锁存器的锁存端
sbit adwr=P3^6; //定义A/D的WR端口
sbit adrd=P3^7; //定义A/D的RD端口
uchar xdata a[500];
/*
uchar timer2_ctr,num;
void T2_time() interrupt 5
{
TF2=0;
timer2_ctr++;
TH2=(65536-750)/256;
TL2=(65536-750)%256;
num++; //定时6秒
if(num==120)
{
num=0;
//AD关
}
}
*/
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
dula=0;
wela=0;
lcden=0;
write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
write_com(0x0c); //设置开显示,不显示光标
write_com(0x06); //写一个字符后地址指针加1
write_com(0x01); //显示清0,数据指针清0
}
void warm() //报警
{
beep=0; //响
delay(5000);
beep=1;
}
uchar deal(uchar a[500]) //心率计算 ?
{
// uchar xdata a[500];
uint n,i,j,k,Max;
uint number;
uchar c[10];
float t;
Max=a[0];
for(i=1;i<=500;i++)
{
if(a[i]>Max)
Max=a[i];
}
t=0.8*Max;
j=0;
for(i=8;i<493;i++)
{if(a[i-8]>t&&a[i-7]>t&&a[i-6]>t&&a[i-5]>t&&a[i-4]>t&&a[i-3]>t&&a[i-2]>t&&a[i-1]>t&&a[i]>t&&a[i+1]>t&&a[i+2]>t&&a[i+3]>t&&a[i+4]>t&&a[i+5]>t&&a[i+6]>t&&a[i+7]>t&&a[i+8]>t)
{
if(a[i]>a[i-8]&&a[i]>a[i-7]&&a[i]>a[i-6]&&a[i]>a[i-5]&&a[i]>a[i-4]&&a[i]>a[i-3]&&a[i]>a[i-2]&&a[i]>a[i-1]&&a[i]>a[i+1]&&a[i]>a[i+2]&&a[i]>a[i+3]&&a[i]>a[i+4]&&a[i]>a[i+5]&&a[i]>a[i+6]&&a[i]>a[i+7]&&a[i]>a[i+8])
{
k++;
c[j]=i;
j++;
}
}
}
number=(c[j]-c[0])/k;
if(number<60|number>100)
{
// warm();
}
n=(150*60)/number;
return n;
}
void display()
{
uint n,num;
write_com(0x80);
for(num=0;num<16;num++)
{
write_data(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<3;num++)
{
write_data(n);
delay(5);
}
}
void main()
{
uint i;
wela=1;
P0=0x7f; //ad片选
wela=0;
init();
display();
for(i=0;i<500;i++)
{
adwr=1;
_nop_();
adwr=0;
_nop_();
adwr=1;
delay(1);
P1=0xff;
adrd=1;
_nop_();
adrd=0;
_nop_();
adrd=1;
_nop_();
a[i]=P1;
//延时
delay(4);
}
if (i==500);
{
deal(a);
}
display(); //输出
}
仿真数据总是不显示,是AD采集的错误还是数据处理的错误?
首先设定门限。在每一数据段512个样本数据中, 寻找最大
值Max, 定义门限t= 0. 8M ax。
如果某点满足下面两个条件, 则认为此点为波峰。
( 1)此点及前后各5点, 共11个样本均值大于门限t。
( 2)此点为11个样本点中的局部最大值。
确定了波峰, 就可按上面的公式计算出脉率。
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="THE PAUSE RATE:";
sbit beep=P2^3;
sbit lcden=P3^4; //液晶使能端
sbit lcdrs=P3^5; //液晶数据命令选择端
sbit dula=P2^6; //申明U1锁存器的锁存端
sbit wela=P2^7; //申明U2锁存器的锁存端
sbit adwr=P3^6; //定义A/D的WR端口
sbit adrd=P3^7; //定义A/D的RD端口
uchar xdata a[500];
/*
uchar timer2_ctr,num;
void T2_time() interrupt 5
{
TF2=0;
timer2_ctr++;
TH2=(65536-750)/256;
TL2=(65536-750)%256;
num++; //定时6秒
if(num==120)
{
num=0;
//AD关
}
}
*/
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
dula=0;
wela=0;
lcden=0;
write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
write_com(0x0c); //设置开显示,不显示光标
write_com(0x06); //写一个字符后地址指针加1
write_com(0x01); //显示清0,数据指针清0
}
void warm() //报警
{
beep=0; //响
delay(5000);
beep=1;
}
uchar deal(uchar a[500]) //心率计算 ?
{
// uchar xdata a[500];
uint n,i,j,k,Max;
uint number;
uchar c[10];
float t;
Max=a[0];
for(i=1;i<=500;i++)
{
if(a[i]>Max)
Max=a[i];
}
t=0.8*Max;
j=0;
for(i=8;i<493;i++)
{if(a[i-8]>t&&a[i-7]>t&&a[i-6]>t&&a[i-5]>t&&a[i-4]>t&&a[i-3]>t&&a[i-2]>t&&a[i-1]>t&&a[i]>t&&a[i+1]>t&&a[i+2]>t&&a[i+3]>t&&a[i+4]>t&&a[i+5]>t&&a[i+6]>t&&a[i+7]>t&&a[i+8]>t)
{
if(a[i]>a[i-8]&&a[i]>a[i-7]&&a[i]>a[i-6]&&a[i]>a[i-5]&&a[i]>a[i-4]&&a[i]>a[i-3]&&a[i]>a[i-2]&&a[i]>a[i-1]&&a[i]>a[i+1]&&a[i]>a[i+2]&&a[i]>a[i+3]&&a[i]>a[i+4]&&a[i]>a[i+5]&&a[i]>a[i+6]&&a[i]>a[i+7]&&a[i]>a[i+8])
{
k++;
c[j]=i;
j++;
}
}
}
number=(c[j]-c[0])/k;
if(number<60|number>100)
{
// warm();
}
n=(150*60)/number;
return n;
}
void display()
{
uint n,num;
write_com(0x80);
for(num=0;num<16;num++)
{
write_data(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<3;num++)
{
write_data(n);
delay(5);
}
}
void main()
{
uint i;
wela=1;
P0=0x7f; //ad片选
wela=0;
init();
display();
for(i=0;i<500;i++)
{
adwr=1;
_nop_();
adwr=0;
_nop_();
adwr=1;
delay(1);
P1=0xff;
adrd=1;
_nop_();
adrd=0;
_nop_();
adrd=1;
_nop_();
a[i]=P1;
//延时
delay(4);
}
if (i==500);
{
deal(a);
}
display(); //输出
}
仿真数据总是不显示,是AD采集的错误还是数据处理的错误?
proteus仿真图
不错的文件,值得收藏