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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 18576|回復: 6
收起左側

單片機脈搏體溫檢測儀的Proteus仿真設計與調試 附源碼+文檔

  [復制鏈接]
ID:430253 發表于 2019-1-10 21:28 | 顯示全部樓層 |閱讀模式
0.png

由于仿真中沒有紅外,手指也模擬不了,其實就是單片機的IO口檢測脈沖信號,那樣用個方波信號模擬就行了
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png

一、設計要求
本設計利用紅外光電傳感器產生脈沖信號,經過放大整形后,輸入單片機內進行相應的控制,從而測量出一分鐘內的脈搏跳動次數,快捷方便。測量范圍限可以用按鍵調節,并進行聲音報警,測量結果以數字方式顯示,測量精確到2次/分。同時還可以設定上限次數和下限次數,當測量的范圍超過設定的范圍則驅動蜂鳴器報警提醒,結果最終可以把采集到的脈搏信號顯示在LCD1602上。

二、方案論證

系統框圖如下:

2.1主控模塊的選型和論證

方案一:
采用MSP430系列單片機,該單片機是TI公司1996年開始推向市場的一種16位超低功耗的混合信號處理器。其內部集成了很多模擬電路、數字電路和微處理器,提供強大的功能。不過該芯片昂貴不適合一般的設計開發[3]。
方案二:
采用51系列的單片機,該單片機是一個高可靠性,超低價,無法解密,高性能的8位單片機,32個IO口,且STC系列的單片機可以在線編程、調試,方便地實現程序的下載與整機的調試。
因此選用方案二中的51系列單片機作為主控芯片。

2.2顯示模塊的選型和論證

方案一:

采用LED數碼管動態掃描,LED數碼管價格雖適中,對于顯示數字也最合適,而且采用動態掃描法與單片機連接時,占用單片機口線少。但是由于數碼管動態掃描需要借助74LS164移位寄存器進行移位,該芯片在電路調試時往往有很多障礙,所以不采用LED數碼管作為顯示。

方案二:

采用LCD液晶顯示屏,液晶顯示屏的顯示功能強大,可顯示大量文字,圖形,顯示多樣,清晰可見,對于本設計而言一個LCD1602的液晶屏即可,價格也還能接受,需要的接口線較多,但會給調試帶來諸多方便。
所以本設計中方案二中的LCD1602液顯示屏作為顯示模塊。

2.3脈搏檢測傳感器的選型和論證

方案一:壓電式
壓電式傳感器的檢測方法是利用壓力傳感器或振動傳感器將人體脈搏振動轉換成電信號。常見的壓力傳感器可用現有的壓電陶瓷代替。壓電式元件的內阻極高,通常采用兩片相同的元件,使其極性反向相疊,由夾在中間的銅片作為一個電極。這樣,中央電極處于全空狀態,可以用具有良好絕緣性的導線引出。此種方法的優點是傳感器種類多,一般的傳感器輸出信號也比較大,對后面的放大電路要求不高。壓電陶瓷具有成本低、取材方便、易于提高敏感度等特點。
方案二:聲電式
聲電式傳感器的作用是將氣體、液體或固體中傳播的機械振動轉換成電信號。因此,它也屬于力學量傳感器。它的制作材料一般由不定性無煙煤顆粒或壓電陶瓷構成。顆粒式聲電傳感器的優點是耐用、成本低和容易制作,缺點是顆粒的機械磨損和接觸表面上的瞬間電弧會使顆粒逐漸老化,從而導致雜音大、性能不穩定和非線性;而壓電陶瓷式的聲電傳感器在檢測聲音信號時卻存在著一定的缺陷。
聲電式檢測方法是利用微音傳感器將人體的振動的聲音轉換成電信號。此種方法的優點是作為傳感器的微音傳感器可利用現有的駐極體或電容式話筒,但其后面的電路要采取一定的措施將環境的聲音干擾信號濾去。
方案三:光電式
光電系統通常是指能敏感由紫外光到紅外光的光能量,并將光能量轉換成電信號的器件。通常用的光電器件有光電二極管和光電三極管。光電式傳感器測量微小的位移變化有明顯的效果,但是光電傳感器對材料、電路控制和光電管屬性要求較高:1)吸收紅外光的能力極強2)介電常數小,以便得到大的輸出電壓。3)介電損耗小。
光電式檢測方法是利用光電傳感器檢測人體內血液流動時對光的透過率或反射率不同而將其轉換成電信號的方法。此種方法有兩種方式:一種是對射式,另一種是反射式。對射式是在一個大小合適的環的兩側各放一個發射管和一個接收管,測量時將人的手指伸到環中,由于手指中的血流量的變化而使光電接收管的光電流也隨之變化,反射式是光電發射與光電接收都指向一個方向,當人體內的血流發生變化時其對光的反射率也隨之變化,從而檢測出心率。這種方法的優點是外界干擾信號小,但其最大的難點是傳感器輸出信號小,對后面的放大電路要求較高。此外,對于干擾變化強烈的信號,回路不宜調制,可視光電管的定向角不同,光軸也不宜把握。
綜上所述,從傳感器的制作工藝、材料的選取、受外界的干擾信號的干擾程度和制作過程中前級電路的處理難易程度上考慮,就選用一對紅外對射二極管實現。

