久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1765|回復: 1
打印 上一主題 下一主題
收起左側

基于單片機的脈搏測量儀設計

[復制鏈接]
跳轉到指定樓層
樓主
ID:918467 發表于 2021-5-12 19:32 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include <reg52.h>                 //調用單片機頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義        變量范圍0~255
  3. #define uint  unsigned int         //無符號整型 宏定義        變量范圍0~65535
  4. #include <intrins.h>
  5. #include "eeprom52.h"

  6. sbit beep = P2^0;   //蜂鳴器IO口定義

  7. sbit k1 = P1^3;
  8. sbit k2 = P1^4;
  9. sbit k3 = P1^5;

  10. bit flag_300ms ;
  11. uchar flag_en;

  12. uchar code table_num[]="0123456789abcdefg";

  13. sbit rs=P1^0;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  14. sbit rw=P1^1;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  15. sbit e =P1^2;         //片選信號   下降沿觸發

  16. char flag=0,bj=90;
  17. unsigned char i=0,timecount=0,displayOK=0,aa=0;
  18. float time[6]={0};
  19. uint rate;

  20. float rate1[6];


  21. /***********************1ms延時函數*****************************/
  22. void delay_1ms(uint q)
  23. {
  24.         uint i,j;
  25.         for(i=0;i<q;i++)
  26.                 for(j=0;j<110;j++);
  27. }


  28. /********************************************************************
  29. * 名稱 : delay_uint()
  30. * 功能 : 小延時。
  31. * 輸入 : 無
  32. * 輸出 : 無
  33. ***********************************************************************/
  34. void delay_uint(uint q)
  35. {
  36.         while(q--);
  37. }

  38. /******************把數據保存到單片機內部eeprom中******************/
  39. void write_eeprom()
  40. {
  41.         SectorErase(0x2000);
  42.         byte_write(0x2000, bj % 256);
  43.         byte_write(0x2001, bj / 256);
  44.         byte_write(0x2058, a_a);       
  45. }

  46. /******************把數據從單片機內部eeprom中讀出來*****************/
  47. void read_eeprom()
  48. {
  49.         bj  = byte_read(0x2001);
  50.         bj<<= 8;
  51.         bj  |= byte_read(0x2000);
  52.         a_a      = byte_read(0x2058);
  53. }

  54. /**************開機自檢eeprom初始化*****************/
  55. void init_eeprom()
  56. {
  57.         read_eeprom();                //先讀
  58.         if(a_a != 1)                //新的單片機初始單片機內問eeprom
  59.         {
  60.                 bj = 95;
  61.                 a_a = 1;
  62.                 write_eeprom();           //保存數據
  63.         }       
  64. }


  65. /********************************************************************
  66. * 名稱 : write_com(uchar com)
  67. * 功能 : 1602命令函數
  68. * 輸入 : 輸入的命令值
  69. * 輸出 : 無
  70. ***********************************************************************/
  71. void write_com(uchar com)
  72. {
  73.         e=0;
  74.         rs=0;
  75.         rw=0;
  76.         P0=com;
  77.         delay_uint(25);
  78.         e=1;
  79.         delay_uint(100);
  80.         e=0;
  81. }

  82. /********************************************************************
  83. * 名稱 : write_data(uchar dat)
  84. * 功能 : 1602寫數據函數
  85. * 輸入 : 需要寫入1602的數據
  86. * 輸出 : 無
  87. ***********************************************************************/
  88. void write_data(uchar dat)
  89. {
  90.         e=0;
  91.         rs=1;
  92.         rw=0;
  93.         P0=dat;
  94.         delay_uint(25);
  95.         e=1;
  96.         delay_uint(100);
  97.         e=0;       
  98. }

  99. /********************************************************************
  100. * 名稱 : write_string(uchar hang,uchar add,uchar *p)
  101. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
  102.                   write_string(1,5,"ab cd ef;")
  103. * 輸入 : 行,列,需要輸入1602的數據
  104. * 輸出 : 無
  105. ***********************************************************************/
  106. void write_string(uchar hang,uchar add,uchar *p)
  107. {
  108.         if(hang==1)   
  109.                 write_com(0x80+add);
  110.         else
  111.                 write_com(0x80+0x40+add);
  112.         while(1)
  113.         {
  114.                 if(*p == '\0')  break;
  115.                 write_data(*p);
  116.                 p++;
  117.         }       
  118. }

  119. /***********************lcd1602上顯示特定的字符************************/
  120. void write_zifu(uchar hang,uchar add,uchar date)
  121. {
  122.         if(hang==1)   
  123.                 write_com(0x80+add);
  124.         else
  125.                 write_com(0x80+0x40+add);
  126.         write_data(date);       
  127. }

  128. /***********************lcd1602上顯示兩位十進制數************************/
  129. void write_sfm3(uchar hang,uchar add,uint date)
  130. {
  131.         if(hang==1)   
  132.                 write_com(0x80+add);
  133.         else
  134.                 write_com(0x80+0x40+add);
  135.         write_data(0x30+date/100%10);
  136.         write_data(0x30+date/10%10);
  137.         write_data(0x30+date%10);       
  138. }

  139. /***********************lcd1602上顯示兩位十進制數************************/
  140. void write_sfm1(uchar hang,uchar add,uint date)
  141. {
  142.         if(hang==1)   
  143.                 write_com(0x80+add);
  144.         else
  145.                 write_com(0x80+0x40+add);
  146.         write_data(0x30+date%10);       
  147. }

  148. /***********************lcd1602初始化設置************************/
  149. void init_1602()
  150. {
  151.         write_com(0x38);        //設置顯示模式
  152.         write_com(0x0c);  //開顯示不顯示光標,光標不閃爍
  153.         write_com(0x06);  //寫一個數據,指針加1
  154.         delay_uint(1000);
  155.         write_string(1,0,"   Heart Rate     ");       
  156.         write_string(2,0,"     000/min       ");
  157. }

  158. /*************定時器0初始化程序***************/
  159. void time_init()          
  160. {
  161.         EA   = 1;                   //開總中斷
  162.         TMOD = 0X01;          //定時器0、定時器1工作方式1
  163.         ET0  = 1;                  //開定時器0中斷
  164.         TR0  = 1;                  //允許定時器0定時
  165. }


  166. /***********外部中斷0初始化程序****************/
  167. void init_int0()          //外部中斷0初始化程序
  168. {
  169.         EX0=1;                          //允許外部中斷0中斷
  170.         EA=1;                           //開總中斷
  171.         IT0 = 1;                   //外部中斷0負跳變中斷
  172. }

  173.        
  174. /************ 排序***************/
  175. void pingjun_zhi(float *p)
  176. {
  177.         static float value;
  178.         static uchar i,j;
  179.         for(j=1;j<5;j++)                   //先對整個數組的5個值進行從小到大的排列
  180.                 for(i=0;i<5 - j;i++)
  181.                 {
  182.                         if(p[i] > p[i+1])
  183.                         {
  184.                                 value = p[i];
  185.                                 p[i] = p[i+1];
  186.                                 p[i+1] = value;               
  187.                         }       
  188.                 }
  189. }

  190. void key()
  191. {
  192.         if(k1==0)
  193.         {
  194.                 while(k1==0);
  195.                 flag++;
  196.                 if(flag==2){flag=0;write_eeprom();}
  197.                 if(flag==0)
  198.                 {
  199.                         write_string(1,0,"   Heart Rate   ");       
  200.                         write_string(2,0,"     000/min    ");               
  201.                 }
  202.                 if(flag==1)
  203.                 {
  204.                         write_string(1,0,"   set Rate     ");       
  205.                         write_string(2,0,"     000/min    ");               
  206.                 }
  207.         }
  208.         if(flag==1)
  209.         {
  210.                 if(k2==0)
  211.                 {
  212.                         while(k2==0);
  213.                         if(bj<99)bj++;
  214.                 }
  215.                 if(k3==0)
  216.                 {
  217.                         while(k3==0);
  218.                         if(bj>5) bj--;
  219.                 }
  220.         }
  221. }
  222. uchar flag_value;

  223. /****************主函數***************/
  224. void main()
  225. {       
  226.         beep = 0;                                //開機叫一聲   
  227.         delay_1ms(150);
  228.         P0 = P1 = P2 = P3 = 0xff;
  229.         init_1602();                    //1602初始化
  230.         time_init();                    //初始化定時器
  231.         init_int0();          //外部中斷0初始化程序
  232.         init_eeprom();
  233.         while(1)
  234.         {
  235.                 key();
  236.                 if(flag==0)
  237.                 {
  238.                         if(displayOK==0)//如果顯示關
  239.                         {
  240.                                  rate = 0;
  241.                                 flag_value = 0;
  242.                         }
  243.                         else//如果顯示開
  244.                         {
  245.                                 if(flag_en == 1)
  246.                                 {
  247.                                         flag_en = 0;
  248.                                         flag_value ++;
  249.                                         if(flag_value == 1)
  250.                                                 rate1[0]=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
  251.                                         if(flag_value == 2)
  252.                                                 rate1[1]=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
  253.                                         if(flag_value == 3)
  254.                                                 rate1[2]=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
  255.                                         if(flag_value == 4)
  256.                                                 rate1[3]=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
  257.                                         if(flag_value >= 5)
  258.                                         {
  259.                                                 rate1[4]=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
  260.                                
  261.                                                 pingjun_zhi(rate1);
  262.                                                 flag_value = 0;
  263.                                                 rate = (rate1[1] / 3 + rate1[2] / 3 + rate1[3] / 3);
  264.                                         }
  265.                                 }
  266.                         }
  267.        
  268.                         write_sfm3(2,5,rate);
  269.                        
  270.                         if(rate>bj)beep=0;
  271.                         else beep=1;       
  272.                 }                       

  273.                 if(flag==1)
  274.                 {
  275.                         write_sfm3(2,5,bj);
  276.                 }


  277. //                write_sfm3(1,13,b1);
  278. //                write_sfm3(1,14,b2);
  279. //                write_sfm3(1,15,b3);
  280.                 delay_1ms(300);
  281.         }
  282. }
  283. /************外部0中斷服務程序***************/
  284. void int0() interrupt 0
  285. {
  286.         static uchar value;
  287.                 EX0=0;//暫時關外部中斷
  288.                 if(timecount<8)   //當連續兩次檢測時間間隔小于8*50ms=400ms不處理
  289.                 {
  290.                         value ++;
  291.                         if(value >= 4)
  292.                         {
  293.                                 value = 0;
  294. //                                flag_value = 0;
  295.                         }       
  296.                         TR0=1;//開定時器
  297.                 }
  298.                 else if(timecount <= 18)
  299.                 {       
  300.                         value = 0;
  301.                         time[i]=timecount*50+TH0*0.256+TL0/1000;//算出間隔時間

  302.                         TH0 = 0x3c;
  303.                         TL0 = 0xb0;     // 50ms         12M
  304.                         timecount=0;//50ms計數清零
  305.                         i++;
  306.                         flag_en = 1;
  307.                         if(i==6)//記錄到超過等于6次時間
  308.                         {
  309.                                 i=1;//計數從1開始
  310.                                 displayOK=1;    //測得5次開始顯示?
  311.                         }                                                               
  312.                 } else
  313.                 {
  314.                         flag_value = 0;
  315.                         timecount = 0;
  316.                 }
  317.                 EX0=1;
  318. }
  319. /*************定時器0中斷服務程序***************/
  320. void time0_int() interrupt 1
  321. {       
  322.         TH0 = 0x3c;
  323.         TL0 = 0xb0;     // 50ms         12M
  324.         timecount++;//每50ms一次計數
  325.         if(timecount>70)     //當超過25*50ms=1.5s沒有檢測到信號停止顯示
  326.         {
  327.                         i=0;//數據個數清零
  328.                         timecount=0;//50ms計數清零
  329.                         displayOK=0;//顯示關
  330.                         TR0=0;//定時器關
  331.                         TH0 = 0x3c;
  332.                         TL0 = 0xb0;     // 50ms         12M
  333.         }
  334. }
