|
2.1主控模塊的選型和論證 方案一: 采用MSP430系列單片機,該單片機是TI公司1996年開始推向市場的一種16位超低功耗的混合信號處理器。其內部集成了很多模擬電路、數字電路和微處理器,提供強大的功能。不過該芯片昂貴不適合一般的設計開發[3]。 方案二 采用51系列的單片機,該單片機是一個高可靠性,超低價,無法解密,高性能的8位單片機,32個IO口,且STC系列的單片機可以在線編程、調試,方便地實現程序的下載與整機的調試。 因此選用方案二中的51系列單片機作為主控芯片。 2.2顯示模塊的選型和論證 方案一: 采用點陣式數碼管顯示,點陣式數碼管是由八行八列的發光二極管組成,對于顯示文字比較合適,如采用在顯示數字顯得太浪費,且價格也相對較高,所以不用此種作為顯示。 方案二: 采用LED數碼管動態掃描,LED數碼管價格雖適中,對于顯示數字也最合適,而且采用動態掃描法與單片機連接時,占用單片機口線少。但是由于數碼管動態掃描需要借助74LS164移位寄存器進行移位,該芯片在電路調試時往往有很多障礙,所以不采用LED數碼管作為顯示。 方案三: 采用LCD液晶顯示屏,液晶顯示屏的顯示功能強大,可顯示大量文字,圖形,顯示多樣,清晰可見,對于本設計而言一個LCD1602的液晶屏即可,價格也還能接受,需要的接口線較多,但會給調試帶來諸多方便。 所以本設計中方案三中的LCD1602液顯示屏作為顯示模塊。 2.3脈搏檢測傳感器的選型和論證 方案一: 采用壓電傳感器用來提取人的脈搏信號,壓電傳感器是利用某些電介質受力后產生的壓電效應制成的傳感器。所謂壓電效應是指某些電介質在受到某一方向的外力作用而發生形變(包括彎曲和伸縮形變)時,由于內部電荷的極化現象,會在其表面產生電荷的現象。通過此現象可以提取出人的脈搏信號。 方案二: 采用光電傳感器提取人體脈搏信號,授予手指組織可以分成皮膚、肌肉、骨骼等非血液組織和血液組織,其中非血液組織的光吸收量是恒定的,而在血液中,靜脈血的搏動相對動脈血是十分微弱的,可以忽略,因此可以認為光透過手指后的變化僅由動脈血的充盈而引起,那么在恒定波長的光源的照射下,通過檢測透過手指的光強將可以間接測量到人體的脈搏信號[4]。 由于光電傳感器較壓電傳感器容易在一般的地方可以買得到,因此這里選用光電傳感器來提取人體脈搏信號。 2.4溫度傳感器的選型方案一 由于本設計是測溫電路,可以使用熱敏電阻之類的器件,將隨被測溫度變化的電壓或電流采樣,進行A/D轉換后就可以用單片機進行數據處理,實現溫度顯示。這種設計需要用到A/D轉換電路,增大了電路的復雜性,而且要做到高精度也比較困難。
方案二 考慮到在單片機屬于數字系統,容易想到數字溫度傳感器,可選用DS18B20數字溫度傳感器,此傳感器為單總線數字溫度傳感器,起體積小、構成的系統結構簡單,它可直接將溫度轉化成串行數字信號給單片機處理,即可實現溫度顯示。另外DS18B20具有3引腳的小體積封裝,測溫范圍為-55~+125攝氏度,測溫分辨率可達0.0625攝氏度,其測量范圍與精度都能符合設計要求。 以上兩種方案相比較,第二種方案的電路、軟件設計更簡單,此方案設計的系統在功耗、測量精度、范圍等方面都能很好地達到要求,故本設計采用方案二。
2.5系統整體設計概述
系統總體設計由STC89C52、按鍵、LCD1602、光電傳感器、時鐘模塊、運放等構成,如圖2.1所示,系統設有四個按鍵,可以設置上下限脈搏數,當超過范圍的時候單片機會驅動蜂鳴器發響,脈搏測量的時候需要人把手輕輕的按在光電傳感器上面,由于人脈搏跳動的時候,血液的透光性不一樣會導致接收器那邊接收的信號強弱不一樣,間接的把人脈搏信號傳回,通過運放對其進行放大、整形后連接到單片機的IO口,單片機利用外部中斷對其進行計數,最終換算成人一分鐘脈搏的跳動次數,最終顯示在液晶屏上。
3.1.3單片機最小系統設計 圖3.3 單片機最小系統電路圖 圖3.3為單片機最小系統電路圖,單片機最小系統有單片機、時鐘電路、復位電路組成,時鐘電路選用了12MHZ的晶振提供時鐘,作用為給單片機提供一個時間基準,其中執行一條基本指令需要的時間為一個機器周期,單片機的復位電路,按下復位按鍵之后可以使單片機進入剛上電的起始狀態。圖中10K排阻為P0口的上拉電阻,由于P0口跟其他IO結構不一樣為漏極開路的結構,因此要加上拉電阻才能正常使用。
3.2.3液晶顯示部分與STC89C52的接口 如圖3.5所示。用STC89C52的P0口作為數據線,用P1.2、P1.1、P1.0分別作為LCD的EN、R/W、RS。其中EN是下降沿觸發的片選信號,R/W是讀寫信號,RS是寄存器選擇信號本模塊設計要點如下:顯示模塊初始化:首先清屏,再設置接口數據位為8位,顯示行數為1行,字型為5×7點陣,然后設置為整體顯示,取消光標和字體閃爍,最后設置為正向增量方式且不移位[10]。向LCD的顯示緩沖區中送字符,程序中采用2個字符數組,一個顯示字符,另一個顯示電壓數據,要顯示的字符或數據被送到相應的數組中,完成后再統一顯示.首先取一個要顯示的字符或數據送到LCD的顯示緩沖區,程序延時2.5ms,判斷是否夠顯示的個數,不夠則地址加一取下一個要顯示的字符或數據。 圖3.5 LCD1602與STC89C52的引腳連接圖
3.3信號采集電路設計 此部分電路的功能是由傳感器將脈搏信號轉換為電信號,一般為幾十毫伏,必須加以放大,以達到整形電路所需的電壓,一般為幾伏。放大后的信號波形是不規則的脈沖信號,因此必須加以濾波整形,整形電路的輸出電壓應滿足計數器的要求。選擇電路:所選放大整形電路框圖如圖3.8所示。 圖3.8 放大整形電路框圖 3.3.1傳感器簡介 傳感器采用了紅外光電轉換器,作用是通過紅外光照射人的手指的血脈流動情況,把脈搏跳動轉換為電信號,其原理電路如圖3.9所示。 圖3.9 傳感器信號調節原理電路 如圖3.9中,紅外管VD采用ST188。用+5V電源供電,R1取150Ω,R2取33kΩ,當人把手指放在發光二極管和光電二極管之間的時候,光電二極管接收到的信號會隨人脈搏強度的變化而變化[11]。 3.3.2濾波電路 圖3.10 放大濾波電路 圖3.10為脈搏計的放大濾波信號,由于脈搏信號輸出的信號十分微弱,一般在uV級別,除此外輸出的信號一般會伴隨很大的噪聲干擾,因此在這里用LM358搭建起一個放大和濾波電路。 3.3.3放大整形電路 經過放大濾波后的脈搏信號仍是不規則的脈沖信號,且有低頻干擾,仍不滿足計數器的要求,必須采用整形電路,這里選用了滯回電壓比較器,如圖3.11所示,其目的是為了提高抗干擾能力。集成運放采用了LM358,除此外LM358還接上了一個LED用作指示脈搏跳動的狀態。 圖3.11波形整形電路 3.4 數字溫度傳感器模塊3.4.1 DS18B20性能- 獨特的單線接口僅需一個端口引腳進行通信
- 簡單的多點分布應用
- 無需外部器件
- 可通過數據線供電
- 零待機功耗
- 測溫范圍-55~+125℃,以0.5℃遞增
- 可編程的分辨率為9~12位,對應的可分辨溫度分別為0.5℃、0.25℃、0.125℃和0.0625℃
- 溫度數字量轉換時間200ms,12位分辨率時最多在750ms內把溫度轉換為數字
- 應用包括溫度控制、工業系統、消費品、溫度計和任何熱感測系統
- 負壓特性:電源極性接反時,傳感器不會因發熱而燒毀,但不能正常工作
3.4.2 DS18B20外形及引腳說明
圖3 DS18B20外形及引腳
- GND:地
- DQ:單線運用的數據輸入/輸出引腳
- VD:可選的電源引腳
3.4.3 DS18B20接線原理圖單總線通常要求接一個約10K左右的上拉電阻,這樣,當總線空閑時,其狀態為高電平。
圖4 DS18B20接線原理圖
3.4.4 DS18B20時序圖 主機使用時間隙來讀寫DS18B20的數據位和寫命令字的位。
圖5 DS18B20初始化時序
圖6 DS18B20讀寫時序 3.4.5 數據處理 高速暫存存儲器由9個字節組成,其分配如表5所示。當溫度轉換命令發布后,經轉換所得的溫度值以二字節補碼形式存放在 高速暫存存儲器的第0和第1個字節。單片機可通過單線接口讀到該數據,讀取時低位在前,高位在后。 圖7 字節分配
下表為12位轉化后得到的12位數據,存儲在18B20的兩個8比特的RAM中,二進制中的前面5位是符號位,如果測得的溫度大于0, 這5位為0,只要將測到的數值乘于0.0625即可得到實際溫度;如果溫度小于0,這5位為1,測到的數值需要取反加1再乘于0.0625即可得到實際 溫度。 例如+125℃的數字輸出為07D0H, 實際溫度=07D0H*0.0625=2000*0.0625=125℃。 例如-55℃的數字輸出為FC90H,則應先將11位數據位取反加1得370H(符號位不變,也不作運算), 實際溫度=370H*0.0625=880*0.0625=55℃。 可見其中低四位為小數位。
圖8 DS18B20溫度數據表 第四章 系統軟件設計 4.1系統軟件總體設計 圖4.1系統流程圖 主程序流程圖如圖4.1所示,單片機上電后先進行初始化,清楚一些參數的初值,然后等待用戶按下對應的按鍵并進入對應的功能,當用戶按下測量按鍵的時候流程如圖4.1(c)所示,單片機通過定時15s測量人體的脈搏次數流程如圖4.1(b)所示,然后再換算出對應的真實的脈搏次數再在液晶屏幕上顯示流程如圖4.1(a)所示,當用戶按下設置脈搏范圍設定按鍵后,單片機根據用戶按下的按鍵進行增加或減少范圍。 首先先調用液晶自定義的字庫,設置好DDRAM地址后在第一行顯示,根據程序中的數據設置顯示數據的首地址并設置循環量,在循環過程中不斷的取字符代碼直到終止,第二行的顯示過程同一行的顯示過程一樣,兩行顯示完畢后便結束子程序,如圖4.2所示[15]。 圖4.2 LCD1602初始化子函數流程圖 4.2程序設計原理 軟件任務分析和硬件電路設計結合進行,哪些功能由硬件完成,哪些任務由軟件完成,在硬件電路設計基本定型后,也就基本上決定下來了。 軟件任務分析環節是為軟件設計做一個總體規劃。從軟件的功能來看可分為兩大類:一類是執行軟件,它能完成各種實質性的功能,如測量,計算,顯示,打印,輸出控制和通信等,另一類是監控軟件,它是專門用來協調各執行模塊和操作者的關系,在系統軟件中充當組織調度角色的軟件。這兩類軟件的設計方法各有特色,執行軟件的設計偏重算法效率,與硬件關系密切,千變萬化。 軟件任務分析時,應將各執行模塊一一列出,并為每一個執行模塊進行功能定義和接口定義(輸入輸出定義)。在各執行模塊進行定義時,將要牽扯到的數據結構和數據類型問題也一并規劃好。 各執行模塊規劃好后,就可以監控程序了。首先根據系統功能和鍵盤設置選擇一種最適合的監控程序結構。相對來講,執行模塊任務明確單純,比較容易編程,而監控程序較易出問題。這如同當一名操作工人比較容易,而當一個廠長就比較難了。 軟件任務分析的另一個內容是如何安排監控軟件和各執行模塊。整個系統軟件可分為后臺程序(背景程序)和前臺程序。后臺程序指主程序及其調用的子程序,這類程序對實時性要求不是太高,延誤幾十ms甚至幾百ms也沒關系,故通常將監控程序(鍵盤解釋程序),顯示程序和打印程序等與操作者打交道的程序放在后臺程序中執行;而前臺程序安排一些實時性要求較高的內容,如定時系統和外部中斷(如掉電中斷)。也可以將全部程序均安排在前臺,后臺程序為“使系統進入睡眠狀態”,以利于系統節電和抗干擾。
第五章 系統調試
5.1軟件調試 基于單片機的脈搏計系統是多功能的數字型設計,,所以對于它的程序也較為復雜,所以在編寫程序和調試時出現了相對較多的問題。最后經過多次的模塊子程序的修改,一步一步的完成,最終解決了軟件。在軟件的調試過程中主要遇到的問題如下: 問題1:燒入程序后,LCD液晶顯示閃動,而且亮度不均勻。 解決:首先對調用的延時進行逐漸修改,可以解決顯示閃動問題。其次,由于本作品使作動態掃描方式顯示的數字,動態掃描很快,人的肉眼是無法看出,但是調用的顯示程序時,如果不在反回時屏蔽掉最后的附值,則會出現很亮的現象,所以在顯示的后面加了屏蔽子令,最后解決了此問題。 問題2:當用戶按下按鍵的時候,單片機讀取的數值跟設定的數值不對。 解決:重新檢查矩陣鍵盤電路的連接,重新建立一個新的對應關系。 5.2硬件調試 基于單片機的脈搏計系統的電路較大,對于焊接方面更是不可輕視,龐大的電路系統中只要出于一處的錯誤,則會對檢測造成很大的不便,而且電路的交線較多,對于各種鋒利的引腳要注意處理,否則會刺破帶有包皮的導線,則會對電路造成短路現象[14]。 在本脈搏計的設計調試中遇到了很多的問題。回想這些問題只要認真多思考都是可以避免的,以下為主要的問題: 問題1:最開始的時候以為單片機IO口直接可以驅動蜂鳴器發聲,后來調試的時候久久不能出聲音(見附錄C)。 解決:經過查找相關資料,知道揚聲器需要三極管來驅動,后來把三極管放大器加上系統便可以正常工作。 問題2:開始的時候由于沒想到脈搏信號十分微弱大概在uV級別,因此沒有放大足夠的倍數,單片機最后沒有檢測到脈搏的信號(見附錄C)。 解決:經過查找相關資料,確定脈搏信號的幅值范圍后,增加放大器的放大倍數就解決問題。 5.3調試結果 1.放大倍數的增加 傳感器的輸出端經示波器觀察有幅度很小的正弦波,但經整形輸出后檢測到的脈沖還是很弱,在確定電路沒有問題的情況下,加強信號的放大倍數,調整電阻R23和R27的阻值。 2.時鐘的調試 根據晶體振蕩頻率計算出內部定時器的基本參數,通過運行一段時間可通過秒表來校正后,看時間誤差的量,以這個量為依據改變程序中的內部定時器基本參數,就可使時鐘調準確。 3.開機后無顯示 首先檢查交流電源部分,有無交流,若無則可能保險管或變壓器燒壞,如有繼續查直流有無,如無則電源已燒壞,可更換解決。 4.顯示正常但經適當運動后測量,脈搏次數沒有增加 可能是前置放大級有問題,可采用更換的辦法判斷并排除。 5.進人測量狀態, 但測量值不穩定 主要是光電傳感器受到電磁波等干擾,其次是損壞或有虛焊。 6.開機后顯示不正常或按鍵失靈 可查手指擺放的位置或按鍵電路,若無故障則是硬件損壞。 經過一系列的問題查找后系統最終能正常工作,并完成所有的功能。 5.4誤差分析
注:實際的脈搏次數以聽診器測出的脈搏次數為參考值。 表3.1列出了測量值,但存在誤差,由于傳感器和其他器件本身并非理想線性,實測數據進行了線性補償。 由均方差公式得: =0.59
誤差分析:經校準,非線性補償后,誤差以基本達到要求。 附錄A:系統整體原理圖:
附錄B:系統源程序 - #include <reg52.h> //調用單片機頭文件
- #define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
- #include<DS18N02.h>
- #include <intrins.h>
- #include "eeprom52.h"
-
-
- #define DBPort P0
-
- unsigned char i=0,timecount=0,displayOK=0,rate=0,rate1=0,aa=0,time1=0,flat300ms=0;
- unsigned int time[6]={0};
- unsigned int oneminte=0;
- unsigned int ReadTempDate;
- unsigned char S_temp_H,S_temp_L,S_heart_H,S_heart_L;
- unsigned char yemian=0,biaozhi=0;
-
-
- sbit K1 = P1^0; //菜單
- sbit K2 = P1^1; //加
- sbit K3 = P1^2; //減
- sbit Buzzer= P1^7; //控制端
-
-
- sbit rs = P2^5 ;
- sbit rw = P2^6 ;
- sbit ep = P2^7 ;
-
-
- bit flag=1;
-
-
- /******************把數據保存到單片機內部eeprom中******************/
- void write_eeprom()
- {
- SectorErase(0x2000);
- byte_write(0x2000, S_heart_H);
- byte_write(0x2001, S_heart_L);
- byte_write(0x2002, S_temp_H);
- byte_write(0x2003, S_temp_L);
-
-
- byte_write(0x2060, a_a);
- }
-
- /******************把數據從單片機內部eeprom中讀出來*****************/
- void read_eeprom()
- {
- S_heart_H = byte_read(0x2000);
- S_heart_L = byte_read(0x2001);
- S_temp_H = byte_read(0x2002);
- S_temp_L = byte_read(0x2003);
- a_a = byte_read(0x2060);
- }
-
- /**************開機自檢eeprom初始化*****************/
- void init_eeprom()
- {
- read_eeprom(); //先讀
- if(a_a != 2) //新的單片機初始單片機內問eeprom
- {
- S_heart_H = 120;
- S_heart_L = 60;
- S_temp_H = 38;
- S_temp_L = 5;
- a_a = 2;
- write_eeprom();
- }
- }
-
- /***********************1ms延時函數*****************************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<110;j++);
- }
-
-
- /********************************************************************
- * 名稱 : delay_uint()
- * 功能 : 小延時。
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void delay_uint(uint q)
- {
- while(q--);
- }
-
-
- typedef bit BOOL ;
-
-
- uchar data_byte;
-
- void delay(uchar ms)
- { // 延時子程序
- uchar i ;
- while(ms--)
- {
- for(i = 0 ; i<250;i++) ;
- }
- }
-
-
- /************************LCD模塊******************************************/
-
- BOOL lcd_bz()//測試LCD忙碌狀態
- {
- BOOL result ;
- rs = 0 ;
- rw = 1 ;
- ep = 1 ;
- result = (BOOL)(P0 & 0x80) ;
- ep = 0 ;
- return result ;
- }
-
- void lcd_init()// 初始化
- {
- write_cmd(0x38) ;
- delay(1);
- write_cmd(0x08) ;
- delay(1);
- write_cmd(0x01) ;
- delay(1);
- write_cmd(0x06) ;
- delay(1);
- write_cmd(0x0c) ;
- delay(1);
- }
-
- display(uchar addr, uchar q)//在某一地址上顯示一字節
- {
- delay(1) ;
- write_addr(addr) ;
- write_byte(q) ;
- // longdelay(1) ;
-
- }
-
-
- void show1()
- {
- lcd_init();// 初始化
- // Welcome
-
-
- display(0x05,'W');
- display(0x06,'e');
- display(0x07,'l');
- display(0x08,'c');
- display(0x09,'o');
- display(0x0a,'m');
- display(0x0b,'e');
- longdelay(50);//短暫延時
-
-
- display(0x42,' ');
- display(0x43,' ');
- display(0x44,' ');
- display(0x45,' ');
- display(0x46,' ');
- display(0x48,' ');
- display(0x49,' ');
- display(0x4a,' ');
- display(0x4b,' ');
- longdelay(50);//短暫延時
-
- /*
- //2012283443
- display(0x02,'2');
- display(0x03,'0');
- display(0x04,'1');
- display(0x05,'2');
- display(0x06,'2');
- display(0x07,'8');
- display(0x08,'3');
- display(0x09,'4');
- display(0x0a,'4');
- display(0x0b,'3');
- longdelay(50);//短暫延時
-
- //TEL:18268256180
- display(0x40,'T');
- display(0x41,'e');
- display(0x42,'l');
- display(0x43,':');
- display(0x44,'1');
- display(0x45,'8');
- display(0x46,'2');
- display(0x47,'6');
- display(0x48,'8');
- display(0x49,'2');
- display(0x4a,'5');
- display(0x4b,'6');
- display(0x4c,'1');
- display(0x4d,'8');
- display(0x4e,'0');
- longdelay(50);//短暫延時
- */
- }
-
-
-
-
-
- void shezhi() //對里面的數值進行修改
- {
- if(!K2) //按下按鍵
- {
- delay_1ms(20);
- if(!K2)
- {
- if(yemian==1)
- {
- S_heart_H+=1; //沒按下一次,數值加1
- if(S_heart_H>=200) {S_heart_H=200;}
- write_eeprom(); //保存數據
-
- display(0x46,S_heart_H/100+'0');
- display(0x47,S_heart_H%100/10+'0');
- display(0x48,S_heart_H%100%10+'0');
- }
-
- if(yemian==2)
- {
- S_heart_L+=1; //沒按下一次,數值加1
- if(S_heart_L>=200) {S_heart_L=200;}
- write_eeprom(); //保存數據
-
- display(0x46,S_heart_L/100+'0');
- display(0x47,S_heart_L%100/10+'0');
- display(0x48,S_heart_L%100%10+'0');
- }
-
- if(yemian==3)
- {
- S_temp_H+=1; //沒按下一次,數值加1
- if(S_temp_H>=125) {S_temp_H=125;}
- write_eeprom(); //保存數據
-
- display(0x46,S_temp_H/100+'0');
- display(0x47,S_temp_H%100/10+'0');
- display(0x48,S_temp_H%100%10+'0');
- }
-
- if(yemian==4)
- {
- S_temp_L+=1; //沒按下一次,數值加1
- if(S_temp_L>=125) {S_temp_L=125;}
- write_eeprom(); //保存數據
-
- display(0x46,S_temp_L/100+'0');
- display(0x47,S_temp_L%100/10+'0');
- display(0x48,S_temp_L%100%10+'0');
- }
-
- }
- // while(!K2); //等待按鍵 彈起 屏蔽此句,可以實現按鍵按下不放開時,連加技術功能,
- // 不過需要將上面延時去抖時間延長效果才好。建議改為: delay_LCD(50);
- }
-
-
- if(!K3) //按下按鍵
- {
- delay_1ms(20);
- if(!K3)
- {
- if(yemian==1)
- {
-
- if(S_heart_H<=1) {S_heart_H=1;}
- S_heart_H-=1; //沒按下一次,數值加1
- write_eeprom(); //保存數據
-
- display(0x46,S_heart_H/100+'0');
- display(0x47,S_heart_H%100/10+'0');
- display(0x48,S_heart_H%100%10+'0');
-
- }
-
-
- if(yemian==4)
- {
- if(S_temp_L<=1) {S_temp_L=1;}
- S_temp_L-=1; //沒按下一次,數值加1
- write_eeprom(); //保存數據
-
- display(0x46,S_temp_L/100+'0');
- display(0x47,S_temp_L%100/10+'0');
- display(0x48,S_temp_L%100%10+'0');
-
-
- }
- }
- // while(!K3); //等待按鍵 彈起 //等待按鍵 彈起 屏蔽此句,可以實現按鍵按下不放開時,連加技術功能,
- // 不過需要將上面延時去抖時間延長效果才好。建議改為: delay_LCD(50);
- }
-
-
- }
-
- void wendumaibo()
- {
-
- if(displayOK==0)//如果顯示關
- {
- display(0x06,'W');
- display(0x07,'a');
- display(0x08,'i');
- display(0x09,'t');
- display(0x0a,'i');
- display(0x0b,'n');
- display(0x0c,'g');
- flag=1;
- oneminte=0;//加上這個,當displayOK標志位沒有置1時,都清零計數,等待重新檢測中計數。
- }
-
- if(displayOK==1 && oneminte<=200)//如果顯示開
- {
- flag=0;
- display(0x06,'T');
- display(0x07,'e');
- display(0x08,'s');
- display(0x09,'t');
- display(0x0a,'i');
- display(0x0b,'n');
- display(0x0c,'g');
- }
-
- ReadTempDate=ReadTemperature();
- display(0x46,ReadTempDate/100+'0');
- display(0x47,ReadTempDate%100/10+'0');
- display(0x48,'.');
- display(0x49,ReadTempDate%100%10+'0');
- display(0x4a,0xdf);
- display(0x4b,'C');
- }
-
-
- void baojin()
- {
- if( ( (rate*6<S_heart_L || rate*6>S_heart_H) && oneminte>200 ) || ReadTempDate>=S_temp_H*10 || ReadTempDate<=S_temp_L*10 ) { Buzzer=0; }
-
- if( oneminte>=0 && oneminte<200 && ReadTempDate<S_temp_H*10 && ReadTempDate>S_temp_L*10 ) { Buzzer=1; }
- }
-
- /*************定時器0初始化程序***************/
- void time_init()
- {
- EA = 1; //開總中斷
- TMOD = 0X01; //定時器0、定時器1工作方式1
- ET0 = 1; //開定時器0中斷
- TR0 = 1; //允許定時器0定時
- }
-
-
- /***********外部中斷0初始化程序****************/
- void init_int0() //外部中斷0初始化程序
- {
- EX0=1; //允許外部中斷0中斷
- EA=1; //開總中斷
- IT0 = 1; //外部中斷0負跳變中斷
- }
-
- /****************主函數***************/
- void main()
- {
- ReadTemperature();
- show1();//顯示問候語和其他信息
- time_init(); //初始化定時器
- init_int0(); //外部中斷0初始化程序
- init_eeprom(); //讀eeprom數據
- while(1)
- {
- key(); //按鍵掃描
- if(flat300ms>=4) //200ms
- {
- flat300ms=0;
- //==================主界面===================
- if(yemian==0)
- {
- if(biaozhi==0)
- {
- biaozhi=1;
-
- lcd_init();// 初始化
- display(0x00,'H');
- display(0x01,'e');
- display(0x02,'a');
- display(0x03,'r');
- display(0x04,'t');
- display(0x05,':');
-
- display(0x40,'T');
- display(0x41,'e');
- display(0x42,'m');
- display(0x43,'p');
- display(0x44,':');
- }
- wendumaibo();
- baojin();
- }
-
- //==================脈搏報警上限 設置===================
- if(yemian==1)
- {
- if(biaozhi==1)
- {
- biaozhi=2;
- Buzzer=1;
- lcd_init();// 初始化
- display(0x04,'H');
- display(0x05,'e');
- display(0x06,'a');
- display(0x07,'r');
- display(0x08,'t');
- display(0x09,'-');
- display(0x0a,'H');
-
- display(0x46,S_heart_H/100+'0');
- display(0x47,S_heart_H%100/10+'0');
- display(0x48,S_heart_H%100%10+'0');
- }
- shezhi();
- }
-
- //==================脈搏報警下限 設置===================
- if(yemian==2)
- {
- if(biaozhi==2)
- {
- biaozhi=3;
- Buzzer=1;
- lcd_init();// 初始化
- display(0x04,'H');
- display(0x05,'e');
- display(0x06,'a');
- display(0x07,'r');
- display(0x08,'t');
- display(0x09,'-');
- display(0x0a,'L');
-
- display(0x46,S_heart_L/100+'0');
- display(0x47,S_heart_L%100/10+'0');
- display(0x48,S_heart_L%100%10+'0');
- }
- shezhi();
- }
-
- //==================溫度報警 上限設置===================
- if(yemian==3)
- {
- if(biaozhi==3)
- {
- biaozhi=4;
- Buzzer=1;
- lcd_init();// 初始化
-
- display(0x05,'T');
- display(0x06,'e');
- display(0x07,'m');
- display(0x08,'p');
- display(0x09,'-');
- display(0x0a,'H');
-
- display(0x46,S_temp_H/100+'0');
- display(0x47,S_temp_H%100/10+'0');
- display(0x48,S_temp_H%100%10+'0');
- }
- shezhi();
- }
-
- //==================溫度報警 下限設置===================
- if(yemian==4)
- {
- if(biaozhi==4)
- {
- biaozhi=0;
- Buzzer=1;
- lcd_init();// 初始化
-
- display(0x05,'T');
- display(0x06,'e');
- display(0x07,'m');
- display(0x08,'p');
- display(0x09,'-');
- display(0x0a,'L');
-
- display(0x46,S_temp_L/100+'0');
- display(0x47,S_temp_L%100/10+'0');
- display(0x48,S_temp_L%100%10+'0');
- }
- shezhi();
- }
-
-
- }
- }
- }
-
-
- void int0() interrupt 0
- {
- if(time1>=8)
- {
- time1=0;
- timecount=0;//50ms計數清零
- i++;
- if(i==3)//記錄到超過等于3次時間
- {
- i=1;//計數從1開始
- displayOK=1; //測得3次開始顯示
- }
-
- if(displayOK==1 && oneminte<=200 &&yemian==0) { rate1=0; rate ++; } //10s
- if( oneminte>200 && flag==0 && yemian==0)
- {
- flag=1;
- rate1=rate*6;
-
- display(0x09,'/');
- display(0x0a,'m');
- display(0x0b,'i');
- display(0x0c,'n');
-
- display(0x06,rate1/100+'0');
- display(0x07,rate1%100/10+'0');
- display(0x08,rate1%100%10+'0');
- }
-
- }
-
- }
-
-
- /*************定時器0中斷服務程序***************/
- void time0_int() interrupt 1
- {
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms 12M
- timecount++;//每50ms一次計數
- time1++;
-
- oneminte++;
- flat300ms++;
- if(timecount>50 &&yemian==0 ) //當超過50*50ms=2.5s左右沒有檢測到信號停止顯示
- {
- i=0;//數據個數清零
- timecount=0;//50ms計數清零
- displayOK=0;//顯示關
- oneminte=0;
- rate=0;
- display(0x06,'W');
- display(0x07,'a');
- display(0x08,'i');
- display(0x09,'t');
- display(0x0a,'i');
- display(0x0b,'n');
- display(0x0c,'g');
-
-
- }
- }
復制代碼
以上的Word格式文檔51黑下載地址:
參考文檔.doc
(895.27 KB, 下載次數: 18)
2020-11-12 10:19 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|