2.4溫度傳感器的選型
方案一:
由于本設計是測溫電路,可以使用熱敏電阻之類的器件,將隨被測溫度變化的電壓或電流采樣,進行A/D轉換后就可以用單片機進行數據處理,實現溫度顯示。這種設計需要用到A/D轉換電路,增大了電路的復雜性,而且要做到高精度也比較困難。

方案二
              考慮到在單片機屬于數字系統,容易想到數字溫度傳感器,可選用DS18B20數字溫度傳感器,此傳感器為單總線數字溫度傳感器,起體積小、構成的系統結構簡單,它可直接將溫度轉化成串行數字信號給單片機處理,即可實現溫度顯示。另外DS18B20具有3引腳的小體積封裝,測溫范圍為-55~+125攝氏度,測溫分辨率可達0.0625攝氏度,其測量范圍與精度都能符合設計要求。
              以上兩種方案相比較,第二種方案的電路、軟件設計更簡單,此方案設計的系統在功耗、測量精度、范圍等方面都能很好地達到要求,故本設計采用方案二。

2.5系統整體設計概述

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

三、理論設計

硬件設計

1、硬件原理圖

2、工作原理

本設計利用紅外光電傳感器產生脈沖信號,經過放大整形后,輸入單片機內進行相應的控制,從而測量出一分鐘內的脈搏跳動次數,當測量的范圍超過設定的范圍則驅動蜂鳴器報警提醒,當檢測的體溫超過設置的溫度上下限也會蜂鳴器報警提醒,結果最終可以把采集到的脈搏信號顯示在LCD1602上。

3.1.1單片機最小系統設計

圖3.1 單片機最小系統電路圖
              圖3.1為單片機最小系統電路圖,單片機最小系統有單片機、時鐘電路、復位電路組成,時鐘電路選用了12MHZ的晶振提供時鐘,作用為給單片機提供一個時間基準,其中執行一條基本指令需要的時間為一個機器周期,單片機的復位電路,按下復位按鍵之后可以使單片機進入剛上電的起始狀態。圖中10K排阻為P0口的上拉電阻,由于P0口跟其他IO結構不一樣為漏極開路的結構,因此要加上拉電阻才能正常使用。

3.1.2 液晶原理介紹

液晶顯示器(LCD)英文全稱為Liquid Crystal Display,它一種是采用了液晶控制透光度技術來實現色彩的顯示器。和CRT顯示器相比,LCD的優點是很明顯的。由于通過控制是否透光來控制亮和暗,當色彩不變時,液晶也保持不變,這樣就無須考慮刷新率的問題。
顯示接口用來顯示系統的狀態,命令或采集的電壓數據。本系統顯示部分用的是LCD液晶模塊,采用一個16×2的字符型液晶顯示模塊。
LCD1602引腳圖

液晶寄存器選擇控制如表3.1。

表3.1寄存器選擇控制
RS
R/W
操作說明
0
0
寫入指令寄存器(清除屏等)
0
1
讀busy flag(DB7),以及讀取位址計數器(DB0~DB6)值
1
0
寫入數據寄存器(顯示各字型等)
1
1
從數據寄存器讀取數據

LCD1602與單片機接口電路如下:


3.1.3信號采集電路