復制代碼

系統總體設計由STC89C52、按鍵、LCD1602、光電傳感器、時鐘模塊、運放等構成,系統設有四個按鍵,可以設置上下限脈搏數,當超過范圍的時候單片機會驅動蜂鳴器發響,脈搏測量的時候需要人把手輕輕的按在光電傳感器上面,由于人脈搏跳動的時候,血液的透光性不一樣會導致接收器那邊接收的信號強弱不一樣,間接的把人脈搏信號傳回,通過運放對其進行放大、整形后連接到單片機的IO口,單片機利用外部中斷對其進行計數,最終換算成人一分鐘脈搏的跳動次數,最終顯示在液晶屏上。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1144925 發表于 2025-4-15 13:48 | 只看該作者
eeprom52.h 文件有嗎
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久热精品在线观看视频 | 在线视频h | 日韩在线观看中文字幕 | 男人天堂网站 | 一道本不卡视频 | www.日韩在线 | 久精品久久 | 嫩草国产 | 欧美日韩精品一区二区三区视频 | 久久久成人免费视频 | 激情欧美一区二区三区中文字幕 | 久久av网站 | 一区二区三区亚洲视频 | 国产精品自产av一区二区三区 | 99色播| 成人免费视频网站在线看 | www.久| 亚洲精品一区二区三区四区高清 | 夜夜操操操 | 一区二区三区免费网站 | 北条麻妃一区二区三区在线视频 | 狠狠色综合网站久久久久久久 | 国产精品久久久久久婷婷天堂 | 精品久久久久久一区二区 | www.4567| 嫩草影院网址 | 亚洲福利网站 | 中文字幕在线免费观看 | 日韩欧美三级电影在线观看 | 欧美在线一区视频 | 久久久精彩视频 | 欧美综合一区二区 | 欧美日韩一二三区 | 另类亚洲视频 | 久久一日本道色综合久久 | 久久久91 | 国产精品久久久久久久久久东京 | 一级免费毛片 | 久久久五月天 | 国产成人a亚洲精品 | 国产精品区二区三区日本 |