




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
學(xué)習(xí)情境2-可調(diào)式數(shù)字鐘基于DS1302和LCD1602的可調(diào)數(shù)字鐘前面的任務(wù)中我們學(xué)會了使用DS1302,知道了如何在單片機系統(tǒng)中的連接,也詳細的學(xué)習(xí)了如何得到DS1302的時鐘,并且我們使用了16個數(shù)碼管把年月日和時分秒實時地顯示出來。但數(shù)碼管的顯示畢竟有其自身的缺陷,現(xiàn)在在工業(yè)控制的各個環(huán)節(jié),都使用液晶進行人機聯(lián)系。在日常生活中,我們對液晶顯示器并不陌生。液晶顯示模塊已作為很多電子產(chǎn)品的通用器件,如在計算器、萬用表、電子表及很多家用電子產(chǎn)品中都可以看到,顯示的主要是數(shù)字、專用符號和圖形。在單片機的人機交流界面中,一般的輸出方式有以下幾種:發(fā)光管、LED數(shù)碼管、液晶顯示器。發(fā)光管和LED數(shù)碼管比擬常用,軟硬件都比擬簡單。本任務(wù)中,我們使用LCD1602液晶顯示器芯片作為時鐘顯示的硬件,這將大大簡化電路結(jié)構(gòu),當(dāng)然,在軟件設(shè)計方面就比數(shù)碼管復(fù)雜得多了。通過本任務(wù)的學(xué)習(xí)。希望能掌握LCD1602的軟硬件設(shè)計方法,為以后學(xué)習(xí)功能更強大的液晶芯片作好知識儲藏。3.1任務(wù)設(shè)計要求和設(shè)計原理一、設(shè)計要求1、利用專用時鐘芯片DS1302獲得秒、分、時、日、月、年等時間單位。2、用液晶顯示芯片LCD1602實時顯示時間3、能通過外部按鍵調(diào)節(jié)時間4、利用Proteus軟件設(shè)計電路原理圖、PCB圖、并結(jié)合軟件進行仿真測試5、利用Keil軟件設(shè)計C語言源程序,通過編譯、鏈接后生成HEX文件二、設(shè)計原理本任務(wù)主要由單片機AT89C52、時鐘芯片DS1302、液晶顯示芯片LCD1602等元器件組成。單片機是整個系統(tǒng)的主控芯片,主要負責(zé)對時鐘芯片內(nèi)部數(shù)據(jù)進行讀寫、并把讀取的數(shù)據(jù)處理后實時送給數(shù)碼管顯示;DS1302時鐘芯片那么產(chǎn)生本任務(wù)所需的時間:秒、分、時、日、月、年這6個時間單元,DS1302通過串行方式與單片機相連,在該芯片的時鐘及復(fù)位引腳信號的控制下實現(xiàn)與單片機的數(shù)據(jù)通信,同時,利用4輸入與門和4個獨立按鍵實行對時間的調(diào)節(jié),可調(diào)節(jié)年、月、日、時、分等5個時間單元,星期時間的調(diào)節(jié)會自動進行。在時間的顯示方面,使用了LCD1602,這大大簡化了電路結(jié)構(gòu),LCD1602通過P0口與單片機相連,顯示的時間數(shù)據(jù)均由單片機的P0口輸出,P0口外接上拉電阻。當(dāng)系統(tǒng)上電后,LCD1602顯示時間〔在仿真條件下,可設(shè)置為顯示電腦時間〕,反復(fù)按下K1按鍵,可依次調(diào)節(jié)年、月、日、時、分,按下K2按鍵,可對相應(yīng)時間進行加調(diào)節(jié),按下K3按鍵,可對相應(yīng)時間進行的減調(diào)節(jié),按下確定按鍵K4,表示時間調(diào)節(jié)完畢。3.2硬件設(shè)計一、硬件電路設(shè)計本硬件系統(tǒng)電路包括:單片機最小系統(tǒng)〔包含時鐘電路、復(fù)位電路和電源電路〕、LCD顯示電路、按鍵調(diào)節(jié)電路和DS1302時鐘電路。系統(tǒng)原理框圖如以下圖所示:8051單8051單片機時鐘電路、復(fù)位電路、電源電路LCD顯示電路LCD顯示電路按鍵調(diào)節(jié)電路DS1302時鐘電路按鍵調(diào)節(jié)電路DS1302時鐘電路圖3-1系統(tǒng)框圖系統(tǒng)各局部電路結(jié)構(gòu)簡單,在此不一一單獨介紹,只簡單介紹LCD顯示電路,其電路設(shè)計原理圖如圖3-2所示。圖3-2LCD1602液晶顯示電路從圖可知,液晶芯片LCD1602的D0-D7與單片機的P0口相連接,且也外接上拉電阻。引腳RS、RW和E分別與P2口的P2.O、P2.1和P2.2連接,當(dāng)然你愿意的話也可以和其他未使用的端口相連。其余電路不作介紹,本任務(wù)整體系統(tǒng)電路原理圖如圖3-3所示。圖3-3整體系統(tǒng)電路原理圖二、LCD1602技術(shù)資料在單片機系統(tǒng)中應(yīng)用液晶顯示器作為輸出器件有以下幾個優(yōu)點:〔1〕顯示質(zhì)量高,由于液晶顯示器每一個點在收到信號后就一直保持那種色彩和亮度,恒定發(fā)光,而不像陰極射線管顯示器〔CRT〕那樣需要不斷刷新新亮點。因此,液晶顯示器畫質(zhì)高且不會閃爍?!?〕數(shù)字式接口,液晶顯示器都是數(shù)字式的,和單片機系統(tǒng)的接口更加簡單可靠,操作更加方便。〔3〕體積小、重量輕,液晶顯示器通過顯示屏上的電極控制液晶分子狀態(tài)來到達顯示的目的,在重量上比相同顯示面積的傳統(tǒng)顯示器要輕得多?!?〕功耗低,相對而言,液晶顯示器的功耗主要消耗在其內(nèi)部的電極和驅(qū)動IC上,因而耗電量比其它顯示器要少得多。1、液晶顯示原理:液晶顯示的原理是利用液晶的物理特性,通過電壓對其顯示區(qū)域進行控制,有電就有顯示,這樣即可以顯示出圖形。液晶顯示器具有厚度薄、適用于大規(guī)模集成電路直接驅(qū)動、易于實現(xiàn)全彩色顯示的特點,目前已經(jīng)被廣泛應(yīng)用在便攜式電腦、數(shù)字攝像機、PDA移動通信工具等眾多領(lǐng)域。2、液晶顯示器的分類:液晶顯示的分類方法有很多種,通??砂雌滹@示方式分為段式、字符式、點陣式等。除了黑白顯示外,液晶顯示器還有多灰度有彩色顯示等。如果根據(jù)驅(qū)動方式來分,可以分為靜態(tài)驅(qū)動〔Static〕、單純矩陣驅(qū)動〔SimpleMatrix〕和主動矩陣驅(qū)動〔ActiveMatrix〕三種。3、液晶顯示器各種圖形的顯示原理:線段的顯示:點陣圖形式液晶由M×N個顯示單元組成,假設(shè)LCD顯示屏有64行,每行有128列,每8列對應(yīng)1字節(jié)的8位,即每行由16字節(jié),共16×8=128個點組成,屏上64×16個顯示單元與顯示RAM區(qū)1024字節(jié)相對應(yīng),每一字節(jié)的內(nèi)容和顯示屏上相應(yīng)位置的亮暗對應(yīng)。例如屏的第一行的亮暗由RAM區(qū)的000H——00FH的16字節(jié)的內(nèi)容決定,當(dāng)〔000H〕=FFH時,那么屏幕的左上角顯示一條短亮線,長度為8個點;當(dāng)〔3FFH〕=FFH時,那么屏幕的右下角顯示一條短亮線;當(dāng)〔000H〕=FFH,〔001H〕=00H,〔002H〕=00H,……〔00EH〕=00H,〔00FH〕=00H時,那么在屏幕的頂部顯示一條由8段亮線和8條暗線組成的虛線。這就是LCD顯示的根本原理。字符的顯示:用LCD顯示一個字符時比擬復(fù)雜,因為一個字符由6×8或8×8點陣組成,既要找到和顯示屏幕上某幾個位置對應(yīng)的顯示RAM區(qū)的8字節(jié),還要使每字節(jié)的不同位為“1”,其它的為“0”,為“1”的點亮,為“0”的不亮。這樣一來就組成某個字符。但由于內(nèi)帶字符發(fā)生器的控制器來說,顯示字符就比擬簡單了,可以讓控制器工作在文本方式,根據(jù)在LCD上開始顯示的行列號及每行的列數(shù)找出顯示RAM對應(yīng)的地址,設(shè)立光標(biāo),在此送上該字符對應(yīng)的代碼即可。漢字的顯示:漢字的顯示一般采用圖形的方式,事先從微機中提取要顯示的漢字的點陣碼〔一般用字模提取軟件〕,每個漢字占32B,分左右兩半,各占16B,左邊為1、3、5……右邊為2、4、6……根據(jù)在LCD上開始顯示的行列號及每行的列數(shù)可找出顯示RAM對應(yīng)的地址,設(shè)立光標(biāo),送上要顯示的漢字的第一字節(jié),光標(biāo)位置加1,送第二個字節(jié),換行按列對齊,送第三個字節(jié)……直到32B顯示完就可以LCD上得到一個完整漢字。1602字符型LCD簡介字符型液晶顯示模塊是一種專門用于顯示字母、數(shù)字、符號等點陣式LCD,目前常用16*1,16*2,20*2和40*2行等的模塊。一般1602字符型液晶顯示器實物如圖3-4:圖3-41602字符型液晶顯示器實物圖1602LCD分為帶背光和不帶背光兩種,其控制器大局部為HD44780,帶背光的比不帶背光的厚,是否帶背光在應(yīng)用中并無差異。1602LCD主要技術(shù)參數(shù):顯示容量:16×2個字符;芯片工作電壓:4.5—5.5V;工作電流:2.0mA(5.0V);模塊最正確工作電壓:5.0V;字符尺寸:2.95×4.35(W×H)mm
引腳功能說明:1602LCD采用標(biāo)準的14腳〔無背光〕或16腳〔帶背光〕接口,各引腳接口說明如表1所示:第1腳:VSS為地電源。第2腳:VDD接5V正電源。第3腳:VL為液晶顯示器比照度調(diào)整端,接正電源時比照度最弱,接地時比照度最高,比照度過高時會產(chǎn)生“鬼影〞,使用時可以通過一個10K的電位器調(diào)整比照度。第4腳:RS為存放器選擇,高電平時選擇數(shù)據(jù)存放器、低電平時選擇指令存放器。第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當(dāng)RS和R/W共同為低電平時可以寫入指令或者顯示地址,當(dāng)RS為低電平R/W為高電平時可以讀忙信號,當(dāng)RS為高電平R/W為低電平時可以寫入數(shù)據(jù)。第6腳:E端為使能端,當(dāng)E端由高電平跳變成低電平時,液晶模塊執(zhí)行命令。第7~14腳:D0~D7為8位雙向數(shù)據(jù)線。第15腳:背光源正極。第16腳:背光源負極。表11602LCD引腳接口說明編號符號引腳說明編號符號引腳說明1VSS電源地9D2數(shù)據(jù)2VDD電源正極10D3數(shù)據(jù)3VL液晶顯示偏壓11D4數(shù)據(jù)4RS數(shù)據(jù)/命令選擇12D5數(shù)據(jù)5R/
W讀/寫選擇13D6數(shù)據(jù)6E使能信號14D7數(shù)據(jù)7D0數(shù)據(jù)15BL
A背光源正極8D1數(shù)據(jù)16BL
K背光源負極1602LCD的指令說明及時序1602液晶模塊內(nèi)部的控制器共有11條控制指令,如表2所示:表2:控制命令表序號指令RSR/WD7D6D5D4D3D2D1D0功能1復(fù)位顯示器0000000001清屏,光標(biāo)歸位2光標(biāo)返回000000001*設(shè)置地址計數(shù)器清零,DDRAM數(shù)據(jù)不變,光標(biāo)移到左上角3字符進入模式00000001I/DS設(shè)置字符進入時的屏幕移位方式4顯示開/關(guān)控制0000001DCB設(shè)置顯示開關(guān),光標(biāo)開關(guān),閃爍開關(guān)5光標(biāo)或字符移位000001S/CR/L**設(shè)置字符與光標(biāo)移動6功能設(shè)置00001DLNF**設(shè)置DL,顯示行數(shù),字體7設(shè)置字符發(fā)生存貯器地址0001字符發(fā)生存貯器地址設(shè)置6位的CGRAM地址以讀/寫數(shù)據(jù)8設(shè)置數(shù)據(jù)存貯器地址001顯示數(shù)據(jù)存貯器地址設(shè)置7位的DDRAM地址以讀/寫數(shù)據(jù)9讀忙標(biāo)志或地址01BF計數(shù)器地址讀忙標(biāo)志及地址計數(shù)器10寫數(shù)據(jù)到CGRAM或DDRAM〕10寫入一字節(jié)數(shù)據(jù),需要先設(shè)置RAM地址向CGRAM/DDRAM寫入一字節(jié)的數(shù)據(jù)11從CGRAM或DDRAM讀數(shù)據(jù)11讀取入一字節(jié)數(shù)據(jù),需要先設(shè)置RAM地址從CGRAM/DDRAM讀取一字節(jié)的數(shù)據(jù)I/D=1遞增,I/D=0遞減。S=0時顯示屏不移動,S=1時,如果I/D=1且有字符寫入時顯示屏左移,否那么右移。D=1顯示屏開,D=0顯示屏關(guān)。C=1時光標(biāo)出現(xiàn)在地址計數(shù)器所指的位置,C=0時光標(biāo)不出現(xiàn)。B=1時光標(biāo)出現(xiàn)閃爍,B=0時光標(biāo)不閃爍。S/C=0時,RL=0那么光標(biāo)左移,否那么右移。S/C=1時,RL=0那么字符和光標(biāo)左移,否那么右移。DL=1時數(shù)據(jù)長度為8位,DL=0時為使用D7-D4共4位,分兩次送一字節(jié)。N=0為單行顯示,N=1時為雙行顯示。F=1時為510點陣字體,F(xiàn)=0時為57點陣字體。BF=1時LCD忙,BF=0時LCD就緒。1602液晶模塊的讀寫操作、屏幕和光標(biāo)的操作都是通過指令編程來實現(xiàn)的?!舱f明:1為高電平、0為低電平〕指令1:清顯示,指令碼01H,光標(biāo)復(fù)位到地址00H位置。指令2:光標(biāo)復(fù)位,光標(biāo)返回到地址00H。指令3:光標(biāo)和顯示模式設(shè)置I/D:光標(biāo)移動方向,高電平右移,低電平左移S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平那么無效。指令4:顯示開關(guān)控制。D:控制整體顯示的開與關(guān),高電平表示開顯示,低電平表示關(guān)顯示C:控制光標(biāo)的開與關(guān),高電平表示有光標(biāo),低電平表示無光標(biāo)B:控制光標(biāo)是否閃爍,高電平閃爍,低電平不閃爍。指令5:光標(biāo)或顯示移位S/C:高電平時移動顯示的文字,低電平時移動光標(biāo)。指令6:功能設(shè)置命令DL:高電平時為4位總線,低電平時為8位總線N:低電平時為單行顯示,高電平時雙行顯示F:低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。指令7:字符發(fā)生器RAM地址設(shè)置。指令8:DDRAM地址設(shè)置。指令9:讀忙信號和光標(biāo)地址BF:為忙標(biāo)志位,高電平表示忙,此時模塊不能接收命令或者數(shù)據(jù),如果為低電平表示不忙。指令10:寫數(shù)據(jù)。指令11:讀數(shù)據(jù)。
與HD44780相兼容的芯片時序表如下:表3:根本操作時序表讀狀態(tài)輸入RS=L,R/W=H,E=H輸出D0—D7=狀態(tài)字寫指令輸入RS=L,R/W=L,D0—D7=指令碼,E=高脈沖輸出無讀數(shù)據(jù)輸入RS=H,R/W=H,E=H輸出D0—D7=數(shù)據(jù)寫數(shù)據(jù)輸入RS=H,R/W=L,D0—D7=數(shù)據(jù),E=高脈沖輸出無讀寫操作時序如圖3-5和3-6所示:圖3-5讀操作時序圖3-6寫操作時序1602LCD的RAM地址映射及標(biāo)準字庫表液晶顯示模塊是一個慢顯示器件,所以在執(zhí)行每條指令之前一定要確認模塊的忙標(biāo)志位,如果該位為低電平,表示不忙,否那么此指令失效。要顯示字符時要先輸入顯示字符地址,也就是告訴模塊在哪里顯示字符,圖3-7是1602的內(nèi)部顯示地址。圖3-71602LCD內(nèi)部顯示地址例如第二行第一個字符的地址是40H,那么是否直接寫入40H就可以將光標(biāo)定位在第二行第一個字符的位置呢?這樣不行,因為寫入顯示地址時要求最高位D7恒定為高電平1所以實際寫入的數(shù)據(jù)應(yīng)該是01000000B〔40H〕+10000000B(80H)=11000000B(C0H)。在對液晶模塊的初始化中要先設(shè)置其顯示模式,在液晶模塊顯示字符時光標(biāo)是自動右移的,無需人工干預(yù)。每次輸入指令前都要判斷液晶模塊是否處于忙的狀態(tài)。1602液晶模塊內(nèi)部的字符發(fā)生存儲器〔CGROM〕已經(jīng)存儲了160個不同的點陣字符圖形,如圖3-8所示,這些字符有:阿拉伯?dāng)?shù)字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比方大寫的英文字母“A〞的代碼是01000001B〔41H〕,顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母“A〞圖3-8字符代碼與圖形對應(yīng)圖3.3軟件設(shè)計軟件設(shè)計中主要是針對DS1302芯片和LCD1602進行程序的設(shè)計,而DS1302的驅(qū)動程序在上個工程中我們已經(jīng)作了詳細介紹,在此不再贅述。我們主要編制LCD的驅(qū)動程序。根據(jù)對LCD資料的分析,程序編制主要有:讀取LCD的狀態(tài),忙檢查,向LCD寫入命令,向LCD寫入數(shù)據(jù),LCD初始化,設(shè)置LCD液晶的顯示位置,顯示字符等,具體如下:1、讀取LCD的狀態(tài)//----------讀取LCD的狀態(tài)-------*/ucharRead_LCD_State(){ucharstate;RS=0;RW=1;EN=1;DelayMS(2);state=P0;EN=0;DelayMS(2);returnstate;}2、忙檢查//-------------忙檢查--------------*/voidLCD_Busy_Wait(){while((Read_LCD_State()&0x80)==0x80); DelayMS(5);}3、向LCD寫入命令//-----------寫LCD命令-----------------*/voidWrite_LCD_Command(ucharcmd){LCD_Busy_Wait();RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(2);EN=0;}4、向LCD寫入數(shù)據(jù)//-----------向LCD寫入數(shù)據(jù)-----------------*/voidWrite_LCD_Data(uchardat){LCD_Busy_Wait();RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(2);EN=0;}5、LCD初始化//-----------LCD初始化-----------------*/voidInitialize_LCD1602()//液晶初始化函數(shù){Write_LCD_Command(0x38);DelayMS(2);//功能設(shè)置,數(shù)據(jù)長度為8位,雙行顯示5×7點//陣字體Write_LCD_Command(0x01);DelayMS(2); //清屏Write_LCD_Command(0x06);DelayMS(2);//字符進入模式:屏幕不動,字符后移Write_LCD_Command(0x0c);DelayMS(2); //顯示開,關(guān)光標(biāo)}6、設(shè)置LCD液晶的顯示位置//-----------設(shè)置液晶顯示位置-----------------*/voidSet_LCD_Position(ucharpos){Write_LCD_Command(pos|0x80); //設(shè)置7位的DDRAM地址值}7、顯示字符//-----------在LCD上顯示字符串-----------------*/voidLCD_Display(ucharp,uchar*str){uchari;Set_LCD_Position(p);for(i=0;i<16;i++){Write_LCD_Data(str[i]);DelayMS(2);}}除此之外,還有年、月、日、時、分等的設(shè)置函數(shù),顯示函數(shù),鍵盤處理函數(shù)等,在此不在詳細介紹,同學(xué)們可參考完整程序中的代碼。數(shù)組數(shù)組數(shù)組是在程序設(shè)計中,為了處理方便,把具有相同類型的假設(shè)干變量按有序的形式組織起來的一種形式。這些按序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組。在C語言中,數(shù)組屬于構(gòu)造數(shù)據(jù)類型。一個數(shù)組可以分解為多個數(shù)組元素,這些數(shù)組元素可以是根本數(shù)據(jù)類型或是構(gòu)造類型。因此按數(shù)組元素的類型不同,數(shù)組又可分為數(shù)值數(shù)組、字符數(shù)組、指針數(shù)組、結(jié)構(gòu)數(shù)組等各種類別。一、一維數(shù)組1、一組的定義定義:數(shù)組是有序數(shù)據(jù)(必須是相同的數(shù)據(jù)類型結(jié)構(gòu))的集合。格式:類型說明符數(shù)組名[常量表達式]例如:inttemp[5];表示數(shù)組名為a,有10個元素,并且每個元素的類型都是int型的。floatb[10],c[5];說明實型數(shù)組b有10個元素,實型數(shù)組c有5個元素;注意:〔1〕數(shù)組名的命名規(guī)那么和標(biāo)示符的命名規(guī)那么相同?!?〕常量表達式要有方括號括起來,不能用圓括號,inta(10);這是非法的!〔3〕常量表達式表示數(shù)組元素的個數(shù),即數(shù)組長度。并且數(shù)組的第一個元素是從下標(biāo)0開始的!〔4〕常量表達式可以是常量也可以是符號常量,不能包含變量。C語言絕對不允許對數(shù)組的大小作動態(tài)定義;例如:下面是非法的intn;scanf(“%d〞,&n);inta[n];〔5〕數(shù)組的類型實際上就是指數(shù)組元素的取值類型,對于同一數(shù)組,它所有元素的數(shù)據(jù)類型都是相同的;〔6〕數(shù)組名不能與其他變量名相同;例如:main(){inta;floata[10];………。。}是非法的!〔7〕允許在同一個類型說明中,說明多個數(shù)組和多個變量;例如:inta,b,c,d[10],e[5];2、一維數(shù)組元素的初始化有以下方法初始化:1〕在定義數(shù)組時,對數(shù)組元素賦初值;例如:inta[10]={0,1,2,3,4,5,6,7,8,9};上面的語句等價于a[0]=0,a[1]=1,2〕可以只給一局部元素賦初值,例如:inta[10]={0,1,2,3,4};表示只給數(shù)組的前5個元素賦初值,后5個元素的值,系統(tǒng)自動默認為03〕在對全部數(shù)組元素賦初值時,可以不指定數(shù)組長度;例如:inta[5]={0,1,2,3,4};可以改寫為:inta[]={0,1,2,3,4};但是,inta[10]={0,1,2,3,4};不能改寫為:inta[]={0,1,2,3,4};3、一維數(shù)組的引用數(shù)組必須先定義,后使用。C語言規(guī)定:只能逐個引用數(shù)組元素,而不能一次引用整個數(shù)組!數(shù)組的引用形式為:數(shù)組名[下標(biāo)]其中,下標(biāo)可以是整型常量也可以是整型表達式。例如:a[0]=a[5]+a[7]+a[2*3]4、一維數(shù)組的程序舉例〔1〕讀10個數(shù)存入數(shù)組中,輸出數(shù)組中的所有數(shù)據(jù)。main(){inti,a[10];for(i=0;i<=9;i++)a[i]=i;/*順序給數(shù)組元素賦初*/for(i=0;i<=9;i++)printf(“%d〞,a[i]);/*順序輸出數(shù)組元素*/}〔2〕讀10個整數(shù)存入數(shù)組中,輸出平均值。#include<stdio。h>#definesize10main(){intx[size],i;floats=0,ave;for(i=0;i<size;i++)scanf(“%d〞,&x[i]);for(i=0;i<size;i++)s+=x[i];ave=s/size;printf(“%d\n〞,ave);}二、二維數(shù)組1、二維數(shù)組的定義定義格式:類型說明符數(shù)組名[常量表達式1][常量表達式2]其中表達式1表示第一維下標(biāo)的長度;表達式2表示第二維下標(biāo)的長度;例如:inta[2][3];說明了一個2行3列的數(shù)組,數(shù)組名為a,數(shù)組元素的類型為整型,該數(shù)組共有2*3個元素;即:a[0][0],a[0][1],a[0][2],a[1][0],a[1][1],a[1][2]注意的是:二維數(shù)組在概念上是二維的,就是說其下標(biāo)在兩個方向上變化,數(shù)組元素在數(shù)組中的位置也處于一個平面中,并不向一維數(shù)組,所有的元素是線性的,但是,二維數(shù)組中的元素和一維數(shù)組中的元素一樣,也是按線性存儲的;如何存儲呢?首先,它和一維數(shù)組一樣,也是按線性存儲的。在C語言中,二維數(shù)組是按行排列的,即存完一行后,順序存入第二行;還是上面那個例子:inta[2][3];由于數(shù)組a說明為int型,所以數(shù)組的每個元素在內(nèi)存中占兩個字節(jié)的存儲空間,2、二維數(shù)組的引用引用形式:數(shù)組名[下標(biāo)][下標(biāo)]其中下標(biāo)應(yīng)該為整型常量或整型表達式;例如:inta[3][4];a[2][3]表示數(shù)組a的第三行第四列的元素。注意:下標(biāo)變量和數(shù)組說明在形式上有些相似,但這兩者具有完全不同的含義;數(shù)組說明的方括號中給出的是某一維的長度;而數(shù)組元素中的下標(biāo)是該元素在數(shù)組中的位置標(biāo)識;數(shù)組說明中的方括號內(nèi)只能是常量。而數(shù)組元素中方括號中的下標(biāo)可以是常量,變量或表達式。3、二維數(shù)組的初始化二維數(shù)組初始化也是在類型說明時給各下標(biāo)變量賦以初值。二維數(shù)組可以按行分段賦值,也可以按行連續(xù)賦值1〕按行分段賦值inta[2][3]={{1,2,3},{4,5,6}};2〕按行連續(xù)賦值inta[2][3]={1,2,3,4,5,6};這兩種賦值的結(jié)果是完全相同的;說明:1〕可以只對局部元素賦值,未賦值的元素自動取0;例如:inta[3][3]={{1},{2},{3}};是對每行的第一列元素賦值,未賦值的元素自動取02〕如果對所有的元素賦初值,那么第一維的長度可以不給出;例如:inta[3][3]={1,2,3,4,5,6,7,8,9};可以改為:inta[][3]={1,2,3,4,5,6,7,8,9};3〕數(shù)組是一種構(gòu)造類型的數(shù)據(jù),二維數(shù)組可以看作是一維數(shù)組的嵌套,設(shè)一維數(shù)組的每個元素又都是一個數(shù)組,就組成了一個二維數(shù)組,當(dāng)然,前提是每個元素的類型必須一致;同理,一個二維數(shù)組也可以分解為多個一維數(shù)組,例如:a[3][4],可分解為3個一維數(shù)組,其數(shù)組名分別是:a[0],a[1],a[2];對這三個一維數(shù)組不需另作說明即可使用,這三個一維數(shù)組都有4個元素,例如:一維數(shù)組a[0]的元素是a[0][0],a[0][1],a[0][2],a[0][3];必須強調(diào)的是,a[0],a[1],a[2]不能當(dāng)作下標(biāo)變量使用,因為它們是數(shù)組名,不是一個單純的下標(biāo)變量;對于一個數(shù)組,例如:a[3][4]可以通過循環(huán)語句來賦值;for(i=0;i<3;i++)for(j=0;j<4;j++)scanf(“%d〞,&a[i][j]);4、二維數(shù)組的使用舉例1〕將一個二維數(shù)組的行和列元素互換,存到另一個二維數(shù)組中。#include<stdio。h>main(){inta[2][3]={{1,2,3},{4,5,6}};intb[3][2],i,j;for(i=0;i<=1;i++){for(j=0;j<=2;j++){printf(“%d〞,a[i][j]);b[j][i]=a[i][j];}printf(“\n〞);}for(i=0;i<=2;i++){for(j=0;j<=1;j++)printf(“%d〞,b[i][j]);printf(“\n〞);}}三、字符型數(shù)組1、字符型數(shù)組的定義定義:每個數(shù)組元素的數(shù)據(jù)類型是字符型的一維數(shù)組。字符數(shù)組的引用,存儲,初始化的方法和一維數(shù)組相同例如:字符型數(shù)組的定義charc[10];定義了字符型數(shù)組c,它的數(shù)組元素有10個,由于字符型和整型是相通的,因此,上面的定義也可以改為:intc[10];例如:字符型數(shù)組的初始化charc[3]={‘a(chǎn)’,’b’,’c’};注意:如果花括號提供的數(shù)組元素個數(shù)大于數(shù)組長度,那么作語法錯誤處理;如果初值個數(shù)小于數(shù)組長度,那么只將這些字符賦給前面的元素,其余的元素自動定為空字符(‘\0’);比方:charc[5]={‘a(chǎn)’,’b’,’c’}abc\0\0如果提供的初值個數(shù)和預(yù)定的數(shù)組長度相同,在定義時可以省掉數(shù)組長度,系統(tǒng)自動根據(jù)初值個數(shù)確定數(shù)組長度。例如:chara[]={‘a(chǎn)’,’b’,’c’,’d’,’e’};也可以用字符串常量賦值;如:charch[6]={“hello〞};charch[6]=〞hello〞;charch[]=〞hello〞;hello\02、字符型數(shù)組的引用可以引用字符數(shù)組中的一個元素即得到一個字符!例如:輸出一個字符串Main(){chara[5]={‘a(chǎn)’,’b’,’c’,’d’,’e’};inti;for(i=0;i<5;i++)printf(“%c〞,a[i];)printf(“\n〞);}四、字符串1、字符串定義定義:C語言中用雙引號括起來的任意字符序列就是字符串。C語言中沒有字符串變量,對程序中的字符串,系統(tǒng)用字符數(shù)組方式保存,連續(xù),順序的存放每一個字符,最后加上一個空字符〞\0”2、字符串的輸入輸出1〕通過逐個字符輸入和輸出:使用%c;2〕通過整個字符串輸入和輸出:使用%s;3、字符串?dāng)?shù)組字符串?dāng)?shù)組就是數(shù)組中的每個元素又都是存放字符串的數(shù)組。例如:可以將一個二維字符數(shù)組看成是一個字符串?dāng)?shù)組;charline[10][80];數(shù)組line共有10個元素,每個元素可以存放80個字符(79個普通字符,一個結(jié)束字符),第一個下標(biāo)決定字符串的個數(shù),第二個下標(biāo)決定字符串的最大長度,line是有十個字符串的數(shù)組,這些字符串的最大長度是79。字符串的初始化方法:例如:charstr[3][5]={“a〞,〞ab〞,〞abc〞};/*根據(jù)定義的大小初始化*/charstr[][5]={“a〞,〞ab〞,〞abc〞};/*根據(jù)右邊字符串的個數(shù),定義數(shù)組大小*/該數(shù)組的存儲示意圖為:a\0ab\0abc\03.4軟件硬件的仿真調(diào)試1、首先利用ISIS-Professional軟件設(shè)計好硬件電路圖。2、其次,利用KEIL軟件建立工程工程,把用C語言編好的程序通過該軟件平臺進行編譯,直至把C程序修改無錯誤為止,并生成HEX文件。3、在ISIS-Professional軟件平臺下導(dǎo)入由KEIL軟件生成的HEX文件,進行仿真,仔細觀察產(chǎn)生的現(xiàn)象和效果,根據(jù)仿真的效果,邊修改邊調(diào)試,直到仿真效果與我們對工程的要求一致為止。本任務(wù)我們用單片機和時鐘芯片DS1302和液晶LCD1602設(shè)計了一個電子時鐘,通過仿真,本系統(tǒng)能夠準確的顯示秒、分、時、星期、年、月、日等時間,由于使用了專門的時鐘芯片和液晶顯示芯片,比前一個任務(wù)無論視覺效果更佳。3.5知識拓展-I/O接口擴展〔二〕一、I/O擴展常用芯片〔1〕TTL/CMOS鎖存器/緩沖器芯片:如74LS377、74LS374、74LS373、74LS273、74LS244、74LS245等;〔2〕通用可編程I/O接口芯片:如8255、8155、8729等;〔3〕可編程陣列:如GAL16V8、GAL20V8等。I/O擴展中應(yīng)注意的幾個問題〔1〕訪問擴展I/O的方法與訪問外部數(shù)據(jù)存儲器完全相同,使用相同的指令?!?〕擴展多片I/O芯片或多個I/O設(shè)備時,注意總線的驅(qū)動能力問題;〔3〕擴展I/O口的目的是為了單片機與外部設(shè)備進行信息交換而設(shè)置的一個輸入輸出通道,I/O口最終與外設(shè)相連?!?〕在軟件設(shè)計時,I/O口對應(yīng)初始狀態(tài)設(shè)置、工作方式選擇要與外接設(shè)備相匹配。二、擴展簡單并行接口1.擴展并行輸出口〔1〕用74LS377擴展并行輸出口74LS377是帶有輸出允許端的8D鎖存器,有8個輸入端口、8個輸出端口、1個時鐘輸入端CLK〔上升沿有效〕和1個允許控制端OE。如圖3-9所示,OE與P2.7相連,74LS377的地址為7FFFH;假設(shè)與P2.0相連,那么地址相應(yīng)為0EFFH。圖3-9MCS-51擴展輸出口74LS377【例3.1】假設(shè)以圖3-8為接口電路,將片內(nèi)RAM地址為50H單元的數(shù)據(jù)通過該電路輸出。程序清單如下:MOVDPTR,#7FFFH;數(shù)據(jù)指針指向74LS377MOVA,50H;輸出的50H單元數(shù)據(jù)送累加器AMOVX@DPTR,A;P0口將數(shù)據(jù)通過74LS377輸出〔2〕用74LS374擴展并行輸出口74LS374是具有三態(tài)輸出的8D邊沿觸發(fā)器,其功能與74LS377相似,74LS374與單片機接口電路如圖3-10所示,74LS374的地址為7FFFH。74LS374具有較強的驅(qū)動能力,輸出低電平電流IOL最大可達24mA,是74LS377的3倍。在有較強驅(qū)動能力要求場合,可選用74LS374作為并行口擴展器件。圖3-1074LS374與單片機接口電路2.擴展并行輸入口并行輸入擴展口比擬簡單,只需采用8位緩沖器即可。常用的緩沖器有74LS244,74LS244為單向總線緩沖器,只能一個方向傳輸數(shù)據(jù)。并行輸入接口與單片機連接如圖3-11所示。圖3-11擴展74LS244并行輸入口【例3.2】如圖3-10所示,擴展并行輸入口,將輸入口中的8位數(shù)據(jù)送片內(nèi)51H單元。程序清單如下:MOVDPTR,#7FFFH;數(shù)據(jù)指針指向74LS244MOVXA,@DPTR;外部數(shù)據(jù)經(jīng)過74LS244送入累加器AMOV51H,A;數(shù)據(jù)送51H單元保存將上述輸入輸出電路合并即如圖3-12所示。在圖3-12的輸入輸出接口電路中,輸入采用三態(tài)門74HC244,輸出采用8D觸發(fā)器〔鎖存器〕74HC374。P0口為雙向數(shù)據(jù)線,既能從74HC244輸入數(shù)據(jù),又能將數(shù)據(jù)通過74HC374輸出。輸出控制信號由P2.0和WR合成,當(dāng)兩者同時為低電平時,或門輸出0,將P0口數(shù)據(jù)鎖存到74HC374,其輸出控制著發(fā)光二極管LED。當(dāng)某線輸出為0時,該線上的LED發(fā)光。輸入控制信號由P2.0和RD合成,當(dāng)二者同時為低電平時,或門輸出為0,選通74HC244,將外部信息輸入到總線。與74HC244相連的按鍵開關(guān)沒有按下時,輸入全為1;假設(shè)按下某鍵那么所在的線輸入為0??梢姡斎胼敵龆际窃赑2.0為0時有效,因此它們的口地址為0FEFFH,即占用相同的地址空間。但是由于分別用RD和WR信號控制,因此不會發(fā)生沖突。圖3-12合并輸入輸出口正如前面所提到的,擴展I/O口和擴展外部RAM一樣,因此訪問外部I/O口就像訪問外部RAM一樣,用的是MOVX類指令。對于圖3-11,如果需要實現(xiàn)的功能是按下任意一個按鍵,對應(yīng)的LED發(fā)光,那么程序如下:LOOP:MOVDPTR,#0FEFFH;數(shù)據(jù)指針指向擴展I/O地址MOVXA,@DPTR;從74HC244讀入數(shù)據(jù),檢測按鍵MOVX@DPTR,A;向74HC374輸出數(shù)據(jù),驅(qū)動LEDSJMPLOOP;循環(huán)三、可編程并行I/O口的擴展1、RAM/IO擴展芯片8155Intel8155是一個具有RAM、I/O和計數(shù)器的通用可編程接口多功能芯片。其具有的資源為:256B的靜態(tài)RAM;兩個可編程的8位并行I/O口PA和PB;一個可編程的6位并行I/O口PC;一個可編程14位減計數(shù)器TC;8位地址鎖存器?!?〕8155的結(jié)構(gòu)及引腳功能8155的引腳如圖3-13〔a〕所示,邏輯框圖如圖3-13〔b〕所示。8155引腳符號的含義和功能如下:AD0~AD7:地址數(shù)據(jù)線;IO/M:IO/RAM選擇信號端,輸入高電平選擇I/O操作,低電平選擇訪問片內(nèi)RAM;CE:片選信號輸入端,低電平有效;RD:讀選通輸入端,低電平有效;WR:寫選通輸入端,低電平有效;TI:計數(shù)器計數(shù)脈沖輸入端;TO:計數(shù)器的輸出信號端,輸出波形由內(nèi)部定時工作方式?jīng)Q定;PA0~PA7:8位并行I/O口;PB0~PB7:8位并行I/O口;PC0~PC5:6位并行I/O口;ALE:地址鎖存信號輸入端,其下降沿時,鎖存AD0~AD7上的地址。RESET:復(fù)位輸入引腳,高電平復(fù)位。Vcc:電源+5V;Vss:接地。圖3-138155引腳及邏輯框圖〔2〕8155的RAM和I/O地址編碼8155的I/O端口及RAM地址在單片機應(yīng)用系統(tǒng)中與外部數(shù)據(jù)存儲器是統(tǒng)一編址的,其控制操作見表3-4,對應(yīng)I/O口存放器的地址編碼見表3-5。8155當(dāng)IO/M為0時,單片機對8155的RAM進行操作,共256B,低八位的地址為:00H—0FFH。8155當(dāng)IO/M為1時,單片機對8155的I/O口進行操作。表3-48155控制操作表低八位地址I/O口xxxxx000B命令/狀態(tài)口xxxxx001BPA口xxxxx010BPB口xxxxx011BPC口xxxxx100B定時器/計數(shù)器低字節(jié)存放器xxxxx101B定時器/計數(shù)器高字節(jié)存放器表3-5
8155的端口地址編碼AD7AD6AD5AD4AD3AD2AD1AD0對應(yīng)端口×××××000命令/狀態(tài)存放器×××××001A口×××××010B口×××××011C口×××××100定時器/計數(shù)器低8位×××××101定時器/計數(shù)器高8位〔3〕命令/狀態(tài)存放器8155的命令/狀態(tài)存放器物理上只有一個端口地址〔見表3-5〕。對該口寫操作,命令字被寫入命令存放器;對該口讀操作,那么從狀態(tài)存放器讀出狀態(tài)字。8155所提供的每個I/O口和定時器都是可編程的。I/O的工作方式選擇,定時器/計數(shù)器的工作控制都是通過對8155內(nèi)部命令存放器設(shè)定命令控制字的方式來實現(xiàn)的,通過對狀態(tài)字的讀取來判別它們的工作狀態(tài)。命令/狀態(tài)存放器共用一個口地址,通過讀/寫信號加以區(qū)分。命令字存放器只能寫不能讀,狀態(tài)存放器只能讀不能寫。8155命令字格式見表3-6;8155狀態(tài)字格式見表3-7。表3-68155命令字格式表TM1TM1TM2IEBIEAPC2PC1PAPAPBA口方式B口方式B口A口計數(shù)器方式00:空操作01:停止計數(shù)10:計滿后停止11:開始計數(shù)0:輸入1:輸出0:禁止中斷1:允許中斷00110110方式1:A、B口根本I/O;C口輸入方式2:A、B口根本I/O;C口輸出方式3:A口選通I/O;B口根本I/O方式4:A、B口選通I/O信號說明:INTRA、INTRB:中斷請求輸出線,高電平有效。STBA、STBB:設(shè)備選通信號輸入線,低電平有效。BFA、BFB:口緩沖器滿信號,高電平有效。表3-78155狀態(tài)字格式表〔4〕接口與編程①硬件連接。8155可以直接與MCS-51單片機連接,不需要任何外加邏輯。擴展一片8155系統(tǒng)將增加256B片外RAM,22位I/O口線及1個14位減法計數(shù)器。MCS-51與8155的連接方法如圖3-14所示。P0口不需要加鎖存器,可以直接與8155的AD0~AD7相連,它既是低8位地址線也是8位數(shù)據(jù)線。8155的鎖存信號ALE直接引自單片機ALE輸出,用以在內(nèi)部鎖存地址。圖3-14MCS-51與8155的一種接口邏輯CE及IO/M與MCS-51的連接方式?jīng)Q定了8155的地址范圍:RAM字節(jié)地址范圍:7E00H~7EFFH命令/狀態(tài)存放器:7F00HPA口:7F01HPB口:7F02HPC口:7F03H定時器低8位存放器:7F04H定時器高8位存放器:7F05H②程序設(shè)計。圖3-13接口電路中,將單片機片內(nèi)RAM50H~5FH單元的內(nèi)容送8155片內(nèi)的50H~5FH單元,設(shè)定8155的工作方式為:A口根本輸入方式,B口根本輸出方式,C口輸入方式,定時器作方波發(fā)生器,對輸入脈沖50分頻。程序清單如下:D8155:MOVR0,50H;將源數(shù)據(jù)單元首地址送存放器R0中MOVDPTR,#7E50H;數(shù)據(jù)指針指向8155內(nèi)部RAM單元LP:MOVA,@R0;數(shù)據(jù)送累加器AMOVX@DPTR,A;數(shù)據(jù)從累加器A送8155內(nèi)部RAM單元INCDPTR;指向下一個8155內(nèi)部RAM單元INCR0;指向下一個CPU內(nèi)部RAM單元CJNER0,#60H,LP;數(shù)據(jù)未傳送完繼續(xù)MOVDPTR,#7F04H;指向定時器低8位MOVA,#32H;分頻系數(shù)32H〔即50〕MOVX@DPTR,A;低8位初值裝入INCDPTR;指向定時器高8位MOVA,#40H;設(shè)定時器方式為連續(xù)方波(40H=01000000B)MOVX@DPTR,A;定時器/計數(shù)器方式及高6位初值裝入MOVDPTR,#7F00H;數(shù)據(jù)指針指向控制字存放器MOVA,#0C2H;設(shè)定A,B口方式,并啟動定時器〔0C2H=11000010B〕MOVX@DPTR,ARET;程序返回0C2H,其意義是:最高2位11的作用是啟動計數(shù)器,最低位D0=0設(shè)PA為輸入,D1=1設(shè)PB為輸出。D3D2=00設(shè)PA、PB為根本I/O,PC為輸入。完整程序代碼1、LCD1602.c源程序//---------------------LCD1602.c--------------------------//液晶控制與顯示驅(qū)動程序//--------------------------------------------------------#include<reg51.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedintsbitRS=P2^0; //LCD存放器選擇sbitRW=P2^1; //LCD讀寫控制sbitEN=P2^2; // LCD啟動//*--------延時子程序--------*//voidDelayMS(uintK){uchari;while(K--){ for(i=0;i<120;i++); }}//----------讀取LCD的狀態(tài)-------*/ucharRead_LCD_State(){ucharstate;RS=0;RW=1;EN=1;DelayMS(2);state=P0;EN=0;DelayMS(2);returnstate;}//-------------忙檢查--------------*/voidLCD_Busy_Wait(){while((Read_LCD_State()&0x80)==0x80); DelayMS(5);}//-----------寫LCD命令-----------------*/voidWrite_LCD_Command(ucharcmd){LCD_Busy_Wait();RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(2);EN=0;}//-----------向LCD寫入數(shù)據(jù)-----------------*/voidWrite_LCD_Data(uchardat){LCD_Busy_Wait();RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(2);EN=0;}//-----------LCD初始化-----------------*/voidInitialize_LCD1602()//液晶初始化函數(shù){Write_LCD_Command(0x38);DelayMS(2); //功能設(shè)置,數(shù)據(jù)長度為8位,雙行顯示,5×7點陣字體Write_LCD_Command(0x01);DelayMS(2); //清屏Write_LCD_Command(0x06);DelayMS(2);//字符進入模式:屏幕不動,字符后移Write_LCD_Command(0x0c);DelayMS(2); //顯示開,關(guān)光標(biāo)}//-----------設(shè)置液晶顯示位置-----------------*/voidSet_LCD_Position(ucharpos){Write_LCD_Command(pos|0x80); //設(shè)置7位的DDRAM地址值}//-----------在LCD上顯示字符串-----------------*/voidLCD_Display(ucharp,uchar*str){uchari;Set_LCD_Position(p);for(i=0;i<16;i++){ Write_LCD_Data(str[i]); DelayMS(2); }}2、main.c源程序//------------------------------------------------------------------------//名稱:用DS1302和1602液晶顯示的實時時鐘//-------------------------------------------------------------------------//說明:本程序運行時會以PC時間為默認時間開始運行,運行過程中可以通過K1按鍵選擇調(diào)節(jié)對象,用K2、K3//按鍵進行加減,用K4按鍵保存。//---------------------------------------------------------------------------------------#include<reg51.h>#include<string.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedintvoidInitialize_LCD1602();//液晶初始化函數(shù)voidLCD_Display(ucharp,uchar*str);sbitSDA=P1^0; //DS1302數(shù)據(jù)線sbitCLK=P1^1; //DS1302時鐘線sbitRST=P1^2; //DS1302 復(fù)位線sbitk1=P3^3; //選擇按鍵sbitk2=P3^4; //加sbitk3=P3^5; // 減sbitk4=P3^6; // 確定uchartcount=0; ucharMonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};//一年中每個月的天數(shù),二月的天數(shù)由年份決定uchar*Week[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};//周日,周一到周六//LCD顯示緩沖ucharLCD_DSY_BUFFER1[]={"DATE00-00-00"};ucharLCD_DSY_BUFFER2[]={"TIME00:00:00"};ucharDateTime[7];//所讀取的日期時間charAdjust_Index=-1;//當(dāng)前調(diào)節(jié)的時間對象:秒,分,時,日,月,年〔0,1,2,3,4,6〕ucharChange_Flag[]="-MHDM-Y";//(分,時,日,月,年)不調(diào)節(jié)秒和周//函數(shù)聲明voidWrite_Byte_TO_DS1302(ucharX);//向DS1302寫入一個字節(jié)ucharRead_Byte_FROM_DS1302(); //從DS1302中讀取一個字節(jié)ucharRead_Data_FROM_DS1302(ucharaddr);//從DS1302指定位置讀取數(shù)據(jù) ,讀數(shù)據(jù)voidWrite_Data_TO_DS1302(ucharaddr,uchardat);//向DS1302指定位置寫入數(shù)據(jù),寫數(shù)據(jù)voidSET_DS1302(); //設(shè)置時間voidGetTime(); //讀取當(dāng)前時間voidInitialization();//初始化函數(shù)//------------------------------------------//主程序//----------------------------------------voidmain(){Initialization();while(1){ if(Adjust_Index==-1) GetTime(); }}//*-----------------初始化函數(shù)--------------*//voidInitialization(){Initialize_LCD1602();//調(diào)用液晶初始化函數(shù)IE=0x83; //允許中斷外部0中斷和T0中斷IP=0x01; // 設(shè)置中斷優(yōu)先級IT0=0x01; // 設(shè)置外部中斷的脈沖觸發(fā)方式TMOD=0x01;//設(shè)置定時器的工作方式,為方式1TH0=-50000/256;//寫入初值TL0=-50000%256;//寫入初值TR0=1;// 啟動定時器}//*--------寫字節(jié)函數(shù),向DS1302寫入一個字節(jié)--------*//voidWrite_Byte_TO_DS1302(ucharX)//向DS1302寫入一個字節(jié){uchari; for(i=0;i<8;i++) { SDA=X&1; CLK=1; CLK=0; X>>=1; }}//*--------讀字節(jié)函數(shù),從DS1302讀取一個字節(jié)--------*//ucharRead_Byte_FROM_DS1302() //從DS1302中讀取一個字節(jié){uchari,byte,t;for(i=0;i<8;i++){ byte>>=1; t=SDA; byte|=t<<7;CLK=1; CLK=0; } //BCD碼轉(zhuǎn)換 returnbyte/16*10+byte%16;}//-------------------------------------------------------------//從DS1302指定位置讀取數(shù)據(jù) ,讀數(shù)據(jù)//---------------------------------------------------------------ucharRead_Data_FROM_DS1302(ucharaddr)//從DS1302指定位置讀取數(shù)據(jù) ,讀數(shù)據(jù){uchardat; RST=0; CLK=0; RST=1; Write_Byte_TO_DS1302(addr);//向DS1302寫入一個地址 dat=Read_Byte_FROM_DS1302();//在上面寫入的地址中讀取數(shù)據(jù) CLK=1; RST=0; returndat;}//-------------------------------------------------------------//向DS1302指定位置寫入數(shù)據(jù),寫數(shù)據(jù)//---------------------------------------------------------------voidWrite_Data_TO_DS1302(ucharaddr,uchardat)//向DS1302指定位置寫入數(shù)據(jù),寫數(shù)據(jù){CLK=0; RST=1; Write_Byte_TO_DS1302(addr); Write_Byte_TO_DS1302(dat); CLK=1; RST=0;}//-----------------------------------------------------------//設(shè)置時間//---------------------------------------------------------voidSET_DS1302() //設(shè)置時間{uchari;Write_Data_TO_DS1302(0x8E,0x00);//寫控制字,取消寫保護//分,時,日,月,年依次寫入for(i=1;i<7;i++){ //分的起始地址是10000010(0x82),后面依次是時,日,月,周,年,寫入地址每次遞增2 Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10)); }Write_Data_TO_DS1302(0x8E,0x80);//寫控制字,加寫保護}//--------------------------------------------------------//讀取當(dāng)前時間//-------------------------------------------------------voidGetTime() //讀取當(dāng)前時間{uchari;for(i=0;i<7;i++){ DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i); }}//------------------------------------------------------------//日期與時間值轉(zhuǎn)換為數(shù)字字符//-------------------------------------------------------------voidFormat_DateTime(uchard,uchar*a){ a[0]=d/10+'0'; a[1]=d%10+'0';}//-------------------------------------------------------------------//判斷是否為閏年//-------------------------------------------------------------------ucharIs_Leapyear(uintyear){return(year%4==0&&year%100!=0)||(year%400==0);}//------------------------------------------------------------------// 求自2000.1.1開始的任何一天是星期幾?//----------------------------------------------------------------------voidRefresh_Week_Day(){uinti,d,w=5;//1999年12.31是星期五for(i=2000;i<2000+DateTime[6];i++){ d=Is_Leapyear(i)?366:365; w=(w+d)%7; }d=0;for(i=1;i<DateTime[4];i++){d+=MonthsDays[i];}d+=DateTime[3];//保存星期,0-6表示星期日,星期一至星期六,為了與DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1;}//-------------------------------------------------//年,月,日和時,分++/--//----------------------------------------------------voidDatetime_Adjust(charX){switch(Adjust_Index){ case6: //年調(diào)整,00-99 if(X==1&&DateTime[6]<99) { DateTime[6]++; } if(X==-1&&DateTime[6]>0) { DateTime[6]--; } //獲取2月天數(shù) MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28; //如果年份變化后當(dāng)前月份的天數(shù)大于上限那么設(shè)為上限 if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]]; } Refresh_Week_Day();//刷新星期 break; case4://月調(diào)整01-12 if(X==1&&DateTime[4]<12) { DateTime[4]++; } if(X==-1&&DateTime[4]>1) { DateTime[4]--; } //獲取2月天數(shù) MonthsDays[2]=Is_Leapyear(2000+DateTim
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國鋁顏料行業(yè)運行現(xiàn)狀及發(fā)展趨勢預(yù)測報告
- 2025-2030年中國鋁冶煉市場競爭格局及前景趨勢預(yù)測報告
- 2025-2030年中國鎢行業(yè)未來投資預(yù)測發(fā)展戰(zhàn)略規(guī)劃分析報告
- 2025四川省建筑安全員《C證》考試題庫
- 2025-2030年中國過氧化鋅市場運營動態(tài)及發(fā)展前景分析報告
- 2025-2030年中國車蠟行業(yè)市場運行態(tài)勢及發(fā)展盈利分析報告
- 2025-2030年中國調(diào)味香料市場發(fā)展前景及投資戰(zhàn)略研究報告
- 2025-2030年中國船舶制造行業(yè)發(fā)展?fàn)顩r及營銷戰(zhàn)略研究報告
- 2025-2030年中國紙基覆銅板市場十三五規(guī)劃及投資風(fēng)險評估報告
- 突發(fā)事件應(yīng)急預(yù)案管理辦法培訓(xùn)課件
- 國家電投《新能源電站單位千瓦造價標(biāo)準值(2024)》
- 糧食儲備庫內(nèi)圓筒鋼板倉及附房工程施工組織設(shè)計
- 原發(fā)性肺癌臨床路徑
- 學(xué)校科技節(jié)活動方案
- 校園食品安全和膳食經(jīng)費管理方案3篇
- TSGD7002-2023-壓力管道元件型式試驗規(guī)則
- 九年級化學(xué)下冊 第12單元 化學(xué)與生活教案 (新版)新人教版
- 金融服務(wù)消費糾紛調(diào)解工作規(guī)范
- 后腹腔鏡下輸尿管切開取石術(shù)
- 二手車購買收據(jù)合同范本
評論
0/150
提交評論