信號采集電路如圖3-2所示。5MM紅外對管D1與D3組成紅外傳感器。因紅外傳感器輸出的脈沖信號是非常微弱的信號,而且頻率很低(如脈搏50次/分鐘為0.78Hz,200次/分鐘為3.33Hz),并且還伴有各種噪聲干擾,故該信號要經過R7、C5低通濾波,去除高頻干擾。當傳感器檢測到較強的干擾噪音時,其輸出端的直流電壓信號會有很大變化
圖3.2 信號采集電路

3.1.4信號放大電路

如圖3-3所示,R3與R8的電阻之比為放大器的放大倍數,經過計算所得該放大器的理論值為200倍,但由于8號接口上5V供壓不足再加上材料限制和人為的因素,該放大倍數只有20倍左右。
  圖中C7為耦合電容,作用為隔直流通交流,之所以使用1uF的電容,是為了讓所有的信號通過。
圖3.3 信號放大電路

3.1.5信號比較電路

電壓比較器是一種常用的集成電路。它可用于報警器電路、自動控制電路、測量技術,也可用于V/F 變換電路、A/D 變換電路、高速采樣電路、電源電壓監測電路、振蕩器及壓控振蕩器電路、過零檢測電路等。我們主要介紹其基本概念、工作原理及典型工作電路,電壓比較器是對兩個模擬電壓比較其大小并判斷出其中哪一個電壓高,接到的信號電壓小于該值時顯示0V,當大于該值時顯示5V,這就形成了0和5V的方波。如圖3.4 所示。
圖3.4 放大濾波電路
軟件設計
3.2系統軟件總體設計
圖3.2系統流程圖
主程序流程圖如圖3.2所示,單片機上電后先進行初始化,清楚一些參數的初值,然后等待用戶按下對應的按鍵并進入對應的功能,當用戶按下測量按鍵的時候流程如圖3.2(c)所示,單片機通過定時15s測量人體的脈搏次數流程如圖3.2(b)所示,然后再換算出對應的真實的脈搏次數再在液晶屏幕上顯示流程如圖3.2(a)所示,當用戶按下設置脈搏范圍設定按鍵后,單片機根據用戶按下的按鍵進行增加或減少范圍。

延時子程序:


四、測試方案、測試結果及分析

4.1軟件調試
當模塊設計完成并在ISIS 7 protues中仿真成功后,電路基本確定,但那只是理論值,需要對這些仿真電路進行試驗,以確保這些電路是否適用與該設計。
4.2硬件調試
準備施焊;加熱焊件;送入焊絲;焊接元件。在焊接過程中要注意假焊,虛焊,焊接不規則等等問題,盡量避免不必要的錯誤。器件安裝焊接完后,就要焊接電線,一定要保證連接端口的正確連接,管腳的位置及所代表的含義不能搞錯,這樣才能避免電路板出現問題,將裝置供電后,將已寫好的程序下載到單片機里面,觀察板子的現象。
測試結果:程序下載好并供電后,LCD顯示屏上顯示14.4°,手指放在紅外燈管上,顯示屏顯示脈搏次數93,如果脈搏超過預先設定的范圍,裝置中的蜂鳴器報警,測量的脈搏在正常范圍內,警報停止報警。按下功能鍵,可以修改設置的警告上下限。在測量時,紅外傳感器檢測到的人體信號很微弱,手指的一點抖動都會引起測量心率值的大幅變化,手指盡量別亂動,以免測量數據不準確,導致蜂鳴器一直報警。
分析:設計要求全部實現。

五、作品功能和使用說明:

作品功能:實現溫度的測量、脈搏測量。能測出即時的溫度和脈搏,顯示在LCD屏上。手指放到紅外對管中,2秒內讀出心率。同時還可以設定上限次數和下限次數,當測量的范圍超過設定的范圍則驅動蜂鳴器報警提醒,當檢測的體溫超過設置的溫度上下限也會蜂鳴器報警提醒。
使用說明:顯示每分鐘脈搏次數和溫度。
三個按鍵:一個設置,一個加,一個減。
按下設置的時候才可以加減。
手指放上去盡量別亂動。

六、心得體會

