找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2713|回复: 1
打印 上一主题 下一主题
收起左侧

通过光电对管测量脉搏的51单片机程序设计

[复制链接]
跳转到指定楼层
楼主
设计采用STC89C51作为主控芯片,采用ST188光电对管对脉搏信号进行采集,再由LM358将信号进行放大后由74HC14将方波信号整形后通过单片机的计数器进行采集,单片机通过定时器和计数器的配合使用,准确的计算出脉搏数后通过LCD1602进行实时显示脉搏测量信息。当没有在测量时候系统检测到会自动的停止测量,在下次检测到脉搏信号后又自动打开。


原理图如下:



单片机源程序如下:
  1. /*************************************************************
  2.                       脉搏计

  3. 补充说明:
  4. ***************************************************************/
  5. #include<reg52.h>                //头文件
  6. #include<INTERRUPT.h>
  7. #include<LCD1602.h>

  8. /************************引脚定义************************/
  9. sbit IN=P3^4;                    //脉搏信号输入
  10. /********************************************************
  11. 函数名称:void display()
  12. 函数作用:脉搏显示程序
  13. 参数说明:
  14. ********************************************************/
  15. void display()
  16. {
  17.         lcd1602_write_character(0,1,"Sphygmus:");  //显示脉搏数、【0:表示第1列,1:表示第1行,所有关于显示都一样】
  18.         LCD_disp_char(9,1,ASCII[maibo/100]);
  19.         LCD_disp_char(10,1,ASCII[maibo%100/10]);
  20.         LCD_disp_char(11,1,ASCII[maibo%10]);
  21.         lcd1602_write_character(12,1,"bpm");

  22.         lcd1602_write_character(0,2,"Time:");           //显示脉搏检测时间、【0:表示第1列,2:表示第2行,所有关于显示都一样】
  23.         LCD_disp_char(5,2,ASCII[T1_num/1000]);
  24.         LCD_disp_char(6,2,ASCII[T1_num%1000/100]);
  25.         LCD_disp_char(7,2,'s');

  26.         LCD_disp_char(10,2,ASCII[TL0/100]);                   //显示当前检测到的脉搏数、【10:表示第11列,2:表示第2行,所有关于显示都一样】
  27.         LCD_disp_char(11,2,ASCII[TL0%100/10]);
  28.         LCD_disp_char(12,2,ASCII[TL0%10]);        
  29.         lcd1602_write_character(13,2,"bpm");
  30. }
  31. /********************************************************
  32. 函数名称:void main()
  33. 函数作用:主函数
  34. 参数说明:
  35. ********************************************************/
  36. void main()
  37. {
  38.         T0_init();    //计数器0、定时器1初始化
  39.         LCD_init();   //LCD1602初始化
  40.         while(1)          //死循环
  41.         {
  42.                 if(IN==0) //检测到脉搏信号
  43.                         TR1=1;//自动开启检测计算脉搏。定时器1开启        
  44.                 display();//显示脉搏相关信息
  45.                 //计算脉搏
  46.                 if(TL0>=5)//如果采集到5个脉搏信号
  47.                 {
  48.                         TL0=0;//重置脉搏数量,重新计数
  49.                         if(T1_num<1000&&T1_num>150)//计算脉搏,条件就是满足5个脉搏信号用时大于1.5S且小于10S,否者都忽略
  50.                         {
  51.                                 if(T1_num<375)                   //脉搏大于80bmp时采用两次求和取平均方式提高精度
  52.                                         maibo=(maibo+30000/T1_num)/2;
  53.                                 else                                   //否者,直接计算脉搏
  54.                                         maibo=30000/T1_num;//脉搏=(5/(T1_num/100))*60=30000/T1_num;其中T1_num单位是10毫秒30000/375=80
  55.                         }
  56.                         T1_num=0;//重置计时
  57.                 }
  58.         }
  59. }

  60. #ifndef _INTERRUPT_H_
  61. #define _INTERRUPT_H_
  62. #include<reg52.h>
  63. #include<math.h>
  64. #define uchar unsigned char
  65. #define uint unsigned int
  66. #define MAX 6    //检测结束脉搏数量
  67. /************************引脚定义************************/
  68. sbit IN=P3^2;         //脉搏信号输入
  69. /************************变量定义************************/
  70. uchar T0_num=0;  //定时计数变量
  71. uint T0_nums=0;  //计时脉搏时间间隔变量
  72. uchar miao=0;         //测量时间秒钟
  73. uchar maibos=0;  //最终测量脉搏数
  74. uchar maibo=0;   //记录脉搏

  75. uchar T[MAX]={0};//记录已采集到的脉搏时间间隔
  76. uchar low=0;         //上一次脉搏时间间隔
  77. /*********************************************************
  78. 函数名称:void T0_init()
  79. 函数作用:计数器0、定时器1初始化函数
  80. 参数说明:
  81. *********************************************************/
  82. void T0_init()
  83. {
  84.         EA=1;                  //开总中断
  85.         TMOD=0x01;             //计数器0工作工作方式1  
  86.         ET0=1;                 //定时器T0中断允许         
  87.         TH0=(65536-10000)/256; //定时器T0的高8位赋初值
  88.         TL0=(65536-10000)%256; //定时器T0的低8位赋初值
  89.         TR0=0;                                   //关闭定时器
  90. }
  91. /*********************************************************
  92. 函数名称:void Int0_init()
  93. 函数作用:外部中断0初始化函数
  94. 参数说明:
  95. *********************************************************/
  96. void Int0_init()
  97. {
  98.         EA=1;                  //开放总中断         
  99.            IT0=1;                 //选择负跳变来触发外中断
  100.         EX0=0;                 //允许使用外中断         
  101. }
  102. /*********************************************************
  103. 函数名称:void T0_interrupt(void) interrupt 1
  104. 函数作用:定时器1中断处理函数
  105. 参数说明:10毫秒定时中断一次
  106. *********************************************************/
  107. void T0_interrupt(void) interrupt 1
  108. {                  
  109.         TH0=(65536-10000)/256;//定时器T0的高8位重新赋初值
  110.         TL0=(65536-10000)%256;//定时器T0的低8位重新赋初值
  111.         if(EX0==1)                          //开启脉搏检测
  112.         {
  113.                 T0_num++;                  //计数变量+1
  114.                 if(T0_num>=100)          //100*10ms=1S
  115.                 {
  116.                         T0_num=0;          //重置计数变量
  117.                         miao++;                  //秒+1
  118.                         if(miao>99)
  119.                                 miao=0;
  120.                 }


  121.                 T0_nums++;            //脉搏时间间隔变量+1
  122.                 if(T0_nums>=500)  //500*10ms=5S
  123.                 {
  124.                         miao=0;              //采集超时,清除所有变量
  125.                         maibo=0;
  126.                         EX0=0;              //关闭脉搏检测
  127.                         TR0=0;
  128.                 }
  129.         }     
  130. }
  131. /*********************************************************
  132. 函数名称:void init0(void) interrupt 0
  133. 函数作用:外部中断0中断处理函数
  134. 参数说明:
  135. *********************************************************/
  136. void init0(void) interrupt 0
  137. {
  138.         uchar i=0;
  139.         uint TS=0;
  140.         if(IN==0&&T0_nums>39)      //再次确认感应,并且距上一次感应的时间足够长,如果过短认为是波动放弃处理
复制代码

全部资料51hei下载地址:
脉搏计源程序代码(Keil).zip (125.67 KB, 下载次数: 29)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:729366 发表于 2020-4-14 22:55 | 只看该作者
proteus里只给单独一个是非门,怎么组成施密特
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表