版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1第14章單片機C語言
程序設計基礎1捶丘撲存搖繪瑪滅眷漆家隴聯(lián)劫莎匙瑣藹材擯草擾癬甭濾處磁嗚臥撈聰熾單片機第14章C語言程序設計單片機第14章C語言程序設計22
第14章目錄14.1編程語言KeilC51簡介
14.1.1KeilC51簡介
14.1.2KeilC51的開發(fā)環(huán)境
14.1.3C51與標準C的主要區(qū)別14.2C51語言程序設計基礎
14.2.1C51語言中的數(shù)據(jù)
14.2.2C51的位變量定義
14.2.3一個簡單的C51程序
14.2.4C51的運算符
14.2.5C51的分支與循環(huán)程序結(jié)構(gòu)浙痹文吸憲冗淵溉昌黨雹陸等揭終兄契盧窒遷誰晃為梳浸凱覺述規(guī)覽備暗單片機第14章C語言程序設計單片機第14章C語言程序設計3
14.2.6AT89S51不同存儲區(qū)的C51定義
14.2.7C51中斷服務函數(shù)的定義14.3C51的程序設計舉例
14.3.1中斷程序的編寫
14.3.2定時器程序的編寫
14.3.3串行口方式0應用程序的編寫
14.3.4獨立式鍵盤查詢方式
14.3.5行列式鍵盤查詢方式
14.3.6DAC0832應用程序的編寫
望轉(zhuǎn)嚼碧撲耐毗司倚傭基佛鞘黎摘論察池獅暈雙乎償字享朽驅(qū)嶺萎捏棧乃單片機第14章C語言程序設計單片機第14章C語言程序設計4
14.3.7ADC0809應用程序的編寫14.4C51的集成開發(fā)環(huán)境KeilμVision3介紹
14.4.1集成開發(fā)環(huán)境KeilμVision3簡介
14.4.2KeilμVision3軟件的安裝、啟動和運行
14.4.3C51程序的開發(fā)流程14.5C51與匯編語言的混合編程
14.5.1C51與MCS-51匯編語言的比較
14.5.2C51與匯編語言混合編程的方法尊梨營砷喬虐始臥馬汁魂報窘幸扦魄窮猿煞酸釘巢梁低窺闊寂洞依舉滑氛單片機第14章C語言程序設計單片機第14章C語言程序設計5內(nèi)容概要 本章在假定讀者已掌握標準C語言前提下,初步介紹如何使用C51來編寫AT89C51單片機的應用程序。
C51是在標準C的基礎上,根據(jù)單片機存儲器硬件結(jié)構(gòu)及內(nèi)部資源,擴展了相應的數(shù)據(jù)類型和變量,而C51在語法規(guī)定、程序結(jié)構(gòu)與設計方法上,都與標準C相同。 本章重點介紹C51對標準C所擴展的部分,并通過一些例程來介紹C51的程序設計思想。最后還對C51的集成開發(fā)環(huán)境KeilμVision3以及C51與匯編語言的混合編程作以介紹。僑桐貼赴茄娜訃郊爬躥通迅證彎竹臥蓮幀駭無垂棚呸販繡窮矩囊俏催廢稿單片機第14章C語言程序設計單片機第14章C語言程序設計614.1編程語言KeilC51簡介 目前51系列單片機編程的C語言都采用KeilC51(簡稱C51),KeilC51是在標準C語言基礎上發(fā)展起來的。14.1.1KeilC51簡介
C語言是美國國家標準協(xié)會(ANSI)制定的編程語言標準,1987年ANSI公布87ANSIC,即標準C語言。KeilC51語言是在ANSIC的基礎上針對51單片機的硬件特點進行的擴展,并向51單片機上移植,經(jīng)過多年努力,C51語言已經(jīng)成為公認的高效、簡潔而又貼近51單片機硬件的實用高級編程語言。6嘯儲掃倫喀孽忘扭屋俘奪皋乖傭掣鄙撣輸綜補彭圖塊逗該瞧玻碑閹熄傅鉚單片機第14章C語言程序設計單片機第14章C語言程序設計7
目前大多數(shù)的51單片機用戶都在使用C51語言來進行程序設計。 用C51進行單片機軟件開發(fā),有如下優(yōu)點:(1)可讀性好。C51語言程序比匯編語言程序的可讀性好,因而編程效率高,程序便于修改。(2)模塊化開發(fā)與資源共享。用C51開發(fā)出來的程序模塊可以不經(jīng)修改,直接被其他項目所用,這使得開發(fā)者能夠很好地利用已有的大量的標準C程序資源與豐富的庫函數(shù),減少重復勞動。7皚蕪柬暴區(qū)諒猙禾摳變瘦精幣釉引部稼壕靶峙較協(xié)輕鉻房速烽旅剔申韻官單片機第14章C語言程序設計單片機第14章C語言程序設計8(3)可移植性好。為某種型號單片機開發(fā)的C語言程序,只需將與硬件相關之處和編譯連接的參數(shù)進行適當修改,就可以方便地移植到其他型號的單片機上。例如,為51單片機編寫的程序通過改寫頭文件以及少量的程序行,就可以方便地移植到PIC單片機上。(4)代碼效率高。當前較好的C51語言編譯系統(tǒng)編譯出來的代碼效率只比直接使用匯編語言低20%左右,如果使用優(yōu)化編譯選項,效果會更好。8熒笨墅麥紹堪迅睦肌駒凰翟吊攘也嘛捍雇鼠溝翼終拷潘到瞞瘁忌姿瘋精疤單片機第14章C語言程序設計單片機第14章C語言程序設計914.1.2KeilC51的開發(fā)環(huán)境
KeilC51是德國Keilsoftware公司開發(fā)的用于51系列單片機的C51語言開發(fā)軟件。KeilC51在兼容ANSIC的基礎上,又增加很多與51單片機硬件相關的編譯特性,使得開發(fā)51系列單片機程序更為方便和快捷,程序代碼運行速度快,所需存儲器空間小,完全可以和匯編語言相媲美。它支持眾多的MCS-51架構(gòu)的芯片,同時集編輯、編譯、仿真等功能于一體,具有強大的軟件調(diào)試功能,是眾多的單片機應用開發(fā)軟件中最優(yōu)秀的軟件之一。9噸盂抓聳委送彌鳳警剛陶特皂帽送溢行寬麗簍散迭幫杖濟砍允唾揖癱葡渭單片機第14章C語言程序設計單片機第14章C語言程序設計10 Keil公司目前已推出V7.0以上版本的C51編譯器,為51單片機軟件開發(fā)提供了全新的C語言環(huán)境,同時保留了匯編代碼高效、快速的特點。 現(xiàn)在,KeilC51已被完全集成到一個功能強大的全新集成開發(fā)環(huán)境(IDE)μVision3中,該環(huán)境下集成了文件編輯處理、編譯鏈接、項目(Project)管理、窗口、工具引用和仿真軟件模擬器以及Monitor51硬件目標調(diào)試器等多種功能,這些功能均可在KeilμVision3環(huán)境中極為簡便地進行操作。10圾數(shù)睹撈爽這梨千應涌侈衙戊知坊沫吼獅耳郭猙年膜番洼恍仁杠辰改攬呵單片機第14章C語言程序設計單片機第14章C語言程序設計11
本章經(jīng)常用到KeilC51和KeilμVision3兩個術(shù)語。KeilC51一般簡寫為C51,指的是51單片機編程所用的C語言;而KeilμVision3,可簡寫為μVision3,指的是用于51單片機的C51程序編寫、調(diào)試的集成開發(fā)環(huán)境。
μVision3內(nèi)部集成了源程序編輯器,并允許用戶在編輯源文件時就可設置程序調(diào)試斷點,便于在程序調(diào)試過程中快速檢查和修改程序。此外,μVision3還支持軟件模擬仿真(Simulator)和用戶目標板調(diào)試(Monitor51)兩種工作方式。在軟件模擬仿真方式下不需任何51單片機及其外圍硬件即可完成用戶程序仿真調(diào)試。11褥林殘憎軒刊錠義蕊駒住捻嗓最腕內(nèi)濕躲芹駁湍肅缽謾料巫皺磊卉柵膜幅單片機第14章C語言程序設計單片機第14章C語言程序設計12
在用戶目標板調(diào)試方式下,利用硬件目標板中的監(jiān)控程序可以直接調(diào)試目標硬件系統(tǒng),使用戶節(jié)省購買硬件仿真器的費用。14.1.3C51與標準C的主要區(qū)別 不同的嵌入式處理器的C編譯系統(tǒng)與標準C的不同之處,主要是它們所針對的嵌入式處理器的硬件系統(tǒng)不同。KeilC51的基本語法與標準C相同,但對標準C進行了擴展。 深入理解KeilC51對標準C的擴展部分是掌握KeilC51的關鍵之一。12黎氓援疊席洶鹼沃毗練代束試歷刷蹄風杭巧唇鵑響皂凰用醚鰓煙湊柯癱奸單片機第14章C語言程序設計單片機第14章C語言程序設計13C51與標準C的主要區(qū)別如下:(1)頭文件的差異。51系列單片機廠家有多個,它們的差異在于內(nèi)部資源如定時器、中斷、I/O等數(shù)量以及功能的不同,而對使用者來說,只需要將相應的功能寄存器的頭文件加載在程序內(nèi),就可實現(xiàn)所具有的功能。因此,KeilC51系列的頭文件集中體現(xiàn)了各系列芯片的不同資源及功能。(2)數(shù)據(jù)類型的不同。51系列單片機包含位操作空間和豐富的位操作指令,因此KeilC51與ANSIC相比又擴展了4種類型,以便能夠靈活地進行操作。13聯(lián)林撬撰蠅恿惡榜狐簿懦扯噪發(fā)茬遣攏絹垮疑棵晌誠幾蒲崇逮茍撞贖狐箔單片機第14章C語言程序設計單片機第14章C語言程序設計14(3)數(shù)據(jù)存儲類型的不同。C語言最初是為通用計算機設計的,在通用計算機中只有一個程序和數(shù)據(jù)統(tǒng)一尋址的內(nèi)存空間,而51系列單片機有片內(nèi)、外程序存儲器,還有片內(nèi)、外數(shù)據(jù)存儲器。標準C并沒有提供這部分存儲器的地址范圍的定義。此外,對于AT89C51單片機中大量的特殊功能寄存器也沒有定義。(4)標準C語言沒有處理單片機中斷的定義。(5)KeilC51與標準C的庫函數(shù)有較大的不同。由于標準C的中的部分庫函數(shù)不適于嵌入式處理器系統(tǒng),因此被排除在KeilC51之外,如字符屏幕和圖形函數(shù)。14柒迎貌亂齒瞻期度鳴掠暑懲檄巡暢肚枷張缺文敝仕缽誓倍瘓難緬繞攪凈痢單片機第14章C語言程序設計單片機第14章C語言程序設計15
有一些庫函數(shù)可以繼續(xù)使用,但這些庫函數(shù)都必須針對51單片機的硬件特點來作出相應的開發(fā),與標準C庫函數(shù)的構(gòu)成與用法有很大的不同。例如庫函數(shù)printf和scanf,在標準C中,這兩個函數(shù)通常用于屏幕打印和接收字符,而在KeilC51中,它們主要用于串行口數(shù)據(jù)的收發(fā)。(6)程序結(jié)構(gòu)的差異。由于51單片機的硬件資源有限,它的編譯系統(tǒng)不允許太多的程序嵌套。其次,標準C所具備的遞歸特性不被KeilC51支持,在C51中,要使用遞歸特性,必須用reentrant進行聲明才能使用。15靡咬碎芯琺貓鈍冷濾叼橡與按未亞拌締忠綱撕籠瞪捌掐棕遇地篙搔蔽漬藐單片機第14章C語言程序設計單片機第14章C語言程序設計16
但是從數(shù)據(jù)運算操作、程序控制語句以及函數(shù)的使用上來說,KeilC51與標準C幾乎沒有什么明顯的差別。如果程序設計者具備了有關標準C的編程基礎,只要注意KeilC51與標準C的不同之處,并熟悉AT89S51單片機的硬件結(jié)構(gòu),就能夠較快地掌握KeilC51的編程。16叉中屬捏悟理燙誣申鉤奴扔量盈頻伙昧凈力姜礎逗鍍氈蝗訓凈胡慈部桌加單片機第14章C語言程序設計單片機第14章C語言程序設計1714.2C51語言程序設計基礎 本節(jié)介紹C51語言程序設計的有關基礎知識。14.2.1C51語言中的數(shù)據(jù)1.數(shù)據(jù)類型
KeilC51的基本數(shù)據(jù)類型如表14-1所示。針對AT89S51單片機的硬件特點,C51在標準C的基礎上,擴展了4種數(shù)據(jù)類型(見表中最后4行)。 注意:擴展的4種數(shù)據(jù)類型,不能使用指針對它們存取。17秦濟次紛連騁至兢夸噎睛碌城叮注撮僳素持岔購戲稿祖玻蘸貌隊穿燴集巧單片機第14章C語言程序設計單片機第14章C語言程序設計18
表14-1
KeilC51支持的數(shù)據(jù)類型18數(shù)據(jù)類型signedcharunsignedcharsignedintunsignedintsignedlongunsignedlongfloatdouble*bitsfrsfr16sbit位數(shù)881616323232642418161字節(jié)數(shù)112244481~312取值范圍-128~+127,有符號字符變量0~255,無符號字符變量-32768~+32767,有符號整型數(shù)0~65535,無符號整型數(shù)-2147483648~+2147483647,有符號長整型數(shù)0~+4294967295,無符號長整型數(shù)±3.402823E+38,浮點數(shù)(精確到7位)±1.175494E-308,浮點數(shù)(精確到15位)對象指針0或10~2550~65535可進行位尋址的特殊功能寄存器的某位的絕對地址熬蚜書諸勝元歡奧瑯蛀籌晃廉漫幻魔寺隔愚椿搏人戶呼櫥擊奮講甭友畸偶單片機第14章C語言程序設計單片機第14章C語言程序設計192.C51的擴展數(shù)據(jù)類型 下面對表14-1中擴展的4種數(shù)據(jù)類型進行說明。(1)位變量bit bit的值可以是1(true),也可以是0(false)。(2)特殊功能寄存器sfr AT89S51特殊功能寄存器在片內(nèi)RAM區(qū)的80H~FFH之間,“sfr”數(shù)據(jù)類型占用一個內(nèi)存單元。利用它可訪問AT89S51內(nèi)部的所有特殊功能寄存器。 例如:sfrP1=0x90這一語句定義P1口在片內(nèi)的寄存器,在后面語句中可用“P1=0xff”(使P1的所有引腳輸出19棚勵艾描會欲割改幼閱滄鷹挨已嗚撰強運煽欲烈上湍壯兌蠕卑跟漳渣蝴搬單片機第14章C語言程序設計單片機第14章C語言程序設計20為高電平)之類的語句來操作特殊功能寄存器。(3)特殊功能寄存器sfr16“sfr16”數(shù)據(jù)類型占用兩個內(nèi)存單元。sfr16和sfr一樣用于操作特殊功能寄存器。所不同的是它用于操作占兩個字節(jié)的特殊功能寄存器。例如:
sfr16DPTR=0x82語句定義了片內(nèi)16位數(shù)據(jù)指針寄存器DPTR,其低8位字節(jié)地址為82H。在后面的語句中可以對DPTR進行操作。20涕眶澡橢塌沼張價廁徑止睬貸暮厲掏披消磚計膝豹灌罷布在情淌聽矽禾蛾單片機第14章C語言程序設計單片機第14章C語言程序設計21(4)特殊功能位
sbit sbit
是指AT89S51片內(nèi)特殊功能寄存器的可尋址位。 例如:
sfrPSW=0xd0 ;/*定義PSW寄存器地址為0xd0*/ sbitPSW^2=0xd2 ;/*定義OV位為PSW.2*/
符號“^”前面是特殊功能寄存器的名字,“^”的后面數(shù)字定義特殊功能寄存器可尋址位在寄存器中的位置,取值必須是0~7。 注意,不要把bit與sbit混淆。bit用來定義普通的位變量,值只能是二進制的0或1。而sbit定義的是特殊功能21固胞橇甥鈞流果飛怔藩磚予郝骸悸道癰詣師皺豎很誡告?zhèn)b敖駭襲槍譚恥繩單片機第14章C語言程序設計單片機第14章C語言程序設計22寄存器的可尋址位,其值是可進行位尋址的特殊功能寄存器的位絕對地址,例如PSW寄存器OV位的絕對地址0xd2。3.數(shù)據(jù)的存儲類型
C51完全支持51單片機硬件系統(tǒng)的所有部分。在51單片機中,程序存儲器與數(shù)據(jù)存儲器是完全分開的,且分為片內(nèi)和片外兩個獨立的尋址空間,特殊功能寄存器與片內(nèi)RAM統(tǒng)一編址,數(shù)據(jù)存儲器與I/O端口統(tǒng)一編址。C51編譯器通過將變量、常量定義成不同存儲類型的方法將它們定義在不同的存儲區(qū)中。22歇餅慈誤資瀝迅撂堆庚撅岔裸非姐桑脊卸偷擅片繭孺祭迅癡擂升倍鈉姑嘔單片機第14章C語言程序設計單片機第14章C語言程序設計23 C51存儲類型與AT89S51的實際存儲空間的對應關系見表14-2。下面對表14-2作以說明。(1)片內(nèi)數(shù)據(jù)存儲器 片內(nèi)RAM可分為3個區(qū)域:data:片內(nèi)直接尋址區(qū),位于片內(nèi)RAM的低128字節(jié)。bdata:片內(nèi)位尋址區(qū),位于片內(nèi)RAM位尋址區(qū)20H~2FH。idata:片內(nèi)間接尋址區(qū),片內(nèi)RAM所有地址單元(00H~FFH)。蝕嘆住禱傲蠕褥淚鉚手月契隕攪舔鏡轄笆牧萬煮溉隧婚圓祥荊敖身樂穗漂單片機第14章C語言程序設計單片機第14章C語言程序設計2424腥套鏈貼羽藍嘔峰鯉簽醛絨阮費碩黨牽撞板盂暖手骨絡標啄纖叔效舟按慣單片機第14章C語言程序設計單片機第14章C語言程序設計25(2)片外數(shù)據(jù)存儲器
pdata:片外數(shù)據(jù)存儲器頁,一頁為256字節(jié)。
xdata:片外數(shù)據(jù)存儲器RAM的64KB空間。(3)片外程序存儲器
code:外部程序存儲器的64KB空間。對單片機編程,正確地定義數(shù)據(jù)類型以及存儲類型,是所有編程者在編程前都需要首先考慮的問題。在資源有限的條件下,如何節(jié)省存儲單元并保證運行效率,是對開發(fā)者的一個考驗。只有對C51中的各種數(shù)據(jù)類型以及存儲類型非常熟練的掌握,才能運用自如。25痰尚箕銻助仆坤來臼脈瑰拉靖窺瞎瓤浴癬晰樓部溜硬奸涉褐涂窿醒丹乳逾單片機第14章C語言程序設計單片機第14章C語言程序設計26
定義變量類型應考慮如下問題:程序運行時該變量可能的取值范圍,是否有負值,絕對值有多大,以及相應需要的存儲空間大小。在夠用的情況下,盡量選擇8位即一個字節(jié)的char型,特別是unsigedchar。對于51系列這樣的定點機而言,浮點類型變量將明顯增加運算時間和程序長度,如果可以的話,盡量使用靈活巧妙的算法來避免浮點變量的引入。 定義數(shù)據(jù)的存儲類型通常遵循如下原則:只要條件滿足,盡量選擇內(nèi)部直接尋址的存儲類型data,然后選擇idata即內(nèi)部間接尋址。對于那些經(jīng)常使用的變量要使用內(nèi)26椒迫菲燎灼氧恢貢折護哎親豈父腥兩伶棉甚歉火墻迷朔胡除埋思牲依煩侵單片機第14章C語言程序設計單片機第14章C語言程序設計27部尋址。在內(nèi)部數(shù)據(jù)存儲器數(shù)量有限或不能滿足要求的情況下才使用外部數(shù)據(jù)存儲器。選擇外部數(shù)據(jù)存儲器可先選擇pdata類型,最后選用xdata類型。 需指出,擴展片外存儲器,原理上雖很簡單,但在實際開發(fā)中,很多時候,會帶來不必要的麻煩,如可能降低系統(tǒng)穩(wěn)定性、增加成本、拉長開發(fā)和調(diào)試周期等,推薦充分利用片內(nèi)存儲空間。 另外,通常的單片機應用都是面對小型的控制,代碼比較短,對于程序存儲區(qū)的大小要求很低,常常是片內(nèi)RAM很緊張而片內(nèi)FlashROM很富裕,因此如果實時性27籽略匙鈕飽桶祿嘗耳最繼閻渤稗備勃孩靳帛奪昆杖匆衙羽斗鎬貉條敏啟半單片機第14章C語言程序設計單片機第14章C語言程序設計28要求不高,可考慮使用宏,以及將一些子函數(shù)的常量數(shù)據(jù)做成數(shù)據(jù)表,放置在程序存儲區(qū),當程序運行時,進入子函數(shù)動態(tài)調(diào)用下載至RAM即可,退出子函數(shù)后立即釋放該內(nèi)存空間。28拜運織鍘霞鹿那掠巨尾躊右霧拱駛囪悲勞饒厘園柳糊諄龍鑷搭壇湍水臻窖單片機第14章C語言程序設計單片機第14章C語言程序設計2914.2.2C51的位變量定義 由于AT89C51能夠進行位操作,C51擴展了“bit”數(shù)據(jù)類型用來定義位變量,這是C51與標準C的不同之處。C51中位變量bit的具體定義如下:1.位變量的C51定義方法
C51通過關鍵字“bit”來定義位變量,格式為:
bitbit-name
; 例如:bitov-flag ;/*將ov-flag定義為位變量*/29耳鼓坐札攻禍鈞宏緒蹄緯康煉投斯犀續(xù)謂烏紀幣帥澎殃傣肌草吸啤臻衡積單片機第14章C語言程序設計單片機第14章C語言程序設計302.C51程序函數(shù)的“bit”參數(shù)及返回值
C51程序函數(shù)可以包含類型為“bit”的參數(shù),也可將其作為返回值。例如:bitfunc(bitb0,bitb1);
/*位變量b0,b1作為函數(shù)func的參數(shù)*/{
……return(b1);
/*位變量b1作為函數(shù)的返回值*/}30喊橙耕按雀碩目塑巋搓針脖逢午擻咐光忻糖錢熒快忠露冀烤蒲蓖櫥谷腹?jié)鈫纹瑱C第14章C語言程序設計單片機第14章C語言程序設計313.位變量的限制 位變量不能用來定義指針和數(shù)組。例如:
bit*ptr
;/*錯誤,不能用位變量來定義指針*/ bita-array[] ;/*錯誤,不能用位變量來定義數(shù)組*/
在定義位變量時,允許定義存儲類型,位變量都被放入一個位段,此段總是位于AT89S51片內(nèi)RAM中,因此其存儲器類型限制為bdata,data或idata,如果將位變量定義成其他類型都會在編譯時出錯。31崩組目拯軍宇抗皋窖撩餓武世魂動哲墻羨泡烴廄肇紗詫特斥尋宅蘋侗悲寫單片機第14章C語言程序設計單片機第14章C語言程序設計3214.2.3一個簡單的C51程序 一個C51源程序是由一個個模塊化的函數(shù)所構(gòu)成,函數(shù)是指程序中的一個模塊,main()函數(shù)為程序的主函數(shù),其他若干個函數(shù)可以理解為一些子程序。 一個C51源程序無論包含了多少函數(shù),它總是從main()函數(shù)開始執(zhí)行,不論main()函數(shù)位于程序的什么位置。程序設計者就是編寫一系列的函數(shù)模塊,并在需要的時候調(diào)用這個函數(shù),實現(xiàn)程序所要求的功能。32備供秘滇猩足直乘菏滄卜腥窟備糜值清拍鑄漿慮優(yōu)恫鍍楓再扯俄令填朋坊單片機第14章C語言程序設計單片機第14章C語言程序設計331.C51程序與函數(shù) 下面通過一個簡單C51程序,認識C51程序與函數(shù)?!纠?4-1】
在AT89S51的P1.0腳接有一只發(fā)光二極管,二極管的陰極接P1.0腳,陽極通過限流電阻接+5V,現(xiàn)在讓發(fā)光二極管每隔800ms閃滅,占空比為50%。已知單片機時鐘晶振為12MHz,即每個機器周期1μs,采用軟件延時的方法,參考程序如下:33瞄刀攝眉鋤摧廄翰霓碴嚷得擎?zhèn)u親崗耘擯撾港卯蔥隴埔剪星尸申屬俠敝單片機第14章C語言程序設計單片機第14章C語言程序設計34#include<reg51.h> /*包含reg51.h頭文件*/sbitP10=P1^0;
/*定義位變量P1.0,也可使用sbitP10=0x90*/voidDelay(unsignedinti) /*延時函數(shù)Delay(),i是形式參數(shù)
*/{ /*兩個花括號之間為函數(shù)Delay()的函數(shù)體*/unsignedintj;
/*定義變量j*/} for(;i>0;i--) /*如果i>0,則i減1*/ { for(j=0;j<333;j++)/*如果j<333,則j加1*/ {
;
/*空函數(shù)*/ }}}34居羚抿敦幼掐隱駭霍擎羔戊針透后挑趨沃熾陪懼胺堰狠淖若渭踞污香歹件單片機第14章C語言程序設計單片機第14章C語言程序設計35voidmain(void) /*主函數(shù)main()*/{while(1)
/*主程序輪詢*/{ P10=1;
/*P1.0輸出高電平,發(fā)光二極管滅*/Delay(800);
/*將實際參數(shù)800傳遞給形式參數(shù)i, 延時800ms*/ P10=0;
/*P1.0輸出低電平,發(fā)光二極管亮*/ Delay(800)/*將實際參數(shù)800傳遞給形式參數(shù)i,延時800ms*/ }}35亦盔光子倔疚室旨弄外侯稻譬纖燥翹愧堪豪李釬朋澤案市貳鈍庭農(nóng)經(jīng)雜裳單片機第14章C語言程序設計單片機第14章C語言程序設計36
下面對程序進行簡要說明。 程序的第1行是“文件包含”,是將另一個文件“reg51.h”的內(nèi)容全部包含進來。文件“reg51.h”包含了51單片機全部的特殊功能寄存器的字節(jié)地址及可尋址位的位地址定義。 程序包含reg51.h的目的就是為了使用P1這個符號,即通知程序中所寫的P1是指AT89S51的P1端口,而不是其他變量。36貨侈奠背瑣吹桓庫吃锨首魂煥缺只預竣洽下瘩命焦囊渭銻猜頭意冉寬否蠱單片機第14章C語言程序設計單片機第14章C語言程序設計37
打開reg51.h文件可以看到“sfrP1=0x90;”,即定義符號P1與地址0x90對應,而P1口的地址就是0x90。雖然這里的“文件包含”只有一行,但C編譯器在處理的時候卻要處理幾十行或幾百行。
程序的第2行用符號P10來表示P1.0引腳。在C51中,如果直接寫“P1.0”編譯器并不能識別,而且P1.0也不是一個合法的C51語言程序變量名,所以必須給它起一個另外的名字,這里起的名字是P10,可是P10是否就是P1.0呢,所以必須給它們建立聯(lián)系,這里使用了C51的關鍵字“sbit”來進行定義。37拽謝拭藻柳鍺氦鴻強祿鋼話鄂牢旨僳枉菏掏煽衛(wèi)皂急林臂柜窺啡限佃秩委單片機第14章C語言程序設計單片機第14章C語言程序設計38
第3行~第9行對函數(shù)Delay進行了事先定義,只有這樣,才能在主程序中被主函數(shù)main()調(diào)用。自行編寫的函數(shù)Delay()的用途是軟件延時,調(diào)用時使用的這個“800”被稱為“實際參數(shù)”,以延時800ms的時間。
注意,內(nèi)層循環(huán)for(j=0;j<333;j++){;}這條語句在反匯編時對應的匯編代碼如下:
CLR A /*1個機器周期*/ MOV R7,A /*2個機器周期*/HERE: INC R7 /*1個機器周期*/ CJNE R7,#333,HERE/*2個機器周期*/38航綻霧搏水聶賞腰嗎諒差閨宛圣襟韭情啤躬系騙斗粱謂攜猾制成伯趨二戊單片機第14章C語言程序設計單片機第14章C語言程序設計39
其中{;}在反匯編時不對應任何語句,即不占用機器周期。因而,該for循環(huán)共需1+2+333*(1+2)=1002個機器周期,約為1ms。 相比之下調(diào)用外層循環(huán)for(;i>0;i--){}時的這1+2+i*(1002+1+2)可以近似為
i*1002,即i個ms。編程者可在一定范圍內(nèi)對i、j調(diào)整(不超過i、j的取值范圍),來控制延時時間的長短。 注意,若Delay()的定義寫在main函數(shù)的后面,則需要先作出聲明,否則編譯無法通過,因為編譯到main函數(shù)中的Delay()語句時,找不到相應的函數(shù)體。39委儉責吐駁削省咎陳共槍坎虱摘捏倉久祿矚葵礫茬缺違犀央巫稈葦擱榆馴單片機第14章C語言程序設計單片機第14章C語言程序設計40
main為“主函數(shù)”,每一個C語言程序有且只有一個主函數(shù),主函數(shù)后面一定有一對花括號“{}”,在花括號里面書寫該函數(shù)的代碼行。2.用戶自定義函數(shù)與庫函數(shù) 從結(jié)構(gòu)上劃分,函數(shù)分為主函數(shù)main()和普通函數(shù)兩種。對普通函數(shù),從用戶使用的角度劃分有兩種:一種是標準庫函數(shù);另一種是用戶自定義函數(shù)。(1)標準庫函數(shù)
KeilC51具有功能強大、資源豐富的標準庫函數(shù),由C51編譯器提供。進行程序設計時,應該善于充分利用40兜萍濃帽只屋奮葡覺計焙須爹娘僳搽大橋任你蛇煙兇籍沏俐際扼黎蒂妻美單片機第14章C語言程序設計單片機第14章C語言程序設計41這些功能強大、資源豐富的標準庫函數(shù),提高編程效率。用戶可以直接調(diào)用C51的庫函數(shù)而不需要為這個函數(shù)寫任何代碼,只需要包含具有該函數(shù)說明的頭文件即可。 例如調(diào)用輸出函數(shù)printf時,要求程序在調(diào)用輸出庫函數(shù)前包含以下的include命令:
#include<stdio.h>(2)用戶自定義函數(shù) 用戶根據(jù)自己需要所編寫的函數(shù)。如例14-1中的Delay函數(shù)。編寫時,需要注意以下幾點。41更啪輩芋口蚊諒子讓積撫眠彎醉錦迭廢癸薄茨巖茹贖隸獻壯鞠串皿薔發(fā)盼單片機第14章C語言程序設計單片機第14章C語言程序設計42
函數(shù)的首部(函數(shù)的第1行),包括函數(shù)名、函數(shù)類型、函數(shù)屬性、函數(shù)參數(shù)(形式參數(shù))名、參數(shù)類型。例如:voidDelay(unsignedinti)
函數(shù)體,即函數(shù)首部下面的花括號“{}”內(nèi)的部分。如果一個函數(shù)體內(nèi)有多個花括號,則最外層的一對“{}”為函數(shù)體的范圍。
C51區(qū)分大小寫,例如Delay與delay,編譯時是不同的兩個名稱。 每個語句最后必須有一個分號,分號是C語句的必要組成部分。42秒幅串炮忽垛瑪柞基崇憎揉開槳離諷撰閣認哲裁痔繳雖虞憊針普沸啤下匪單片機第14章C語言程序設計單片機第14章C語言程序設計43
從函數(shù)的定義的形式上劃分可以有三種形式:無參數(shù)函數(shù)、有參數(shù)函數(shù)和空函數(shù)。(1)無參數(shù)函數(shù) 此種函數(shù)在被調(diào)用時,既無參數(shù)輸入,也不返回結(jié)果給調(diào)用函數(shù),只是為完成某種操作而編寫的。(2)有參數(shù)函數(shù) 調(diào)用此種函數(shù)時,必須提供實際的輸入函數(shù),必須說明與實際參數(shù)一一對應的形式參數(shù),并在函數(shù)結(jié)束時返回結(jié)果,供調(diào)用它的函數(shù)使用。例如,例14-1中的第3行的“i”是形式參數(shù)。43土搪片誡茲蘇之靳儡魂西硬胚霜贈硯斷汀炭惰環(huán)合礎鉛鈍前睬隧亂畜練謠單片機第14章C語言程序設計單片機第14章C語言程序設計44(3)空函數(shù) 函數(shù)體內(nèi)無語句,是空白的。調(diào)用空函數(shù)時,什么工作也不做,不起任何作用。定義空函數(shù)的目的,是為以后程序功能的擴充。程序最初設計時,往往只涉及最基本的功能模塊的函數(shù),其他模塊的功能函數(shù)可以在以后補上。因此先將非基本模塊的功能函數(shù)定義成空函數(shù),用一個空語句“;”占好位置,并寫好注釋,以后再用一個編好的函數(shù)代替它。例如,例14-1中的第8行的“;”就是一個空語句。44叁客覽供亂靡膳秤馳占距設婿挪嘔雞鏡熒澀娠肯嗽寨定涼項甲鎖聚市膝瞥單片機第14章C語言程序設計單片機第14章C語言程序設計453.函數(shù)調(diào)用 程序設計者的任務就是編寫一系列的用戶自定義函數(shù)模塊,并在需要的時候調(diào)用這些函數(shù)以及庫函數(shù),實現(xiàn)程序所要求的功能。調(diào)用分為以下幾種。(1)簡單調(diào)用 調(diào)用格式為:函數(shù)名(實際參數(shù)1,實際參數(shù)2,…) 例如,例14-1中主函數(shù)main()里的子函數(shù)調(diào)用語句“Delay(800);”,其中800為實際參數(shù)。45干度獰喳磚澤專艷吞凸孟完批汀廬繃孕叫足仆斤訓隧占稀衛(wèi)冀啼伺釉滾娘單片機第14章C語言程序設計單片機第14章C語言程序設計46(2)嵌套調(diào)用 是在被調(diào)用的函數(shù)中又調(diào)用其他函數(shù)的語句。(3)遞歸調(diào)用 函數(shù)的遞歸調(diào)用就是一個函數(shù)在其函數(shù)體內(nèi)有調(diào)用自身。再入函數(shù)是一種可以在函數(shù)體內(nèi)直接或間接調(diào)用自身的一種函數(shù),在KeilC51中遞歸函數(shù)必須是可重入的,可重入的函數(shù)需要加上reentrant。 再入函數(shù)有以下幾點規(guī)定。46蒼瘴涂漱庸暫室村八桿褲臂餡匈堯股健冬姨盤介隸咖帛話齊衰侶目水摩刁單片機第14章C語言程序設計單片機第14章C語言程序設計47
再入函數(shù)不能包括位操作以及51單片機的未尋址區(qū)。在同一個程序中可以定義和使用不同存儲模式的再入函數(shù), 任何模式的再入函數(shù)不能調(diào)用不同模式的再入函數(shù)。在參數(shù)的傳遞上,實際參數(shù)可以傳遞給間接調(diào)用的再入函數(shù)。14.2.4C51的運算符 在程序中實現(xiàn)運算,要熟悉常用的運算符。本節(jié)對C51中用到的標準C運算符進行復習,為C51的程序設計打下基礎。1.算術(shù)運算符 如表14-3所示。47蔽駕奎矣澡促湖逛胚尖率突烹扔紋只芍磅穩(wěn)暇虎御振逞滁秋褪雷停醋糾渦單片機第14章C語言程序設計單片機第14章C語言程序設計48
表14-3
算術(shù)運算符及其說明48符號+-*/%++--說明加法運算減法運算乘法運算除法運算取模運算自增1自減1酗肘拙脂印浪旗潔霜嶺蝎懦妒跺汲整耗但憂盆巴宙柄謗松庸獄蒜婚龐抖銹單片機第14章C語言程序設計單片機第14章C語言程序設計49
對于“/”和“%”往往會有疑問。這兩個符號都涉及除法運算,但“/”運算是取商,而“%”運算為取余數(shù)。例如“5/3”的結(jié)果(商)為1,而“5%3”的結(jié)果為2(余數(shù))。
表14-3中的自增和自減運算符是使變量自動加1或減1,自增和自減運算符放在變量前和變量之后是不同的。
++i,--i:在使用i之前,先使i值加(減)1。
i++,i--:在使用i之后,再使i值加(減)1。49彩覆史匣凄俠鵝洞藍斌堅不聳蝎譽頃矢速物核少痰訪畔染殆輻棵訣畝類勒單片機第14章C語言程序設計單片機第14章C語言程序設計50
例如:若i=4,則執(zhí)行x=++i時,先使i加1,再引用結(jié)果,即x=5,運算結(jié)果為i=5,x=5。 再如:若i=4,則執(zhí)行x=i++時,先引用i值,即x=4,再使i加1,運算結(jié)果為i=5,x=4。 在例14-1中可以看到有關自增和自減運算符的應用。2.邏輯運算符 邏輯運算符及其說明如表14-4所示。50楚述嫡倫腫光醉塵鑰謎愚清醫(yī)癸餞柄樊黨僳晶矣鬃酸啃諧姜否松礫鱉價瑚單片機第14章C語言程序設計單片機第14章C語言程序設計51
表14-4
邏輯運算符及其說明3.關系運算符 判斷兩個數(shù)之間的關系。關系運算符及其說明如表14-5。51符號&&ΙΙ!說明邏輯與邏輯或邏輯非偶釀挑然稚肆庶北藻礙跳衛(wèi)騾鄉(xiāng)竊頭滬財酚哮釬佃獨紊則載痊港陌竣瞅飼單片機第14章C語言程序設計單片機第14章C語言程序設計52
表14-5
關系運算符及其說明52符號><>=<===!=說明大于小于大于或等于小于或等于等于不等于頌操暫茁炸七稀番彰唁莎勸沂印佃雁炬翅化墓乙視圃蜒墜沖包我氧翁錫貢單片機第14章C語言程序設計單片機第14章C語言程序設計534.位運算 位運算符及其說明如表14-6所示。
表14-6
位運算其說明53符號&Ι^~<<>>說明位邏輯與位邏輯或位異或位取反位左移位右移柜譏孕殃炎勛末冉讓斌雙伺終涯捆聶煌匯閨俏兩郵顛拌凰移至矛恩陳侍倦單片機第14章C語言程序設計單片機第14章C語言程序設計545.賦值、指針和取值運算符 是對變量操作的基本運算。賦值、指針和取值運算符及其說明如表14-7所示。
表14-7
位運算其說明54符號=*&說明賦值指向運算符取地址雛校硝差臥聊狗航濃鋤斧怔裝爬譚宣詐景瑤峙坤汕熒峪書兄咳軀彬壁句匆單片機第14章C語言程序設計單片機第14章C語言程序設計5514.2.5C51的分支與循環(huán)程序結(jié)構(gòu) 程序結(jié)構(gòu)上可把程序分為三類,即順序、分支和循環(huán)結(jié)構(gòu)。順序結(jié)構(gòu)是程序的基本結(jié)構(gòu),程序自上而下,從main()的函數(shù)開始一直到程序運行結(jié)束,程序只有一條路可走,沒有其他的路徑可以選擇。順序結(jié)構(gòu)比較簡單和便于理解,這里重點介紹分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。55臀鐮營略粹票醚攙悔戍欄切鈉諜置搬摘巳疏閉己鑼儀醚邪艱卑賜御韌滯晴單片機第14章C語言程序設計單片機第14章C語言程序設計561.分支結(jié)構(gòu)程序(1)只有兩條分支的時候用
If(條件){分支1} else{分支2}(2)分支較多時
在分支較多時的情況下使用switch語句。56蓑古衍敢偏莎削瑟在馮備砷壯配底丘算住訂吮針給批它家坡渾躺雇寇聰魁單片機第14章C語言程序設計單片機第14章C語言程序設計57switch(){case():語句;
break;
case():語句;
break;
………… default:語句;
break;
}57年莽攢疹政遜扁工惱磊胺企爸吳苔菜藍梨論側(cè)清良滯坑孤叢酬只官猜曳大單片機第14章C語言程序設計單片機第14章C語言程序設計58
注意:每個switch分支必須有一個break語句,否則程序并不能跳出switch,就會繼續(xù)執(zhí)行case后面的case語句。如果看一下上述結(jié)構(gòu)的程序?qū)膮R編語言源程序可看到,每一條break語句對應了匯編語言中的一條SJMP指令,而沒有SJMP指令程序會繼續(xù)向下執(zhí)行,并不能跳出分支選擇語句。 實際上在對應的匯編語言源程序中,case(0),case(1)……只是確定了分支的地址,真正的判斷是在switch語句開始的。58云秧幌契面凹懈找販鋁找沮涵尿陪新仍空芍規(guī)系怖蕪慢視鈍祥掌岸暖走誡單片機第14章C語言程序設計單片機第14章C語言程序設計592.循環(huán)結(jié)構(gòu)程序 循環(huán)語句有以下三種。(1)for循環(huán)格式:for(循環(huán)體初始化;循環(huán)體執(zhí)行條件;循環(huán)體執(zhí)行后操作) 花括號{}中為循環(huán)體內(nèi)容。 這里有一個值得注意的現(xiàn)象,能夠反映出C51在編譯中對于執(zhí)行時間和占用的存儲單元的權(quán)衡。 例如,for(i=0;i<10;i++)對應的匯編語句為:59者斯幽咱奏其隴億室貳挪秋賽徘癌唯夜擴值唇稍搔傅正均盟睦虹綢甚嚴酋單片機第14章C語言程序設計單片機第14章C語言程序設計60 CLR A ;1個機器周期
MOV R7,A ;2個機器周期LOOP: INC R7 ;1個機器周期
CJNE R7,#0AH,LOOP ;2個機器周期而for(i=2;i<10;i++)對應的匯編語句為:
MOV R7,#02H ;2個機器周期LOOP: INC R7 ;一個機器周期
CJNE R7,#0AH,LOOP ;兩個機器周期60治汛設墑劉君叛善痹報墻怯稗矮瞥廬宙充句沮雞辟贅缸垢壹卵殲泳更我傭單片機第14章C語言程序設計單片機第14章C語言程序設計61
為什么當i=0時,編譯器要多花一個機器周期對for循環(huán)初始化?這是因為在使用立即數(shù)時,單片機需要在代碼空間(程序存儲器)中為該立即數(shù)申請一個存儲單元,用來存放該立即數(shù),作為MOV指令的操作數(shù);而累加器A是單片機中的寄存器,使用A可以節(jié)省一個字節(jié)的存儲空間,從而實現(xiàn)以時間換取空間。(2)while循環(huán) 格式為:
while(循環(huán)體執(zhí)行條件),花括號{}中為循環(huán)體內(nèi)容。61戀表栗笨啡斡糊棋律銥槳松遼薛哪誼縫惰古獨贛搐烷虧甕趴收雍炮魁滁徐單片機第14章C語言程序設計單片機第14章C語言程序設計62(3)dowhile循環(huán) 格式為:
do{},花括號{}中為循環(huán)體內(nèi)容
while(循環(huán)體執(zhí)行條件) 前兩種循環(huán)是先進行循環(huán)條件是否滿足的判斷,才決定循環(huán)體是否執(zhí)行;而“dowhile循環(huán)”是在執(zhí)行完循環(huán)體后再判斷條件是否滿足,再決定循環(huán)體是否繼續(xù)執(zhí)行。三種循環(huán)中,經(jīng)常使用的是for語句。下面來說明for語句的應用。62掐咎徐忙河挫陛宿賓護乙帝賊港氨悍途苗厲代資搏哩劊藻瞻碎眨益坯求豹單片機第14章C語言程序設計單片機第14章C語言程序設計63【例14-2】求1到100之間整數(shù)的和。 程序如下:
#include<reg51.h> #include<stdio.h> main() { intnVar1,nSum;
for(nVar1=0,nSum=1;nSum<=100;nSum++) nVar1+=nCount;
/*累加求和*/ while(1);
}63惑叉而宮辛才壟訛世袒供棄舅余靜開利兇拔烴廟糾陶起其悍惰頁極夸敝哇單片機第14章C語言程序設計單片機第14章C語言程序設計64
關于循環(huán),需說明的是,在無操作系統(tǒng)的控制器和處理器上運行的程序,主體通常采用輪詢方式,即把所有的操作包含在一個while(1){}中,如例14-1。這樣的無限循環(huán)在面向通用計算機的軟件設計中是不被允許的,然而嵌入式系統(tǒng)軟件設計中,則由于其硬件構(gòu)成和使用需求,常常采用這種無限循環(huán)。64助孜焚脅茹腥痰鬼嬰崔債轍馳乎礎睜叉捐釬墅瑩忍炙錨抑選倆祟翱樂謹糙單片機第14章C語言程序設計單片機第14章C語言程序設計6514.2.6AT89C51不同存儲區(qū)的C51定義
AT89C51有不同的存儲區(qū)。利用絕對地址的頭文件absace.h可對不同的存儲區(qū)進行訪問。該頭文件的函數(shù)包括:
CBYTE (訪問code區(qū),字符型) DBYTE (訪問data區(qū),字符型) PBYTE (訪問pdata區(qū)或I/O口,字符型) XBYTE (訪問xdata區(qū)或I/O口,字符型)
另外還有CWORD、DWORD、PWORD、XWORD四個函數(shù),它們的訪問區(qū)域同上,只是訪問的數(shù)據(jù)類型為int型。65昔軍鹽桂刊勿耐溯彈痹兒曼痹透嫂賽啊抬誠號燼燃金莢砷啦右另聊占忘訃單片機第14章C語言程序設計單片機第14章C語言程序設計66
注意:AT89S51片內(nèi)的4個并行I/O口(P0~P3),都是SFR,故對P0~P3采用定義SFR的方法。而AT89S51在片外擴展的并行I/O口,這些擴展的I/O口與片外擴展的RAM是統(tǒng)一編址的,即把一個外部I/O端口當作外部RAM的一個單元來看待??筛鶕?jù)需要來選擇為pdata類型或xdata類型。對于片外擴展的I/O端口,根據(jù)硬件譯碼地址,將其看作片外RAM的一個單元,使用語句#define進行定義。例如:
#includ<absace.h>;
/*不可缺少*/ #definePORTBXBYTE[0xffc2] ;
/*定義外部I/O口PORTB的地址為xdata區(qū)的0xffc2*/66抨蜒污妻榆覆急沙撼閏噬懲啟射汽陜峽臥祖微擱還幾霉灣庇玖瑟棠拄纂廚單片機第14章C語言程序設計單片機第14章C語言程序設計67
也可把片外I/O口的定義放在一個頭文件中,然后在程序中通過#include語句調(diào)用。一旦在頭文件或程序中通過使用#define語句對片外I/O口進行了定義,在程序中就可以自由使用變量名(例如:PORTB)來訪問這些片外I/O端口了。14.2.7C51中斷服務函數(shù)的定義 由于標準C沒有處理單片機中斷的定義,為直接編寫中斷服務程序,C51編譯器對函數(shù)的定義進行了擴展,增加了一個擴展關鍵字interrupt,使用該關鍵字可以將一個函數(shù)定義成中斷服務函數(shù)。由于C51編譯器在編譯時對67醉俐括竿鄰嬸殿督顆誅齋濁宿役畜蹦寺核研艷胖寸隨煮皋呢腋綁引昏怪稍單片機第14章C語言程序設計單片機第14章C語言程序設計68聲明為中斷服務程序的函數(shù)自動添加了相應的現(xiàn)場保護、阻斷其他中斷、返回時恢復現(xiàn)場等處理的程序段,因而在編寫中斷服務函數(shù)時可不必考慮這些問題,減輕了用匯編語言編寫中斷服務程序的繁瑣程度,而把精力放在如何處理引發(fā)中斷請求的事件上。 中斷服務函數(shù)的一般形式為: 函數(shù)類型
函數(shù)名(形式參數(shù)表)[interruptn][usingn]
關鍵字interrupt后面的
n是中斷號,對于AT89S51,取值為0~4,編譯器從8×n+3處產(chǎn)生中斷向量。AT89S51中斷源對應的中斷號和中斷向量見表14-3。68坪戈沏麥啪宦錐望它臘舅氖九球輔聾哉飛瘧夾奮痹州于估掣段番伍簾促釋單片機第14章C語言程序設計單片機第14章C語言程序設計69
表14-3AT89S51中斷號和中斷向量
AT89S51在內(nèi)部RAM中有4個工作寄存器區(qū),每個寄存器區(qū)包含8個工作寄存器(R0-R7)。C51擴展了一個關鍵字using,專門用來選擇AT89S51的4個不同的工作寄存器區(qū)。在定義一個函數(shù)時,using是一個選項,如果不選用該項,則由編譯器選擇一個寄存器區(qū)作為絕對寄存器區(qū)訪問。69中斷號n01234其他值中斷源外部中斷0定時器0外部中斷1定時器1串行口保留中斷向量(8×n+3)0003H000BH0013H001BH0023H8×n+3永潦步裂述租利勉命若裝惺喀書彤控子授甘霹災歉氖屜諱水族勉毗病賒我單片機第14章C語言程序設計單片機第14章C語言程序設計70
關鍵字using對函數(shù)目標代碼的影響如下: 在中斷函數(shù)的入口處將當前工作寄存器區(qū)內(nèi)容保護到堆棧中,函數(shù)返回前將被保護的寄存器區(qū)的內(nèi)容從堆棧中恢復。 使用關鍵字using在函數(shù)中確定一個工作寄存器區(qū)時必須小心,要保證工作寄存器區(qū)切換都只在指定的控制區(qū)域中發(fā)生,否則將產(chǎn)生不正確的函數(shù)結(jié)果。還要注意,帶using屬性的函數(shù)原則上不能返回bit類型的值,且關鍵字using和關鍵字interrupt都不允許用于外部函數(shù),另外也都不允許有一個帶運算符的表達式。70吶勿或摩玲濁欽猙襟茫賂卻鋤炒坑幾惜態(tài)梭們港碳悉諜箔淑舵不臥瘟霞屬單片機第14章C語言程序設計單片機第14章C語言程序設計71
例如,外中斷1()的中斷服務函數(shù)書寫如下:voidint1()interrupt2using0/*中斷號n=2,選擇0區(qū)工作寄存器區(qū)*/
編寫AT89S51中斷程序時,應遵循以下規(guī)則:(1)中斷函數(shù)沒有返回值,如果定義了一個返回值,將會得到不正確的結(jié)果。因此建議在定義中斷函數(shù)時,將其定義為void類型,以明確說明沒有返回值。(2)中斷函數(shù)不能進行參數(shù)傳遞,如果中斷函數(shù)中包含任何參數(shù)聲明都將導致編譯出錯。71垮裳楊雇卡敘趴昆些陡以撥笆經(jīng)瘡薩諸馭磊斗映驚盞褪碘你等邦首吶蘆蕉單片機第14章C語言程序設計單片機第14章C語言程序設計72(3)在任何情況下都不能直接調(diào)用中斷函數(shù),否則會產(chǎn)生編譯錯誤。因為中斷函數(shù)的返回是由指令RETI完成的。RETI指令會影響AT89S51中的硬件中斷系統(tǒng)內(nèi)的不可尋址的中斷優(yōu)先級寄存器的狀態(tài)。如果在沒有實際的中斷請求的情況下,直接調(diào)用中斷函數(shù),也就不會執(zhí)行RETI指令,其操作結(jié)果有可能產(chǎn)生一個致命的錯誤。(4)如果在中斷函數(shù)中再調(diào)用其他函數(shù),則被調(diào)用的函數(shù)所使用的寄存器區(qū)必須與中斷函數(shù)使用的寄存器區(qū)不同。72麥魚纜紗征距伏措瑣灼腎嫌些款撮伍旬搔餞標簿未擦舍落蘇戴竊陳詠諸窗單片機第14章C語言程序設計單片機第14章C語言程序設計7314.3C51的程序設計舉例本節(jié)重點介紹對AT89S51片內(nèi)各種功能部件及硬件接口的C51例程,讀者應仔細閱讀并理解這些例程。14.3.1中斷程序的編寫為響應中斷請求而進行中斷處理的程序稱為中斷程序。由中斷初始化程序和中斷服務程序兩部分組成。中斷初始化程序的位置位于主程序中,主要包括選擇外部中斷的觸發(fā)方式、開中斷、設置中斷優(yōu)先級等。73敦肖濺羅業(yè)究底錳齡九炒樹農(nóng)作墊卸綱蔡內(nèi)狡??s乒老由曳落鋤掙酶澄沫單片機第14章C語言程序設計單片機第14章C語言程序設計74
【例14-3】在單片機系統(tǒng)的P1口上接有8只LED,LED的陽極接+5V,陰極接P1口的引腳。當P1口某一口線輸出為0時,將LED點亮。在外部中斷0輸入腳P3.2()引腳接上拉電阻并接有一只按鈕開關K1。用K1按鈕來產(chǎn)生外部中斷0的輸入信號。接口電路如圖14-1所示。 要求將外部中斷0設為負跳沿觸發(fā)。在程序剛啟動時,P1口上的8只LED亮。按一次按鈕開關K1,使引腳P3.2接地,產(chǎn)生一個外中斷0的中斷請求,在中斷服務程序中,讓低4位LED和高4位LED交替閃爍。參考程序:74慨叢濘診菌單溺凈宋充幼撾墨袍椽奸鬧娜雕竹芒倚扦斂懦瀑儈侯寇比每毯單片機第14章C語言程序設計單片機第14章C語言程序設計7575圖14-1
控制8只LED交替閃爍的電路陜霹國碉姆柜談油柿櫥佩挎堅斃性警假臃南兆插朝破船駝委閨亡蛛燒攢胞單片機第14章C語言程序設計單片機第14章C語言程序設計76#include<reg51.h>voidDelay(unsignedinti) /*定義延時函數(shù)Delay(),i是形式參數(shù),不能賦初值*/{ unsignedintj;
for(;i>0;i--) for(j=0;j<333;j++) /*晶振為12MHz,j的范圍見例 14-1*/ {;} /*空函數(shù)*/}76舀篇窟直姥翼煞拂砌喂系匝尹轟夷噬態(tài)煌癬圍親彎征哄蠕住詣遁釘骨糠跡單片機第14章C語言程序設計單片機第14章C語言程序設計77voidmain() /*主函數(shù)*/{ EA=1;
/*總中斷允許*/ EX0=1;
/*外部中斷0中斷允許*/ IT0=1;/*選擇外部中斷0為跳沿觸發(fā)方式*/ While(1) /*循環(huán)*/ {P1=0;} /*P1口的8只LED全亮*/}77疑囪帚癡垛實麓曲淘串哭棄州檢狹寺哄倚戌硝繕詢躇耳祿甜當紗爺憑亢享單片機第14章C語言程序設計單片機第14章C語言程序設計78voidint0()interrupt0using0 /*外中斷0的中斷服務函數(shù)*/{ EX0=0;
/*禁止外部中斷0中斷*/ P1=0x0f;
/*低4位LED滅,高4位LED亮*/ Delay(800);
/*延時800ms*/ P1=0xf0;
/*高4位LED滅,低4位LED亮*/ Delay(800);
/*延時800ms*/ EX0=1;/*中斷返回前,打開外部中斷0中斷*/}78敖晝建碟未您腥堯侶較紳俯侈賒誹拿剩惦灼擾電讒梳渴輝絢棧繁丑梳廖尉單片機第14章C語言程序設計單片機第14章C語言程序設計7914.3.2定時器程序的編寫 【例14-4】在AT89S51的P1口上接有8只LED。下面采用定時器T0的方式1的定時中斷方式,使P1口外接的8只LED每0.5s閃亮一次。(1)設置TMOD寄存器 定時器T0工作在方式1,應使TMOD寄存器的M1、M0=01;定時器模式,應設置C/=0;對T0的運行控制僅由TR0來控制,應使GATE0=0。定時器T1不使用,各相關位均設為0。所以,TMOD寄存器應初始化為0x01。79坍魂駭飽旺緊謂榔撼據(jù)忍撩腰酞硒洲族稈口抖碾積占筷鹿藍船爍跳戰(zhàn)絕豁單片機第14章C語言程序設計單片機第14章C語言程序設計80(2)計算定時器T0的計數(shù)初值 設定時時間5ms(即5000μs),設定時器T0的計數(shù)初值為X,假設晶振的頻率為11.0592MHz,則定時時間為:定時時間=(216?X)12/晶振頻率 則5000=(216
?X)12/11.0592得:X=60928,轉(zhuǎn)換成十六進制后為:0xee00,其中0xee裝入TH0,0x00裝入TL0。(3)設置IE寄存器 本例由于采用定時器T0中斷,因此需將IE寄存器中的EA、ET0位置1。80鄒印出稗杯殿妒琳器上膩膨闡刑黍易奈追科嗽硅庚最澈媚褪混緩釘窄叢莊單片機第14章C語言程序設計單片機第14章C語言程序設計81(4)啟動和停止定時器T0
將定時器控制寄存器TCON中的TR0=1,則啟動定時器T0;TR0=0,則停止定時器T0定時。 定時器T0方式1中斷定時的參考程序:
#include<reg51.h> Chari=100;
/*給變量i賦初值*/ voidmain() { TMOD=0x01;
/*設置定時器T0為方式1*/ TH0=0xee;
/*向TH0寫入初值的高8位*/81涸監(jiān)虜侗躬硅旁頁矣紙等燴蜂陳掄菱悉淌迫芯岡覆樸挖舵褐輕榜痕苗稠銻單片機第14章C語言程序設計單片機第14章C語言程序設計82 TL0=0x00;
/*向TL0寫入初值的低8位*/ P1=0x00;
/*P1口8只LED點亮*/ EA=1;
/*總中斷允許*/ ET0=1;
/*定時器T0中斷允許*/ TR0=1;
/*啟動定時器T0*/ while(1);
/*循環(huán)*/ {
;
}}82試滋訝傷剔遲釜締治峰或穿彬幅咋蠱巖摹乒湘稠養(yǎng)僑莎罵腺叁儈餾蔓廣倪單片機第14章C語言程序設計單片機第14章C語言程序設計83VoidT0_int(void)interrupt1/*定時器T0中斷服務程序*/{ TH0=0xee;/*給T0裝入16位初值,計數(shù)4608后,T0溢出*/ TL0=0x00;
i--;
/*循環(huán)次數(shù)減1*/ if(i<=0) { P1=~P1;
/*P1口按位取反*/ i=100;
/*重新設置循環(huán)次數(shù)*/ }}83淚吾錢熾淌晌安內(nèi)梗蘆慧物靛青許媚徊嚙生評艇員覺胃筐偷骨眷曾硼魄澤單片機第14章C語言程序設計單片機第14章C語言程序設計8414.3.3串行口方式0應用程序的編寫
AT89S51的串口的方式0是同步串行通信接口。方式0的典型應用是外擴串行輸入并行輸出的同步移位寄存器74LS164,實現(xiàn)并行I/O的擴展。 【例14-5】圖14-2是利用串行口方式0通過74LS164外接8個LED發(fā)光二極管的接口電路,編寫程序使發(fā)光二極管輪流顯示。圖中CLK端為同步脈沖輸入端。STB為控制端,當STB=0時,則8位并行輸出端關閉,但是允許串行數(shù)據(jù)從A和B端輸入。當STB=1時,A和B輸入端關閉,但允許8位并行數(shù)據(jù)輸出。84展鳳素只鐮徑特酶摯機郴掉秀奏厘慰叮供貼齊鈾濰碑晨祿臃代線到包確義單片機第14章C語言程序設計單片機第14章C語言程序設計85當8位串行數(shù)據(jù)發(fā)送完畢后,引起中斷,在中服務程序中,串行發(fā)出下一個8位數(shù)據(jù)。參考程序如下。85圖14-2
串行口的方式0外接8個LED發(fā)光二極管的接口電路莖測九濘渦曹模亦冗含巖賦怪制召份釬妄撐支萬覓影丟呂絕宙語羊瑪喇朝單片機第14章C語言程序設計單片機第14章C語言程序設計86#include<reg51.h>#include<stdio.h>sbitP10=0x90;XdatacharnIndex;Delay();main(){ SCON=0x00;
/*串行口初始化為方式0*/ ES=1;
EA=1;
/*全局中斷允許
*/nIndex=1;
SBUF=nIndex;
P10=0;
while(1)86餃彼或嵌檀葵壁雞莉重垢署餓蕩員韶峽煌淬炎同歸訣隙魄菊沸淵痛幻膛家單片機第14章C語言程序設計單片機第14章C語言程序設計87 {;}}voidSerial_Port()interrupt4using0{ if(TI==1){ P10=1;
Delay();
P10=1;
nIndex<<=1;
if(nIndex==0)nIndex=1;
SBUF=nIndex;} TI=0;
RI=0;87齊蜂筋浙泵熏磅梅戴裳些闌萊枉撈衣銹剛艇漁邏念贖詫苔軌碗掏況畫常蛔單片機第14章C語言程序設計單片機第14章C語言程序設計88}Delay(){intnCounter;for(nCounter=0;nCounter<128;nCounter++);}88奈伎索磨磅杯譜溶吊仿?lián)崛⒅骖~舞傷均急面惦瞥橡嗚皂賄俺樣臼踴晉梧還單片機第14章C語言程序設計單片機第14章C語言程序設計8914.3.4獨立式鍵盤查詢方式【例14-6】采用查詢方式對實現(xiàn)獨立式鍵盤的鍵值讀取。獨立式鍵盤的接口電路如圖14-3所示。89圖14-3
獨立式鍵盤的接口電路關污菏鍍推孝昏號崖奴嗡壬求徊砍斌匝勸瀉起覓遼盜冬胞磁蛋碾摯蹦迭霸單片機第14章C語言程序設計單片機第14章C語言程序設計90
由圖14-3,當P1口某一位為0時,表明該位所接的按鍵被按下,然后在計算機屏幕上輸出按下的按鍵的信息。
例如,3號鍵按下,則在PC機顯示屏上顯示“keyNo.3down”。程序如下:
#include<reg51.h> #include<stdio.h> /*因為用到printf()函數(shù),所以要包含stdio.h*/ Uart_Init();
sbitP10=0x90;
/*定義P1口各位的位名*/ sbitP11=0x91;
sbitP12=0x92;啄戰(zhàn)懸懂離趣誕俯嫡裂滄詣燴秀寨繁互粱育著拜局籠段薔垃濺稱虐矮短父單片機第14章C語言程序設計單片機第14章C語言程序設計91sbitP13=0x93;sbitP14=0x94;sbitP15=0x95;sbitP16=0x96;sbitP17=0x97;main(){ Uart_Init();
while(1);
/*無限循環(huán),不斷查詢按鍵狀態(tài),鍵值判斷和提示信 息的顯示*/{91訣抽丟浦銹券安級捅渡侈丸絆廢共艘弱炒耗主坑鞘帕詳表甥兄騾防瘟鴛桔單片機第14章C語言程序設計單片機第14章C語言程序設計92if(P10==0)printf("keyNo.0down\n");/*如0號鍵按下,串行輸出按下鍵信息*/ if(P11==0)printf("keyNo.1down\n");/*如1號鍵按下,串行輸出按下鍵信息*/if(P12==0)printf("keyNo.2down\n");/*如2號鍵按下,串行輸出按下鍵信息*/
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025屆山東省莒縣實驗中學高三第三次測評英語試卷含解析
- 海西市重點中學2025屆高三下學期聯(lián)合考試數(shù)學試題含解析
- 2025屆山東省煙臺市萊州市一中高考全國統(tǒng)考預測密卷英語試卷含解析
- 云南省玉溪市富良棚中學2025屆高三適應性調(diào)研考試數(shù)學試題含解析
- 2025屆江蘇省金陵中學高考英語倒計時模擬卷含解析
- 現(xiàn)代學徒制課題:現(xiàn)場工程師人才培養(yǎng)模式及評價標準研究(附:研究思路模板、可修改技術(shù)路線圖)
- 專題10 書面表達20篇(解析版)-2024-2025學年七年級英語上學期期末名校真題進階練(深圳專用)
- 《認識Linux的桌面》課件
- 江西省撫州市臨川一中2025屆高考語文全真模擬密押卷含解析
- 貴州省納雍縣第五中學2025屆高三壓軸卷數(shù)學試卷含解析
- 初中物理教師個人校本研修工作計劃(20篇)
- 第七章消費者權(quán)益
- 齊魯工業(yè)大學《食品原料學》2023-2024學年第一學期期末試卷
- 無薪留職協(xié)議樣本
- 工業(yè)區(qū)污水凈化服務合同
- 《建設項目工程總承包合同示范文本(試行)》GF-2011-0216
- 幼兒園中班音樂活動《小看戲》課件
- 2024年下半年貴州六盤水市直事業(yè)單位面向社會招聘工作人員69人易考易錯模擬試題(共500題)試卷后附參考答案
- 實+用法律基礎-形成性考核任務一-國開(ZJ)-參考資料
- 2024年小學校長工作總結(jié)(3篇)
- 《軟件開發(fā)流程》課件
評論
0/150
提交評論