通過這次課程設計,學到了不少課本上沒有的知識,也鍛煉了自己的動手能力,將以前學過的零散的知識串到一起。經過長時間的設計及調試,軟件仿真基本能實現基于單片機的脈搏計的所有功能。但是硬件的穩定性有待進一步提高,無法發現錯誤在何處。
綜合設計主要涉及硬件和軟件兩方面的內容,硬件和軟件開發能力都獲得了提高。首先硬件方面,基本了解了電子產品的開發流程和所要做的工作,焊完實物后,首先是硬件調試。電路的調試過程是檢驗、修正設計方案的實踐過程,但也是對理論知識的實際應用,解決各種問題的關鍵環節,是電路設計人員必須掌握的基本技能。基本掌握了Protel99SE原理圖的方法,通過開發板的設計和硬件搭建的過程,對51系單片機的接口有了更深層次的理解,熟悉了一些單片機常用的外圍電路引腳和連接方法,如LCD液晶,鍵盤等。并且學會了分析問題解決問題的能力,加深了對所學理論知識的理解和運用,動手能力得到了很大的提高,創新意識得到了鍛煉。

單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>       

  3. #define uint            unsigned int
  4. #define uchar           unsigned char
  5. #define ulong           unsigned long         //宏定義
  6. #define LCD_DATA        P0                                 //定義P0口為LCD_DATA

  7. sbit LCD_RS =P2^5;
  8. sbit LCD_RW =P2^6;
  9. sbit LCD_E  =P2^7;                                                 //定義LCD控制引腳

  10. sbit Xintiao =P1^0 ;                                         //脈搏檢測輸入端定義
  11. sbit speaker =P2^4;                                                 //蜂鳴器引腳定義
  12. sbit DQ=P3^7;

  13. void delay5ms(void);   //誤差 0us
  14. void LCD_WriteData(uchar LCD_1602_DATA);         /********LCD1602數據寫入***********/
  15. void LCD_WriteCom(uchar LCD_1602_COM);                 /********LCD1602命令寫入***********/
  16. void lcd_1602_word(uchar Adress_Com,uchar Num_Adat,uchar *Adress_Data); /*1602字符顯示函數,變量依次為字符顯示首地址,顯示字符長度,所顯示的字符*/
  17. void InitLcd();//液晶初始化函數

  18. void Tim_Init();

  19. uchar Xintiao_Change=0;           //
  20. uint  Xintiao_Jishu;
  21. uchar stop;
  22. uchar View_Data[3];
  23. uchar View_L[3];
  24. uchar View_H[3];
  25. uchar Xintiao_H=100;        //脈搏上限
  26. uchar Xintiao_L=40;                //脈搏下限
  27. uint wendu=0;

  28. uchar Key_Change;
  29. uchar Key_Value;                //按鍵鍵值
  30. uchar View_Con;                        //設置的位(0正常工作,1設置上限,2設置下限)
  31. uchar View_Change;


  32. /*****延時子程序*****/
  33. void Delay_DS18B20(int num)
  34. {
  35.   while(num--) ;
  36. }
  37. /*****初始化DS18B20*****/
  38. void Init_DS18B20(void)
  39. {
  40.   unsigned char x=0;
  41.   DQ = 1;         //DQ復位
  42.   Delay_DS18B20(8);    //稍做延時
  43.   DQ = 0;         //單片機將DQ拉低
  44.   Delay_DS18B20(80);   //精確延時,大于480us
  45.   DQ = 1;         //拉高總線
  46.   Delay_DS18B20(34);
  47. }
  48. /*****讀一個字節*****/
  49. unsigned char ReadOneChar(void)
  50. {
  51.   unsigned char i=0;
  52.   unsigned char dat = 0;
  53.   for (i=8;i>0;i--)
  54.   {
  55.     DQ = 0;     // 給脈沖信號
  56.     dat>>=1;
  57.     DQ = 1;     // 給脈沖信號
  58.     if(DQ)
  59.     dat|=0x80;
  60.     Delay_DS18B20(4);
  61.   }
  62.   return(dat);
  63. }

  64. void WriteOneChar(unsigned char dat)
  65. {
  66.   unsigned char i=0;
  67.   for (i=8; i>0; i--)
  68.   {
  69.     DQ = 0;
  70.     DQ = dat&0x01;
  71.     Delay_DS18B20(5);
  72.     DQ = 1;
  73.     dat>>=1;
  74.   }
  75. }
  76. /*****讀取溫度*****/
  77. unsigned int ReadTemperature(void)
  78. {
  79.   unsigned char a=0;
  80.   unsigned char b=0;
  81.   unsigned int t=0;
  82.   float tt=0;
  83.   Init_DS18B20();
  84.   WriteOneChar(0xCC);  //跳過讀序號列號的操作
  85.   WriteOneChar(0x44);  //啟動溫度轉換
  86.   Init_DS18B20();
  87.   WriteOneChar(0xCC);  //跳過讀序號列號的操作
  88.   WriteOneChar(0xBE);  //讀取溫度寄存器
  89.   a=ReadOneChar();     //讀低8位
  90.   b=ReadOneChar();    //讀高8位
  91.   t=b;
  92.   t<<=8;
  93.   t=t|a;
  94.   tt=t*0.0625;
  95.   t= tt*10+0.5;     //放大10倍輸出并四舍五入
  96.   return(t);
  97. }
  98. //=====================================================================================
  99. //=====================================================================================
  100. //=====================================================================================


  101. void main()          //主函數
  102. {
  103. InitLcd();
  104. Tim_Init();
  105. lcd_1602_word(0x80,16,"Heart Rate:     ");          //初始化顯示

  106. TR0=1;
  107. TR1=1;                                  //打開定時器
  108. while(1)                          //進入循環
  109.   {
  110.           if(View_Con==0)
  111.         {
  112.                 wendu=ReadTemperature();
  113.                 lcd_1602_word(0xc0,10," Temp:    ");//顯示第二行數據
  114.                 LCD_WriteCom(0x80+0x40+10);
  115.                 LCD_WriteData(wendu/100+0x30);
  116.                 LCD_WriteData(wendu%100/10+0x30);
  117.                 LCD_WriteData('.');
  118.                 LCD_WriteData(wendu%100%10+0x30);
  119.                 LCD_WriteData(0xdf);
  120.                 LCD_WriteData('C');
  121.         }
  122.          
  123.    if(Key_Change)          //有按鍵按下并已經得出鍵值
  124.     {
  125.          Key_Change=0;          //將按鍵使能變量清零,等待下次按鍵按下
  126.          View_Change=1;
  127.          switch(Key_Value)                                //判斷鍵值
  128.           {
  129.            case 1:                                                //設置鍵按下
  130.                  {
  131.                           View_Con++;                        //設置的位加
  132.                           if(View_Con==3)                //都設置好后將此變量清零
  133.                            View_Con=0;
  134.                           break;                                //跳出,下同
  135.                          }
  136.            case 2:                                                //加鍵按下
  137.                  {
  138.                           if(View_Con==2)                //判斷是設置上限
  139.                            {
  140.                                    if(Xintiao_H<150)        //上限數值小于150
  141.                                  Xintiao_H++;                //上限+
  142.                            }
  143.                           if(View_Con==1)                //如果是設置下限
  144.                            {
  145.                                    if(Xintiao_L<Xintiao_H-1)//下限值小于上限-1(下限值不能超過上限)
  146.                                  Xintiao_L++;                //下限值加
  147.                            }
  148.                           break;
  149.                          }
  150.            case 3:                                                //減鍵按下
  151.                  {
  152.                           if(View_Con==2)                //設置上限
  153.                            {
  154.                                    if(Xintiao_H>Xintiao_L+1)//上限數據大于下限+1(同樣上限值不能小于下限)
  155.                                  Xintiao_H--;                //上限數據減
  156.                            }
  157.                           if(View_Con==1)                //設置下限
  158.                            {
  159.                                    if(Xintiao_L>30)        //下限數據大于30時
  160.                                  Xintiao_L--;                //下限數據減
  161.                            }
  162.                           break;
  163.                          }
  164.          }
  165.         }
  166.    if(View_Change)//開始顯示變量
  167.     {
  168.          View_Change=0;//變量清零
  169.          if(stop==0)                          //心率正常時
  170.           {
  171.            if(View_Data[0]==0x30) //最高位為0時不顯示
  172.             View_Data[0]=' ';
  173.           }
  174.          else                                          //心率不正常(計數超過5000,也就是兩次信號時間超過5s)不顯示數據
  175.           {
  176.            View_Data[0]=' ';
  177.            View_Data[1]=' ';
  178.            View_Data[2]=' ';
  179.           }

  180.          switch(View_Con)
  181.           {
  182.            case 0: //正常顯示
  183.                   {
  184.                            lcd_1602_word(0x80,16,"Heart Rate:     ");//顯示一行數據

  185.                            lcd_1602_word(0x8d,3,View_Data);                         //第1行顯示心率

  186.                            break;
  187.                           }
  188.            case 1: //設置下限時顯示
  189.                   {
  190.                            lcd_1602_word(0x80,16,"Heart Rate:     ");//第一行顯示心率
  191.                            lcd_1602_word(0x8d,3,View_Data);
  192.                           
  193.                            View_L[0]=Xintiao_L/100+0x30;                //將下限數據拆字
  194.                            View_L[1]=Xintiao_L%100/10+0x30;
  195.                            View_L[2]=Xintiao_L%10+0x30;

  196.                            if(View_L[0]==0x30)                                        //最高位為0時,不顯示
  197.                             View_L[0]=' ';
  198.                           
  199.                            lcd_1602_word(0xC0,16,"Warning L :     ");//第二行顯示下限數據
  200.                            lcd_1602_word(0xCd,3,View_L);
  201.                            break;
  202.                           }
  203.            case 2: //設置上限時顯示(同上)
  204.                   {
  205.                            lcd_1602_word(0x80,16,"Heart Rate:     ");
  206.                            lcd_1602_word(0x8d,3,View_Data);
  207.                           
  208.                            View_H[0]=Xintiao_H/100+0x30;
  209.                            View_H[1]=Xintiao_H%100/10+0x30;
  210.                            View_H[2]=Xintiao_H%10+0x30;

  211.                            if(View_H[0]==0x30)
  212.                             View_H[0]=' ';
  213.                           
  214.                            lcd_1602_word(0xC0,16,"Warning H :     ");
  215.                            lcd_1602_word(0xCd,3,View_H);
  216.                            break;
  217.                           }
  218.           }
  219.         }
  220.   }
  221. }

  222. void Time1() interrupt 3                //定時器1服務函數
  223. {
  224.         static uchar Key_Con,Xintiao_Con;
  225.         TH1=0xd8;                   //10ms
  226.         TL1=0xf0;                   //重新賦初值
  227.         switch(Key_Con)   //無按鍵按下時此值為0
  228.         {
  229.                 case 0:                   //每10ms掃描此處
  230.                 {
  231.                         if((P3&0x07)!=0x07)//掃描按鍵是否有按下
  232.                         {
  233.                                 Key_Con++;                  //有按下此值加1,值為1
  234.                         }
  235.                         break;
  236.                 }
  237.                 case 1:                                          //10ms后二次進入中斷后掃描此處(Key_Con為1)
  238.                 {
  239.                         if((P3&0x07)!=0x07)//第二次進入中斷時,按鍵仍然是按下(起到按鍵延時去抖的作用)
  240.                         {
  241.                                 Key_Con++;                  //變量加1,值為2
  242.                                 switch(P3&0x07)  //判斷是哪個按鍵按下
  243.                                 {
  244.                                         case 0x06:Key_Value=1;break;         //判斷好按鍵后將鍵值賦值給變量Key_Value
  245.                                         case 0x05:Key_Value=2;break;
  246.                                         case 0x03:Key_Value=3;break;
  247.                                 }
  248.                         }
  249.                         else                                                                 //如果10ms時沒有檢測到按鍵按下(按下時間過短)
  250.                         {
  251.                                 Key_Con=0;                                                 //變量清零,重新檢測按鍵
  252.                         }
  253.                         break;
  254.                 }
  255.                 case 2:                                                                         //20ms后檢測按鍵
  256.                 {
  257.                         if((P3&0x07)==0x07)                                 //檢測按鍵是否還是按下狀態
  258.                         {
  259.                                 Key_Change=1;                                         //有按鍵按下使能變量,(此變量為1時才會處理鍵值數據)
  260.                                 Key_Con=0;                                                //變量清零,等待下次有按鍵按下
  261.                         }
  262.                         break;
  263.                 }
  264.         }
  265.                
  266.         switch (Xintiao_Con)//此處與上面按鍵的檢測類似
  267.         {
  268.                 case 0:                         //默認Xintiao_Con是為0的
  269.                 {
  270.                         if(!Xintiao)//每10ms(上面的定時器)檢測一次脈搏是否有信號
  271.                         {
  272.                                 Xintiao_Con++;//如果有信號,變量加一,程序就會往下走了
  273.                         }
  274.                         break;
  275.                 }
  276.                 case 1:
  277.                 {
  278.                         if(!Xintiao)           //每過10ms檢測一下信號是否還存在
  279.                         {
  280.                                 Xintiao_Con++;//存在就加一
  281.                         }
  282.                         else
  283.                         {
  284.                                 Xintiao_Con=0;//如果不存在了,檢測時間很短,說明檢測到的不是脈搏信號,可能是其他干擾,將變量清零,跳出此次檢測
  285.                         }
  286.                         break;
  287.                 }
  288.                 case 2:
  289.                 {
  290.                         if(!Xintiao)
  291.                         {
  292.                                 Xintiao_Con++;//存在就加一
  293.                         }
  294.                         else
  295.                         {
  296.                                 Xintiao_Con=0;//如果不存在了,檢測時間很短,說明檢測到的不是脈搏信號,可能是其他干擾,將變量清零,跳出此次檢測
  297.                         }
  298.                         break;
  299.                 }
  300.                 case 3:
  301.                 {
  302.                         if(!Xintiao)
  303.                         {
  304.                                 Xintiao_Con++;//存在就加一
  305.                         }
  306.                         else
  307.                         {
  308.                                 Xintiao_Con=0;//如果不存在了,檢測時間很短,說明檢測到的不是脈搏信號,可能是其他干擾,將變量清零,跳出此次檢測
  309.                         }
  310.                         break;
  311.                 }
  312.                 case 4:
  313.                 {
  314.                         if(Xintiao)//超過30ms一直有信號,判定此次是脈搏信號,執行以下程序
  315.                         {
  316.                                 if(Xintiao_Change==1)//心率計原理為檢測兩次脈沖間隔時間計算心率,變量Xintiao_Change第一次脈沖時為0的,所有走下面的else,第二次走這里
  317.                                 {
  318.                                         View_Data[0]=(60000/Xintiao_Jishu)/100+0x30;
  319.                                         View_Data[1]=(60000/Xintiao_Jishu)%100/10+0x30;
  320.                                         View_Data[2]=(60000/Xintiao_Jishu)%10+0x30;
  321.                                        
  322.                                         if(((60000/Xintiao_Jishu)>=Xintiao_H)||((60000/Xintiao_Jishu)<=Xintiao_L))//心率不在范圍內報警
  323.                                         speaker=0;                        //蜂鳴器響
  324.                                         else
  325.                                         speaker=1;                        //不響
  326.                        
  327.                                         View_Change=1;           //計算出心率后啟動顯示
  328.                                         Xintiao_Jishu=0;           //心跳計數清零
  329.                                         Xintiao_Change=0;   //計算出心率后該變量清零,準備下次檢測心率
  330.                                         stop=0;                           //計算出心率后stop清零
  331.                                    TR0=0;
  332.                                 //   wendu=ReadTemperature();
  333.                                 //   TR1=0;
  334.                                 }
  335.                                 else//第一次脈沖時Xintiao_Change為0
  336.                                 {
  337.                                         Xintiao_Jishu=0;        //脈沖計時變量清零,開始計時
  338.                                         Xintiao_Change=1;//Xintiao_Change置1,準備第二次檢測到脈沖時計算心率
  339.                                         TR0=1;
  340.                                 }
  341.                                 Xintiao_Con=0;        //清零,準備檢測下一次脈沖
  342.                                 break;
  343.                         }
  344.                 }
  345.         }
  346. }
  347. /**定時器T0工作函數**/
  348. void Time0() interrupt 1
  349. {
  350. TH0=0xfc;                   //1ms
  351. TL0=0x18;                   //重新賦初值
  352. Xintiao_Jishu++;  //心跳計數加
  353. if(Xintiao_Jishu==5000)//心跳計數大于5000
  354.   {
  355.    Xintiao_Jishu=0;                //數據清零
  356.    View_Change=1;                //顯示位置1
  357.    Xintiao_Change=0;        //置零,準備再次檢測
  358.    stop=1;           //心跳計數超過5000后說明心率不正常或者沒有測出,stop置1
  359.    speaker=1;  //關閉蜂鳴器
  360.   }
  361. }
  362. /**定時器初始化函數**/
  363. void Tim_Init()
  364. {
  365. EA=1;                          //打開中斷總開關
  366. ET0=1;                          //打開T0中斷允許開關
  367. ET1=1;                          //打開T1中斷允許開關
  368. TMOD=0x11;                  //設定定時器狀態
  369. TH0=0xfc;                   //1ms
  370. TL0=0x18;                   //賦初值

  371. TH1=0xd8;                   //10ms
  372. TL1=0xf0;                   //賦初值
  373. }

  374. /**Adress_Com顯示地址,Num_Adat顯示字符數量,Adress_Data顯示字符串內容**/
  375. void lcd_1602_word(uchar Adress_Com,uchar Num_Adat,uchar *Adress_Data)
  376. {
  377. uchar a=0;
  378. uchar Data_Word;
  379. LCD_WriteCom(Adress_Com); //選中地址
  380. for(a=0;a<Num_Adat;a++)   //for循環決定顯示字符個數
  381.   {
  382.    Data_Word=*Adress_Data;          //讀取字符串數據
  383.    LCD_WriteData(Data_Word);  //顯示字符串
  384.    Adress_Data++;                          //顯示地址加一
  385.   }
  386. }

  387. ……………………

  388. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
