因为最小系统都是那几样东西就没上这个图了,主要就是AT89S52+DS1302+24C02,还有就是用红外对管做的传感器模块。
光电脉搏检测的基本原理是:随着心脏的搏动,人体组织半透明度随之改变。当血液送到人体组织时,组织的半透明度减小;当血液流回心脏,组织的半透明度增大,这种现象在人体组织较薄的手指尖、耳垂等部位最为明显。利用波长600-1000nm的红光或红外发光二极管产生的光线照射到人体的手指尖、耳垂等部位,用装在该部位另一侧或同侧旁边的光电接收管来检测机体组织的透明程度,即可将搏动信息转换成电信号。
#include
#include "LCD12864.h"
#include "math.h"
#include "DS1302.h"
#include "AT24C02.H"
//#include "Draw_Sin.h"
//#include "System_Init.h"
#define uchar unsigned char
#define uint unsigned int
unsigned char chuzhi;
unsigned char flang1=0;
unsigned char DATA1;
#define Key_Start P1_0
#define Key_Return P1_1
#define Key_Find P1_2 //查询按键
#define Key_Sin P1_3 //查询按键
#define Bee P3_3
#define Inter P3_5
#define LED P1_4
sfr WDTRST =0xA6;
unsigned int k; //定义定时器中间变量
unsigned char Face=0; //界面变量
bit KeyStart_Switch; //定义开关允许位 为0时开关有效
bit Check_flag; //检测标志位 检测到脉搏时为1,否则为0
unsigned char H,L;
unsigned int Temp_fan,DATA;
bit Save_falg;
unsigned char Write_add; //量测完成后,24C0X写操作指向地址
unsigned char jayt; //进度条变量
unsigned char Num[4]; //显示缓存
bit Sleep_mode; //睡眠模式开启标志位,为1时为开启状态
bit alarm; //上下限报警标志位
unsigned char time[3]; //从24C0X取出的时间显示缓存
void read_24c02();
void Display_LCD12864_Face3();
void cunchu_24c02();
void Display_Auto_Mode();
void Timer0NCounterT1_Init();
void Rst_Watchdog(void); //看门狗拿来复位
void Cotrl_Key(); //按键控制
void Display_LCD12864_Face0(); //界面一
void Display_LCD12864_Face1(); //界面二
void Display_LCD12864_Face2(); //界面三
void Display_LCD12864_Face3(); //界面四
void Display_LCD12864_Face4(); //界面五
void Display_Auto_Mode(); //睡眠模式界面
void Timer0NCounterT1_Init()
{
EA=1;
TMOD=0X51;
TH0=0xd8;
TL0=0xf0;
ET0=1;
TH1=0X00;TL1=0X00;
ET1=1;
TR0=0;
TR1=1;
}
void Bee_Speak(unsigned int t)
{
Bee=0;LED=0;
delay_ms(t);
Bee=1;LED=1;
delay_ms(t);
}
void Rst_Watchdog(void) //看门狗拿来复位
{
WDTRST = 0x1E; //先赋值1E 然后赋值E1
WDTRST = 0xE1;
}
void Cotrl_Key()
{
if(Key_Start==0)
{
delay_ms(10);
if(Key_Start==0)
{
if(KeyStart_Switch==0)
{
TR1=0;
TH1=0X00; //
TL1=0X00; //计数器清零
TR0=1; //
TR1=1; //
Face=1; //切换到界面一
LcdWcom(0x01);
Bee_Speak(50);
KeyStart_Switch=1;
}
while(Key_Start==0);
}
}
if(Key_Return==0)
{
delay_ms(10);
if(Key_Return==0)
{
Rst_Watchdog(); // 复位
Bee_Speak(50);
}
}
if(Key_Find==0) //查询按键
{
delay_ms(50);
if(Key_Find==0)
{
if(Face==0||Face==2||Face==3||Face==4) //待机状态下
{
TL1=0;
TR1=0;
Face=3; //查询界面
Check_flag=1; //关闭自动模式
Display_LCD12864_Face3();
Bee_Speak(50);
}
while(Key_Find==0);
}
}
}
void Display_LCD12864_Face0()
{
if(Check_flag==0)
{
if(TL1==1){Display_HZ_Line(0,0,">>");}
if(TL1==2){Display_HZ_Line(0,0,">>> ");}
if(TL1==3){Display_HZ_Line(0,0,">>>>");}
if(TL1==4){Display_HZ_Line(0,0,">>>>> ");}
}
Display_HZ_Line(1,1,"尝试检测脉搏");
Display_HZ_Line(2,2,"请您放好");
time_display();
delay_ms(80);
Check_flag=0;
Display_Auto_Mode();
}
void Display_LCD12864_Face1()
{
unsigned char i;
unsigned char Num[3]; //显示缓存
unsigned char Temp;
Display_HZ_Line(0,0,"测量中....");
delay_ms(80);
if(jayt==0){Display_HZ_Line(2,0,"10%>> ");}
if(jayt==1){Display_HZ_Line(2,0,"29%>>>");}
if(jayt==2){Display_HZ_Line(2,0,"42%>>>>>");}
if(jayt==3){Display_HZ_Line(2,0,"57%>>>>>>>");}
if(jayt==4){Display_HZ_Line(2,0,"77%>>>>>>>>>");}
if(jayt==5){Display_HZ_Line(2,0,"95%>>>>>>>>>>>");}
delay_ms(20);
H=TH1; //读取计数值高位
L=TL1; //读取计数值低位
Temp=H*256+L; //合成总数 16位
Num[0]= Temp/100;
Num[1]= Temp0/10;
Num[2]= Temp;
LcdWcom(0x90+0x05); //显示计数值
for(i=0;i
{
LcdWdata(Num+'0');
}
delay_ms(20);
time_display();
delay_ms(20);
}
void Display_LCD12864_Face2()
{
unsigned char i;
jayt=0; //清除进度条殘影
if(flang1==1) //清除第二行留下的殘影
{
LcdWcom(0x01);
delay_ms(50);
flang1=0;
}
if(Save_falg==1) //写入24C0X标志位为1,数据写入24C0X
{
for(i=5;i>1;i--)
{
write_AT24C02_ADD(20+i,read_AT24C02_ADD(20+i-1)); //存储数据
delay_ms(50); //AT24C02_init();
write_AT24C02_ADD(70+i,read_AT24C02_ADD(70+i-1)); //存储时间
delay_ms(50); //AT24C02_init();
write_AT24C02_ADD(80+i,read_AT24C02_ADD(80+i-1)); //
delay_ms(50);//AT24C02_init();
write_AT24C02_ADD(90+i,read_AT24C02_ADD(90+i-1)); //
delay_ms(50); // AT24C02_init();
write_AT24C02_ADD(50,i); //存入地址变量,防止乱写
delay_ms(50); // AT24C02_init();
Save_falg=0; //写入标志位清0
}
write_AT24C02_ADD(20+1,DATA); //存储数据
delay_ms(50);// AT24C02_init();
write_AT24C02_ADD(70+1,shi); //存储时间
delay_ms(50); //AT24C02_init();
write_AT24C02_ADD(80+1,fen); //
delay_ms(50);//AT24C02_init();
write_AT24C02_ADD(90+1,miao); //
delay_ms(50); // AT24C02_init();
write_AT24C02_ADD(50,1); //存入地址变量,防止乱写
delay_ms(50); // AT24C02_init();
Save_falg=0;
}
if(alarm==1){Display_HZ(1,2,"异");Display_HZ(1,3,"常");Display_HZ(1,4,"!");} //上下限报警
else {Display_HZ(1,2,"无");Display_HZ(1,3,"异");Display_HZ(1,4,"常");}
delay_ms(70);
Display_HZ_Line(0,0,"您的量测结果是: ");
delay_ms(70);
LcdWcom(0x88+0x02); //显示最终结果
for(i=0;i
{
LcdWdata(Num+'0');
delay_ms(10);
}
Display_HZ_Line(2,4,"次/ 分钟");
delay_ms(70);
time_display(); //显示时间
}
void Display_LCD12864_Face3()
{
unsigned char Read_add; //查询模式下,24C0X读操作指向地址
LcdWcom(0x01); //清屏
delay_ms(20);
Read_add++;
if(Read_add==6)Read_add=1;
DATA1=read_AT24C02_ADD(20+Read_add); //取出数据
delay_ms(50);
time[0]=read_AT24C02_ADD(70+Read_add); //取出时间
delay_ms(50);
time[1]=read_AT24C02_ADD(80+Read_add);
delay_ms(50);
time[2]=read_AT24C02_ADD(90+Read_add);
delay_ms(50);
Display_HZ(0,1,"第");
delay_ms(5);
LcdWcom(0x80+0x02);
LcdWdata(Read_add+'0');
delay_ms(1);
Display_HZ(0,3,"次");
delay_ms(1);
Display_HZ(0,4,"量");
delay_ms(1);
Display_HZ(0,5,"测");
delay_ms(1);
Display_HZ(0,6,"结");
delay_ms(1);
Display_HZ(0,7,"果");
LcdWcom(0x89);
LcdWdata(DATA1/100+'0');
LcdWdata(DATA10/10+'0');
LcdWdata(DATA1+'0');
Display_HZ(2,3,"次");
LcdWcom(0x88+0x04);
LcdWdata('/');
Display_HZ(2,5,"分");
Display_HZ(2,6,"钟");
delay_ms(1);
LcdWcom(0x98); //显示读取出来的时间
LcdWdata(time[0]/10+'0');
LcdWdata(time[0]+'0');
LcdWdata(':');
LcdWdata(time[1]/10+'0');
LcdWdata(time[1]+'0');
LcdWdata(':');
LcdWdata(time[2]/10+'0');
LcdWdata(time[2]+'0');
}
void Display_Auto_Mode()
{
if(Check_flag==0) //自动启动模式
{
if(TL1>2) //判断
{
if(TL1>4) //再次判断
{
delay_ms(50);
if(TL1>5) //再再次判断
{
TR1=0;
TH1=0X00; //
TL1=0X00; //计数器清零
TR0=1; //
TR1=1; //
Bee_Speak(200);
Check_flag=1;
Face=1;
LcdWcom(0x01);
}
}
}
}
}
void main()
{
unsigned char i;
Timer0NCounterT1_Init();
AT24C02_init();
reset_1302();
Display_Init();
sheshi();
Write_add=read_AT24C02_ADD(50);
// Display_Welcom1();
GUI_Fill_GDRAM(0x00);
Bee_Speak(70);
while(1)
{
Cotrl_Key();
if(Face==0){Display_LCD12864_Face0();}
if(Face==1){Display_LCD12864_Face1();}
if(Face==2)
{
Display_LCD12864_Face2();
i++;
if(i==10)
{
Sleep_mode=1;
TR1=1;
Face=4;
chuzhi=1;
}
}
if(Face==4){time_display();}
}
}
void Timer0(void) interrupt 1
{
uchar i,j,Temp;
uchar Temp_Data[3];
uchar H1,L1;
TH0=0xd8;
TL0=0xf0;
k++;
if(k==500||k==1000)jayt++; //进度条取样
if(Sleep_mode==0) //正常测量模式
{
if(k==1000) //1000=10s定时
{
k=0;
j++;
H1=TH1; //读取计数值高位
L1=TL1; //读取计数值低位
Temp_Data=H1*256+L1; //采样3次,取出数据
if(j==3) //j=3,为采集3次,每次采集10s,共30s
{
// TR1=0; //关闭计数
// TR0=0; //关闭定时
j=0;
DATA=(Temp_Data[0]+Temp_Data[1]+Temp_Data[2])/3; //求平均值
DATA=DATA*6; //*6推算得到60S时的值
if((DATA>120)||(DATA
else alarm=0;
Num[0]= DATA/100;
Num[1]= DATA0/10;
Num[2]= DATA;
Bee_Speak(50);
Face=2; //进入界面二
Save_falg=1; //数据写入24C0X允许标志位,为1时允许写入,写完后清0
flang1=1; //某标志位,用于清屏
}
}
}
else if(Sleep_mode==1) //正常测量模式
{
if(k==500)
{
k=0;
TR1=1;
TR0=1;
L1=TL1;
Temp=L1;
if((chuzhi==1)&&(Temp==0)) //判断手指是否拿出
{
chuzhi=0;
LED=0;
}
if((chuzhi==0)&&(Temp>2)) //判断手指是否放入
{
LED=0;
Rst_Watchdog();
}
TL1=0; TH1=0;
}
}
}