设计采用STC89C51作为主控芯片,采用ST188光电对管对脉搏信号进行采集,再由LM358将信号进行放大后由74HC14将方波信号整形后通过单片机的计数器进行采集,单片机通过定时器和计数器的配合使用,准确的计算出脉搏数后通过LCD1602进行实时显示脉搏测量信息。当没有在测量时候系统检测到会自动的停止测量,在下次检测到脉搏信号后又自动打开。
原理图如下:
单片机源程序如下:
- /*************************************************************
- 脉搏计
- 补充说明:
- ***************************************************************/
- #include<reg52.h> //头文件
- #include<INTERRUPT.h>
- #include<LCD1602.h>
- /************************引脚定义************************/
- sbit IN=P3^4; //脉搏信号输入
- /********************************************************
- 函数名称:void display()
- 函数作用:脉搏显示程序
- 参数说明:
- ********************************************************/
- void display()
- {
- lcd1602_write_character(0,1,"Sphygmus:"); //显示脉搏数、【0:表示第1列,1:表示第1行,所有关于显示都一样】
- LCD_disp_char(9,1,ASCII[maibo/100]);
- LCD_disp_char(10,1,ASCII[maibo%100/10]);
- LCD_disp_char(11,1,ASCII[maibo%10]);
- lcd1602_write_character(12,1,"bpm");
- lcd1602_write_character(0,2,"Time:"); //显示脉搏检测时间、【0:表示第1列,2:表示第2行,所有关于显示都一样】
- LCD_disp_char(5,2,ASCII[T1_num/1000]);
- LCD_disp_char(6,2,ASCII[T1_num%1000/100]);
- LCD_disp_char(7,2,'s');
- LCD_disp_char(10,2,ASCII[TL0/100]); //显示当前检测到的脉搏数、【10:表示第11列,2:表示第2行,所有关于显示都一样】
- LCD_disp_char(11,2,ASCII[TL0%100/10]);
- LCD_disp_char(12,2,ASCII[TL0%10]);
- lcd1602_write_character(13,2,"bpm");
- }
- /********************************************************
- 函数名称:void main()
- 函数作用:主函数
- 参数说明:
- ********************************************************/
- void main()
- {
- T0_init(); //计数器0、定时器1初始化
- LCD_init(); //LCD1602初始化
- while(1) //死循环
- {
- if(IN==0) //检测到脉搏信号
- TR1=1;//自动开启检测计算脉搏。定时器1开启
- display();//显示脉搏相关信息
- //计算脉搏
- if(TL0>=5)//如果采集到5个脉搏信号
- {
- TL0=0;//重置脉搏数量,重新计数
- if(T1_num<1000&&T1_num>150)//计算脉搏,条件就是满足5个脉搏信号用时大于1.5S且小于10S,否者都忽略
- {
- if(T1_num<375) //脉搏大于80bmp时采用两次求和取平均方式提高精度
- maibo=(maibo+30000/T1_num)/2;
- else //否者,直接计算脉搏
- maibo=30000/T1_num;//脉搏=(5/(T1_num/100))*60=30000/T1_num;其中T1_num单位是10毫秒30000/375=80
- }
- T1_num=0;//重置计时
- }
- }
- }
- #ifndef _INTERRUPT_H_
- #define _INTERRUPT_H_
- #include<reg52.h>
- #include<math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define MAX 6 //检测结束脉搏数量
- /************************引脚定义************************/
- sbit IN=P3^2; //脉搏信号输入
- /************************变量定义************************/
- uchar T0_num=0; //定时计数变量
- uint T0_nums=0; //计时脉搏时间间隔变量
- uchar miao=0; //测量时间秒钟
- uchar maibos=0; //最终测量脉搏数
- uchar maibo=0; //记录脉搏
- uchar T[MAX]={0};//记录已采集到的脉搏时间间隔
- uchar low=0; //上一次脉搏时间间隔
- /*********************************************************
- 函数名称:void T0_init()
- 函数作用:计数器0、定时器1初始化函数
- 参数说明:
- *********************************************************/
- void T0_init()
- {
- EA=1; //开总中断
- TMOD=0x01; //计数器0工作工作方式1
- ET0=1; //定时器T0中断允许
- TH0=(65536-10000)/256; //定时器T0的高8位赋初值
- TL0=(65536-10000)%256; //定时器T0的低8位赋初值
- TR0=0; //关闭定时器
- }
- /*********************************************************
- 函数名称:void Int0_init()
- 函数作用:外部中断0初始化函数
- 参数说明:
- *********************************************************/
- void Int0_init()
- {
- EA=1; //开放总中断
- IT0=1; //选择负跳变来触发外中断
- EX0=0; //允许使用外中断
- }
- /*********************************************************
- 函数名称:void T0_interrupt(void) interrupt 1
- 函数作用:定时器1中断处理函数
- 参数说明:10毫秒定时中断一次
- *********************************************************/
- void T0_interrupt(void) interrupt 1
- {
- TH0=(65536-10000)/256;//定时器T0的高8位重新赋初值
- TL0=(65536-10000)%256;//定时器T0的低8位重新赋初值
- if(EX0==1) //开启脉搏检测
- {
- T0_num++; //计数变量+1
- if(T0_num>=100) //100*10ms=1S
- {
- T0_num=0; //重置计数变量
- miao++; //秒+1
- if(miao>99)
- miao=0;
- }
- T0_nums++; //脉搏时间间隔变量+1
- if(T0_nums>=500) //500*10ms=5S
- {
- miao=0; //采集超时,清除所有变量
- maibo=0;
- EX0=0; //关闭脉搏检测
- TR0=0;
- }
- }
- }
- /*********************************************************
- 函数名称:void init0(void) interrupt 0
- 函数作用:外部中断0中断处理函数
- 参数说明:
- *********************************************************/
- void init0(void) interrupt 0
- {
- uchar i=0;
- uint TS=0;
- if(IN==0&&T0_nums>39) //再次确认感应,并且距上一次感应的时间足够长,如果过短认为是波动放弃处理
复制代码
全部资料51hei下载地址:
脉搏计源程序代码(Keil).zip
(125.67 KB, 下载次数: 29)
|