16 脈搏體溫檢測儀的設計與制作2016111435朱波.zip (731.88 KB, 下載次數: 340)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:675863 發表于 2020-1-12 21:23 | 顯示全部樓層
仿真運行不了,似乎有錯誤
回復

使用道具 舉報

ID:705967 發表于 2020-4-7 22:19 | 顯示全部樓層
霸氣范 發表于 2020-1-12 21:23
仿真運行不了,似乎有錯誤

真的嗎??運行不了嗎?
回復

使用道具 舉報

ID:57810 發表于 2020-4-7 23:45 | 顯示全部樓層
好資料,學習下,樓上的 仿真運行出來是這樣的,大家看看有錯誤嗎?我是用Proteus 7.5版本,,,剛開始用8.8也是仿真不出來
51hei.png
回復

使用道具 舉報

ID:382079 發表于 2020-4-20 08:19 | 顯示全部樓層
樓主, 是不是還得在這個仿真里面導入程序才能運行呢
回復

使用道具 舉報

ID:314894 發表于 2020-4-29 21:05 | 顯示全部樓層
樓主你仿真運行不了,在線調試都沒用
回復

使用道具 舉報

ID:755333 發表于 2020-5-21 09:45 | 顯示全部樓層
ywc3000 發表于 2020-4-7 23:45
好資料,學習下,樓上的 仿真運行出來是這樣的,大家看看有錯誤嗎?我是用Proteus 7.5版本,,,剛開始用8.8也是 ...

仿真里的脈搏數據不能顯示呀
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av免费网站在线观看 | 久久久精品一区 | 亚洲高清视频在线观看 | www国产精| 久久久久久精 | 盗摄精品av一区二区三区 | 综合精品久久久 | 91免费观看视频 | 一区二区欧美在线 | 国产日韩欧美一区二区 | 日韩精品免费 | 免费看的av | 亚洲视频精品在线 | 国产www成人 | 精品久久久久久亚洲精品 | 99精品久久| 午夜视频在线 | 欧美精品福利视频 | 操一草| 一区免费 | 国产日韩精品一区 | 在线小视频| 成人av电影免费在线观看 | 国产日韩一区二区三区 | 高清免费在线 | 中文字幕亚洲一区 | 香蕉国产在线视频 | 天天欧美 | 91麻豆精品国产91久久久久久久久 | 欧美一区 | 伊人春色成人网 | 色在线视频网站 | 亚洲www| 欧美高清一区 | 色婷婷综合在线观看 | 91国内精精品久久久久久婷婷 | 欧美一区二区三区 | 成人免费区一区二区三区 | 国产精品一区二区不卡 | 国产一区二区三区久久久久久久久 | 亚洲综合二区 |