




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
單片機原理及應(yīng)用李建忠第1頁,共169頁,2023年,2月20日,星期一7.1C語言與MCS–51用匯編程序設(shè)計MCS–51系列單片機應(yīng)用程序時,必須要考慮其存儲器結(jié)構(gòu),尤其必須考慮其片內(nèi)數(shù)據(jù)存儲器與特殊功能寄存器正確、合理的使用以及按實際地址處理端口數(shù)據(jù)。用C語言編寫MCS–51單片機的應(yīng)用程序,雖然不像用匯編語言那樣具體地組織、分配存儲器資源和處理端口數(shù)據(jù),但在C語言編程中,對數(shù)據(jù)類型與變量的定義,必須要與單片機的存儲結(jié)構(gòu)相關(guān)聯(lián),否則編譯器不能正確地映射定位。用C語言編寫單片機應(yīng)用程序與編寫標準的C語言程序的不同之處就在于根據(jù)單片機存儲結(jié)構(gòu)及內(nèi)部資源定義相應(yīng)的C語言中的數(shù)據(jù)類型和變量,其它的語法規(guī)定、程序結(jié)構(gòu)及程序設(shè)計方法都與標準的C語言程序設(shè)計相同。第2頁,共169頁,2023年,2月20日,星期一用C語言編寫的應(yīng)用程序必須經(jīng)單片機的C語言編譯器(簡稱C51),轉(zhuǎn)換生成單片機可執(zhí)行的代碼程序。支持MCS–51系列單片機的C語言編譯器有很多種。如AmericanAutomation、Auocet、BSO/TASKING、DUNFIELDSHAREWARE、KEIL/Franklin等。其中KEIL/Franklin以它的代碼緊湊和使用方便等特點優(yōu)于其它編譯器。本章是針對這種編譯器介紹MCS–51單片機C語言程序設(shè)計。第3頁,共169頁,2023年,2月20日,星期一7.2C51數(shù)據(jù)類型及在MCS-51中的存儲方式7.2.1C51的數(shù)據(jù)類型FranklinC51編譯器具體支持的數(shù)據(jù)類型有:位型(bit)、無符號字符(unsignedchar)、有符號字符(singedchar)、無符號整型(unsignedint)、有符號整型(signedint)、無符號長整型(unsignedlong)、有符號長整型(signedlong)、浮點型(float)和指針類型等。第4頁,共169頁,2023年,2月20日,星期一表7.1FranklinC51的數(shù)據(jù)類型數(shù)據(jù)類型長度(bit)長度(byte)值域bit110,1unsignedchar810~255signedchar81–128~127unsignedint1620~65535signedint162–32768~32767unsignedlong3240~4294967295signedlong324–2147483648~2147483647float324±1.176E–38~±3.40E+38(6位數(shù)字)double648±1.176E–38~±3.40E+38(10位數(shù)字)一般指針243存儲空間0~65535第5頁,共169頁,2023年,2月20日,星期一7.2.2C51數(shù)據(jù)在MCS-51中的存儲方式位變量(bit):與MCS-51硬件特性操作有關(guān)的可以定義成位變量。位變量必須定位在MCS-51單片機片內(nèi)RAM的位尋址空間中。字符變量(char):字符變量的長度為1byte即8位。這很合適MCS-51單片機,因為MCS-51單片機每次可處理8位數(shù)據(jù)。對于無符號變量(unsignedchar)的值域范圍是0~255。對于有符號字符變量(signedchar),最具有重要意義的位是最高位上的符號標志位(msb)。此位為1代表"負",為0代表"正"。有符號字符變量和無符號字符變量在表示0~127的數(shù)值時,其含義是一樣的,都是0~0x7F。負數(shù)一般用補碼表示,即用11111111表示-1,用11111110表示-2……。當(dāng)進行乘除法運算時,符號問題就變得十分復(fù)雜,而C51編譯器會自動地將相應(yīng)的庫函數(shù)調(diào)入程序中來解決這個問題。第6頁,共169頁,2023年,2月20日,星期一整型變量(int):整型變量的長度為16位。與8080和8086CPU系列不同,MCS-51系列單片機將int型變量的高位字節(jié)數(shù)存放在低地址字節(jié)中,低位字節(jié)數(shù)存放在高地址字節(jié)中。有符號整型變量(signedint)也使用msb位作符號標志位,并使用二進制補碼表示數(shù)值??芍苯邮褂脦追N專用的機器指令來完成多字節(jié)的加、減、乘、除運算。整型變量值0x1234以圖7.1所示的方式存放在內(nèi)存中。第7頁,共169頁,2023年,2月20日,星期一圖7.1整型數(shù)的存儲結(jié)構(gòu)…0x120x34…+0+1地址0x120x340x560x78….+0+1+2+3地址圖7.2長整型變量的存儲結(jié)構(gòu)第8頁,共169頁,2023年,2月20日,星期一浮點型變量(float):浮點型變量為32位,占4個字節(jié),許多復(fù)雜的數(shù)學(xué)表達式都采用浮點變量數(shù)據(jù)類型。應(yīng)用符號位表示數(shù)的符號,用階碼和尾數(shù)表示數(shù)的大小。用它們進行任何數(shù)學(xué)運算都需要使用由編譯器決定的各種不同效率等級的庫函數(shù)。FranklinC51的浮點變量數(shù)據(jù)類型的使用格式與IEEE-754標準有關(guān),具有24位精度,尾數(shù)的高位始終為"1",因而不保存,位的分布如下:●1位符號位?!?位指數(shù)位?!?3位尾數(shù)。第9頁,共169頁,2023年,2月20日,星期一符號位是最高位,尾數(shù)為低23位,內(nèi)存中按字節(jié)存儲順序如下:地址+0+1+2+3內(nèi)容MMMMMMMMMMMMMMMMEMMMMMMMSEEEEEEE其中,S為符號位,1表示負,0表示正;E為階碼;M為23位尾數(shù),最高位為"1"。浮點變量值-12.5的十進制為:0xC1480000,它按圖7.3所示方式存于內(nèi)存中。第10頁,共169頁,2023年,2月20日,星期一0x000x000x480xC1….+0+1+2+3地址圖7.3浮點數(shù)的存儲結(jié)構(gòu)第11頁,共169頁,2023年,2月20日,星期一在編程時,如果只強調(diào)運算速度而不進行負數(shù)運算時,最好采用無符號(unsigned)格式。無符號字符類型的使用:無論何時,應(yīng)盡可能使用無符號字符變量,因為它能直接被MCS-51所接受?;谕瑯拥脑?,也應(yīng)盡量使用位變量。有符號字符變量雖然也只占用一個字節(jié),但需要進行額外的操作來進行測試代碼的符號位。這無疑會降低代碼效率。第12頁,共169頁,2023年,2月20日,星期一使用簡化形式定義數(shù)據(jù)類型。其方法是在源程序開頭使用#define語句自定義簡化的類型標識符。例如:#defineucharunsignedchar#defineuintunsignedint這樣,在編程中,就可以用uchar代替unsignedchar,用uint代替unsignedint來定義變量。第13頁,共169頁,2023年,2月20日,星期一7.3C51數(shù)據(jù)的存儲類型與MCS-51存儲結(jié)構(gòu)表7.2C51存儲類型與MCS-51存儲空間的對應(yīng)關(guān)系存儲類型與存儲空間的對應(yīng)關(guān)系data直接尋址片內(nèi)數(shù)據(jù)存儲區(qū),訪問速度快(128字節(jié))bdata可位尋址片內(nèi)數(shù)據(jù)存儲區(qū),允許位與字節(jié)混合訪問(16字節(jié))idata間接尋址片內(nèi)數(shù)據(jù)存儲區(qū),可訪問片內(nèi)全部RAM地址空間(256字節(jié))pdata分頁尋址片外數(shù)據(jù)存儲區(qū)(256字節(jié))由MOV@Ri訪問(i=0,1)xdata片外數(shù)據(jù)存儲區(qū)(64KB)由MOVX@DPTR訪問code程序存儲器64KB空間,由MOVC@DPTR訪問第14頁,共169頁,2023年,2月20日,星期一表7.3C51存儲類型及其數(shù)據(jù)長度和值域存儲類型長度(bit)長度(byte)值域范圍data810~255idata810~255pdata810~255xdata1620~65535code1620~65535第15頁,共169頁,2023年,2月20日,星期一帶存儲類型的變量的定義的一般格式為數(shù)據(jù)類型存儲類型變量名帶存儲類型的變量定義舉例:chardatavar1;bitbdataflags;floatidatax,y,z;unsignedintpdatavar2;unsignedcharvector[3][4];第16頁,共169頁,2023年,2月20日,星期一表7.4存儲模式說明存儲模式說明SMALL默認的存儲類型是data,參數(shù)及局部變量放入可直接尋址片內(nèi)RAM的用戶區(qū)中(最大128字節(jié))。另外所有對象(包括堆棧),都必須嵌入片內(nèi)RAM。棧長很關(guān)鍵,因為實際棧長依賴于函數(shù)嵌套調(diào)用層數(shù)COMPACT默認的存儲類型是pdata,參數(shù)及局部變量放入分頁的外部數(shù)據(jù)存儲區(qū),通過@R0或@R1間接訪問,??臻g位于片內(nèi)數(shù)據(jù)存儲區(qū)中LARGE默認的存儲類型是xdata,參數(shù)及局部變量直接放入片外數(shù)據(jù)存儲區(qū),使用數(shù)據(jù)指針DPTR來進行尋址。用此數(shù)據(jù)指針進行訪問效率較低,尤其對兩個或多個字節(jié)的變量,這種數(shù)據(jù)類型的訪問機制直接影響代碼的長度第17頁,共169頁,2023年,2月20日,星期一7.4MCS-51特殊功能寄存器(SFR)的C51定義MCS-51單片機中,除了程序計數(shù)器PC和4組工作寄存器組外,其它所有的寄存器均為特殊功能寄存器(SFR),分散在片內(nèi)RAM區(qū)的高128字節(jié)中,地址范圍為80H~0FFH。SFR中有11個寄存器具有位尋址能力,它們的字節(jié)地址都能被8整除,即字節(jié)地址是以8或0為尾數(shù)的。為了能直接訪問這些SFR,F(xiàn)ranklinC51提供了一種自主形式的定義方法,這種定義方法與標準C語言不兼容,只適用于對MCS-51系列單片機進行C語言編程。特殊功能寄存器C51定義的一般語法格式如下: sfrsfr-name=intconstant;第18頁,共169頁,2023年,2月20日,星期一"sfr"是定義語句的關(guān)鍵字,其后必須跟一個MSC-51單片機真實存在的特殊功能寄存器名,"="后面必須是一個整型常數(shù),不允許帶有運算符的表達式,是特殊功能寄存器"sfr-name"的字節(jié)地址,這個常數(shù)值的范圍必須在SFR地址范圍內(nèi),位于0x80~0xFF。例如:sfrSCON=0x98; /*串口控制寄存器地址98H*/sfrTMOD=0x89; /*定時器/計數(shù)器方式控制寄存器地址89H*/第19頁,共169頁,2023年,2月20日,星期一MCS-51系列單片機的特殊功能寄存器的數(shù)量與類型不盡相同,因此建議將所有特殊的"sfr"定義放入一個頭文件中,該文件應(yīng)包括MCS-51單片機系列機型中的SFR定義。C51編譯器的"reg51.h"頭文件就是這樣一個文件。在新的MCS-51系列產(chǎn)品中,SFR在功能上經(jīng)常組合為16位值,當(dāng)SFR的高字節(jié)地址直接位于低字節(jié)之后時,對16位SFR的值可以直接進行訪問。例如52子系列的定時器/計數(shù)器2就是這種情況。為了有效地訪問這類SFR,可使用關(guān)鍵字"sfr16"來定義,其定義語句的語法格式與8位SFR相同,只是"="后面的地址必須用16位SFR的低字節(jié)地址,即低字節(jié)地址作為"sfr16"的定義地址。第20頁,共169頁,2023年,2月20日,星期一例如:sfr16T2=0xCC /*定時器/計數(shù)器2:T2低8位地址為0CCH,T2高8位地址為0CDH*/這種定義適用于所有新的16位SFR,但不能用于定時器/計數(shù)器0和1。對于位尋址的SFR中的位,C51的擴充功能支持特殊位的定義,像SFR一樣不與標準C兼容,使用"sbit"來定義位尋址單元。第21頁,共169頁,2023年,2月20日,星期一第一種格式:sbitbit-name=sfr-name^intconstant;"sbit"是定義語句的關(guān)鍵字,后跟一個尋址位符號名(該位符號名必須是MCS-51單片機中規(guī)定的位名稱),"="后的"sfr-name"必須是已定義過的SFR的名字,"^"后的整常數(shù)是尋址位在特殊功能寄存器"sfr-name"中的位號,必須是0~7范圍中的數(shù)。例如:sfrPSW=0xD0; /*定義PSW寄存器地址為D0H*/sbitOV=PSW^2; /*定義OV位為PSW.2,地址為D2H*/sbitCY=PSW^7; /*定義CY位為PSW.7,地址為D7H*/第22頁,共169頁,2023年,2月20日,星期一第二種格式:sbitbit-name=intconstant^intconstant;"="后的intconstant為尋址地址位所在的特殊功能寄存器的字節(jié)地址,"^"符號后的intconstant為尋址位在特殊功能寄存器中的位號。例如:sbitOV=0XD0^2; /*定義OV位地址是D0H字節(jié) 中的第2位*/sbitCY=0XD0^7; /*定義CY位地址是D0H字節(jié)中 的第7位*/第23頁,共169頁,2023年,2月20日,星期一第三種格式:sbitbit-name=intconstant;"="后的intconstant為尋址位的絕對位地址。例如:sbitOV=0XD2; /*定義OV位地址為D2H*/sbitCY=0XD7; /*定義CY位地址為D7H*/特殊功能位代表了一個獨立的定義類,不能與其它位定義和位域互換。第24頁,共169頁,2023年,2月20日,星期一7.5MCS-51并行接口的C51定義MCS-51系列單片機并行I/O接口除了芯片上的4個I/O口(P0~P3)外,還可以在片外擴展I/O口。MCS-51單片機I/O口與數(shù)據(jù)存儲器統(tǒng)一編址,即把一個I/O口當(dāng)作數(shù)據(jù)存儲器中的一個單元來看待。使用C51進行編程時,MCS-51片內(nèi)的I/O口與片外擴展的I/O可以統(tǒng)一在一個頭文件中定義,也可以在程序中(一般在開始的位置)進行定義,其定義方法如下:對于MCS-51片內(nèi)I/O口按特殊功能寄存器方法定義。例如:sfrP0=0x80;/*定義P0口,地址為80H*/sfrP1=0x90;/*定義P1口,地址為90H*/第25頁,共169頁,2023年,2月20日,星期一對于片外擴展I/O口,則根據(jù)硬件譯碼地址,將其視作為片外數(shù)據(jù)存儲器的一個單元,使用#define語句進行定義。例如#include<absacc.h>#definePORTAXBYTE[0xFFC0]absacc.h是C51中絕對地址訪問函數(shù)的頭文件,將PORTA定義為外部I/O口,地址為FFC0H,長度為8位。一旦在頭文件或程序中對這些片外I/O口進行定義后,在程序中就可以自由使用變量名與其實際地址的聯(lián)系,以便使程序員能用軟件模擬MCS-51的硬件操作。第26頁,共169頁,2023年,2月20日,星期一(1)位變量C51定義。使用C51編程時,定義了位變量后,就可以用定義了的變量來表示MCS-51的位尋址單元。位變量的C51定義的一般語法格式如下:位類型標識符(bit)位變量名;例如:bitdirection_bit; /*把direction_bit定義為位變量*/bitlook_pointer; /*把look_pointer定義為位變量*/7.6位變量的C51定義第27頁,共169頁,2023年,2月20日,星期一(2)函數(shù)可包含類型為"bit"的參數(shù),也可以將其作為返回值。例如:
bitfunc(bitb0,bitb1) /*變量b0,b1作為函數(shù)的參數(shù)*/{return(b1); /*變量b1作為函數(shù)的返回值*/}注意,使用(#pragmadisable)或包含明確的寄存器組切換(usingn)的函數(shù)不能返回位值,否則編輯器將會給出一個錯誤信息?!?8頁,共169頁,2023年,2月20日,星期一(3)對位變量定義的限制。位變量不能定義成一個指針,如不能定義:bit*bit_pointer。不存在位數(shù)組,如不能定義:bitb_array[]。在位定義中,允許定義存儲類型,位變量都被放入一個位段,此段總位于MCS-51片內(nèi)的RAM區(qū)中。因此,存儲類型限制為data和idata,如果將位變量的存儲類型定義成其它存儲類型都將編譯出錯。第29頁,共169頁,2023年,2月20日,星期一例1先定義變量的數(shù)據(jù)類型和存儲類型:bdataintibase; /*定義ibase為bdata整型變量*/bdatacharbary[4]; /*bary[4]定義為bdata字符型數(shù)組*/然后可使用"sbit"定義可獨立尋址訪問的對象位:sbitmybit0=ibase^0; /*mybit0定義為ibase的第0位*/sbitmybit15=ibase^15; /*mybit0定義為ibase的第15位*/sbitAry07=bary[0]^7; /*Ary07定義為abry[0]的第7位*/sbitAry37=bary[3]^7; /*Ary37定義為abry[3]的第7位*/第30頁,共169頁,2023年,2月20日,星期一對象ibase和bary也可以字節(jié)尋址:ary37=0; /*bary[3]的第7位賦值為0*/bary[3]='a'; /*字節(jié)尋址,bary[3]賦值為'a'*/sbit定義要位尋址對象所在字節(jié)基址對象的存儲類型為"bdata",否則只有絕對的特殊位定義(sbit)是合法的。"^"操作符后的最大值依賴于指定的基類型,對于char/uchar而言是0~7,對于int/uint而言是0~15,對于long/ulong而言是0~31。第31頁,共169頁,2023年,2月20日,星期一7.7C51構(gòu)造數(shù)據(jù)類型1.基于存儲器的指針基于存儲器的指針以存儲器類型為參量,它在編譯時才被確定。因此,為指針選擇存儲器的方法可以省掉,以便這些指針的長度為一個字節(jié)(idata*,data*,pdata*)或2個字節(jié)(code*,xdata*)。編譯時,這類操作一般被"行內(nèi)"(inline)編碼,而無需進行庫調(diào)用?;诖鎯ζ鞯闹羔樁x舉例:charxdata*px;第32頁,共169頁,2023年,2月20日,星期一在xdata存儲器中定義了一個指向字符型(char)的指針變量px。指針自身在默認存儲區(qū)(決定于編譯模式),長度為2個字節(jié)(值為0~0xFFFF)。charxdata*datapdx;除了明確定義指針位于MCS-51內(nèi)部存儲區(qū)(data)外,其它與上例相同,它與編譯模式無關(guān)。datacharxdata*pdx;第33頁,共169頁,2023年,2月20日,星期一structtime{charhour;charmin;charsec;structtimexdata*pxtime;}在結(jié)構(gòu)structtime中,除了其它結(jié)構(gòu)成員外,還包含有一個具有和structtime相同的指針pxtime,time位于外部數(shù)據(jù)存儲器(xdata),指針pxtime具有兩個字節(jié)長度。第34頁,共169頁,2023年,2月20日,星期一structtimeidata*ptime;這個聲明定義了一個位于默認存儲器中的指針,它指向結(jié)構(gòu)time,time位于idata存儲器中,結(jié)構(gòu)成員可以通過MCS-51的@R0或@R1進行間接訪問,指針ptime為1個字節(jié)長。ptime→pxtime→hour=12;使用上面的關(guān)于structtime和structidata*ptime的定義,指針"pxtime"被從結(jié)構(gòu)中間接調(diào)用,它指向位于xdata存儲器中的time結(jié)構(gòu)。結(jié)構(gòu)成員hour被賦值為12。第35頁,共169頁,2023年,2月20日,星期一2.一般指針一般指針包括3個字節(jié):1個字節(jié)存儲類型和2個字節(jié)偏移地址,即地址+0+1+2內(nèi)容存儲器類型偏移地址高位字節(jié)偏移地址低位字節(jié)其中,第一字節(jié)代表了指針的存儲器類型,存儲器類型編碼如下:存儲器類型idataxdatapdatadatacode值12345第36頁,共169頁,2023年,2月20日,星期一例如,以xdata類型的0x1234地址為指針可以表示如下:地址+0+1+2內(nèi)容0x020x120x34當(dāng)用常數(shù)作指針時,必須注意正確定義存儲器類型和偏移量。例如,將常數(shù)值0x41寫入地址為0x8000的外部數(shù)據(jù)存儲器。
#defineXBYTE((char*)0x20000L)XBYTE[0x8000]=0x41;其中,XBYTE被定義為(char*)0x20000L,0x20000L為一般指針,其存儲類型為2,偏移量為0000H,這樣XBYTE成為指向xdata零地址的指針。而XBYTE[8000]則是外部數(shù)據(jù)存儲器的0x8000絕對地址。第37頁,共169頁,2023年,2月20日,星期一7.8模塊化程序開發(fā)過程圖7.4程序開發(fā)過程第38頁,共169頁,2023年,2月20日,星期一7.8.1混合編程1.命名規(guī)則表7.5函數(shù)名的轉(zhuǎn)換說明符號名轉(zhuǎn)換規(guī)則voidfunc(void)FUNC無參數(shù)傳遞或不含寄存器參數(shù)的函數(shù)名不作改變轉(zhuǎn)入目標文件中,名字只是簡單地轉(zhuǎn)換為大寫形式voidfunc(void)_FUNC帶寄存器參數(shù)的函數(shù)名加入“_”字符前綴,表明這類函數(shù)包含寄存器的參數(shù)傳遞voidfunc(void)reentrant_?FUNC對于重入函數(shù)加上“_?”字符串前綴,表明這類函數(shù)包含棧內(nèi)的參數(shù)傳遞第39頁,共169頁,2023年,2月20日,星期一例2用匯編語言編寫函數(shù)"toupper",參數(shù)傳遞發(fā)生在寄存器R7中。UPPERSEGMENTCODE ;程序段PUBLIC_TOUPPER ;入口地址PSEGUPPER ;程序段_TOUPPER:MOVA,R7 ;從R7中取參數(shù) CJNEA,#'a',$+3JCUPPERETCJNEA,#'z'+1,$+3JNCUPPERETCLRACC,5UPPERET:MOVR7,A ;返回值放在R7中RET ;返回到C第40頁,共169頁,2023年,2月20日,星期一2.參數(shù)傳遞規(guī)則表7.6參數(shù)傳遞的寄存器選擇參數(shù)類型charintlong,float一般指針第1個參數(shù)R7R6,R7R4~R7R1,R2,R3第2個參數(shù)R5R4,R5R4~R7R1,R2,R3第3個參數(shù)R3R2,R3無R1,R2,R3第41頁,共169頁,2023年,2月20日,星期一func1(inta)"a"是第一個參數(shù),在R6,R7中傳遞。func2(intb,intc,int*d)"b"是第一個參數(shù),在R6,R7中傳遞;"c"是第二個參數(shù),在R4,R5中傳遞;"d"是第三個參數(shù),在R1,R2,R3中傳遞。func3(longe,longf)"e"是第一個參數(shù),在R4~R7中傳遞;"f"是第二個參數(shù),不能在寄存器中傳遞,只能在參數(shù)傳遞段中傳遞。func4(floatg,charh)"g"是第一個參數(shù),在R4~R7中傳遞;"h"是第二個參數(shù),必須在參數(shù)傳遞段中傳遞。第42頁,共169頁,2023年,2月20日,星期一表7.7函數(shù)返回值的寄存器返回值寄存器說明bitC進位標位(unsigned)charR7
(unsigned)intR6,R7高位字節(jié)在R6,低位字節(jié)在R7(unsigned)longR4~R7高位字節(jié)在R4,低位字節(jié)在R7floatR4~R732位IEEE格式,指數(shù)和符號位在R7指針R1,R2,R3R3放存儲器類型,高位在R2,低位在R1第43頁,共169頁,2023年,2月20日,星期一在匯編子程序中,當(dāng)前選擇的寄存器組及寄存器ACC、B、DPTR和PSW都可能改變。當(dāng)被C調(diào)用時,必須無條件地假設(shè)這些寄存器的內(nèi)容已被破壞。如果已在連接/定位程序時選擇了覆蓋,那么每個匯編子程序包含一個單獨的程序段是必要的,因為在覆蓋過程中,函數(shù)間參量通過子程序各自的段參量計算。匯編子程序的數(shù)據(jù)區(qū)甚至可包含在覆蓋部分中,但應(yīng)注意下面兩點:(1)所有段名必須以C51類似的方法建立。(2)每個有局部變量的匯編程序必須指定自己的數(shù)據(jù)段,這個數(shù)據(jù)段只能為其它函數(shù)訪問作參數(shù)傳遞用。所有參數(shù)一個接一個被傳遞,由其它函數(shù)計算的結(jié)果保存入棧。第44頁,共169頁,2023年,2月20日,星期一7.8.2覆蓋和共享1.覆蓋單片機片內(nèi)存儲空間有限,連接器/定位器通常重新啟用程序不再用的位置。這就是說,若一個程序不再調(diào)用,也不由其它程序調(diào)用(甚至間接調(diào)用),那么在其它程序執(zhí)行完之前,這個程序不再運行。這個程序的變量可以放在與其它程序完全相同的RAM空間,很像可重用的寄存器。這種技術(shù)就是覆蓋。在匯編中直接通過手工完成的這些空間分配,C語言中可以由連接器自動管理。若有幾個不相關(guān)聯(lián)的程序時,它可以使RAM單元比手工考慮要用的少。第45頁,共169頁,2023年,2月20日,星期一2.共享1)共享變量類型匯編語言C語言動態(tài)變量
y(){intx;}靜態(tài)變量
staticintx;公用變量PUBLICXX:ds2Intx;外部變量EXTERNDATA(X)MOVDPTR,#Xexternintx;靜態(tài)子程序/函數(shù)Y:…staticy(){…};公共子程序/函數(shù)PUBLICYY:y(){…};外部子程序/函數(shù)EXTERNCODE(Y)LCALLYy()第46頁,共169頁,2023年,2月20日,星期一2)共享函數(shù)/子程序C中函數(shù)若是全局的(公用的),可以放在調(diào)用的函數(shù)之后。若函數(shù)是模塊專用的,它可以定義為靜態(tài)函數(shù),這樣它不能被其它模塊調(diào)用。C語言的ANSI標準建議所有函數(shù)在主函數(shù)前要有原型(進行說明),然后實際函數(shù)可在主函數(shù)之后或其它模塊中。這符合自頂向下編程的概念。匯編語言中,子程序使用標號可在給定模塊的任何位置。匯編器首先掃描得到所有的符號名,然后值就可填入LCALL或LJMP。一個模塊或另一模塊共享子程序,一個使用PUBLIC而另一個使用EXTERN。當(dāng)指定為EXTERN,符號類型(CODE,DATA,XDATA,IDATA,BIT或NUMBER)必須特別加以指定,以便連接器可以確定放在一起的正確類型。第47頁,共169頁,2023年,2月20日,星期一7.8.3庫和連接器/定位器1.庫表7.9FranklinC51的編譯庫庫說明C51S.LIBSMALL模式,無浮點運算C51FPS.LIB浮點數(shù)學(xué)運算庫(SMALL模式)C51C.LIBCOMPACT模式,無浮點運算C51FPC.LIB浮點運算庫(COMPACT模式)C51L.LIBLARGE模式,無浮點運算C51FPL.LIB浮點運算庫(LARGE模式)第48頁,共169頁,2023年,2月20日,星期一2.連接器/定位器1)組合程序模塊將幾個不同程序模塊組合為一個模塊,并自動從庫中挑選模塊嵌入目標文件。輸入文件按命令行中出現(xiàn)的順序處理。通常的程序模塊是由C51編譯器或A51宏匯編生成的可重入的目標文件。第49頁,共169頁,2023年,2月20日,星期一2)組合段將具有相同段名的可重定位段組合成單一的段。在一個程序模塊中定義的一個段成為部分段。一個部分段在源文件中以下列形式指定:(1)名字每個重定位段有一個名字,它可與來自其它模塊的同名的可重定位段組合。絕對段沒有名字。(2)類型類型表明段所屬的地址空間CODE,XDATA,DATA或BIT。第50頁,共169頁,2023年,2月20日,星期一(3)定位方式可重定位段的定位方式有PAGE,INPAGE,INBLOCK,BITADDRESSABLE或UNIT。INPAGE表明段必須放入一頁(高8位地址相同)中以使用短轉(zhuǎn)移和調(diào)用指令。INBLOCK段應(yīng)使用ACALL,必須放在2048字節(jié)塊中。因為沒有連接器可以靈活地判知調(diào)用和轉(zhuǎn)移是否在塊內(nèi)??芍囟ㄎ坏钠渌拗剖牵翰荒艹^256字節(jié);BITADDRESSABLE--必須放在可位尋址的內(nèi)部RAM空間;UNIT--允許段從任意字節(jié)開始(對位變量是位)。(4)長度一個段的長度。第51頁,共169頁,2023年,2月20日,星期一(5)基址段的首址。對于絕對段,地址由匯編器賦予,對于可重定位段,地址由L51決定。在處理程序模塊時,L51自動產(chǎn)生段表(MAP),該表包含了每個段的類型、基址、長度、可重定位性和名字。L51自動將所具有相同名字的所有部分段組合到單一可重定位段中。例如,三個程序模塊包含字段VAR,在組合時,三個段的長度相加,從而組合段的長度也增加了。對組合段有下列規(guī)則:①所有具有相同名的部分段必須有相同類型(CODE,DATA,IDATA,XDATA或BIT)。②組合段的長度不能超過存儲區(qū)的物理長度。③每個組合的部分段的定位方法也必須相同。④絕對段相互不組合,它們被直接拷貝到輸出文件。第52頁,共169頁,2023年,2月20日,星期一3)存儲器分配物理存儲區(qū)最大長度地址區(qū)段類型程序64KB0~0FFFFHCODE外部數(shù)據(jù)64KB0~0FFFFHXDATA直接尋址片內(nèi)數(shù)據(jù)128字節(jié)0~7FHDATA間接尋址片內(nèi)數(shù)據(jù)256字節(jié)0~0FFHIDATA片內(nèi)數(shù)據(jù)的位空間128位0~7FHBIT表7.10MCS-51系列的物理存儲區(qū)第53頁,共169頁,2023年,2月20日,星期一4)采用覆蓋技術(shù)使用數(shù)據(jù)存儲器通過采用一定的覆蓋技術(shù),MCS-51系列少量的片內(nèi)數(shù)據(jù)存儲器可由L51有效地使用。由C51編譯器或是A51匯編器生成的參數(shù)和局部變量(若使用它們的函數(shù)不相互調(diào)用)可在存儲器中覆蓋。這樣,所用的存儲器得到相當(dāng)程度地減少。為完成數(shù)據(jù)覆蓋,L51分析所有不同函數(shù)間的調(diào)用,使用該信息可以確定哪個數(shù)據(jù)和位段可被覆蓋。使用控制參數(shù)OVERLAY和NOOVERLAY可允許或禁止覆蓋。OVERLAY是默認值,用它可產(chǎn)生非常緊湊的數(shù)據(jù)區(qū)。第54頁,共169頁,2023年,2月20日,星期一5)決定外部參考地址具有相同名的外部符號(EXTERN)和公用符號(PUBLIC)被確定后,外部符號指向其它模塊中的地址。一個已聲明的外部符號用具有相同名字的功用符號確定,外部參考地址由其公共參考地址確定。這還與類型(DATA,IDATA,XDATA,CODE,BIT或NUMBER)有關(guān),如果類型不符或未發(fā)現(xiàn)外部符號參考地址的公用符號,則會產(chǎn)生錯誤。公用符號的絕對地址在段定位后決定。第55頁,共169頁,2023年,2月20日,星期一6)絕對地址計算定義絕對地址并計算可重定位段的地址。在段分配和外部公用參考地址處理完后,程序模塊中所有可重定位地址和外部地址要進行計算,此時生成的目標文件中的符號信息(DEBUG)被改變以反映新的值。第56頁,共169頁,2023年,2月20日,星期一7)產(chǎn)生絕對目標文件可執(zhí)行程序以絕對目標格式產(chǎn)生。該絕對目標文件可包含附加的符號信息(DEBUG),從而使符號調(diào)試成為可能。符號信息可用參數(shù)NODEBUGSYMBOLS,NODEBUGPUBLICS和NODEBUGLINES禁止。輸出文件是可執(zhí)行的,并可由仿真器裝入調(diào)試或被OHS51翻譯為IntelHEX格式文件以供EPROM固化。第57頁,共169頁,2023年,2月20日,星期一8)產(chǎn)生映像文件產(chǎn)生一個反映每個處理步驟的映像文件,它顯示有關(guān)連接/定位過程的信息和程序符號,并包含一個公用和外部符號的交叉參考報告。映像文件包含下列信息:①文件名和命令行參數(shù)。②模塊的文件名和模塊名。③一個包含段地址、類型、定位方法和名字的存儲器分配表。該表可在命令行中用NOMAP參考禁止。第58頁,共169頁,2023年,2月20日,星期一④段和符號的所有錯誤列表。列表文件末尾顯示出所有出錯的原因。⑤一個包含輸入文件中符號信息的符號表。該信息由MODULES,SYMBOLS,PUBLICS和LINES名組成,LINES是C編譯器產(chǎn)生的行號。符號信息可用參數(shù)NOSYMBOLS,NOPUBLICS和NOLINES完全或部分禁止。⑥一個按字母順序排列的有關(guān)所有PUBLIC和EXTERN符號的交叉參考報告,其中顯示出符號類型和模塊名。第一個顯示的模塊名是定義了PUBLIC符號的模塊,后面的模塊名是定義了EXTERN符號的模塊。在命令行輸入?yún)?shù)IXREF可產(chǎn)生此報告。⑦在連接器/定位器運行期間檢測到的錯誤同時顯示在屏幕和文件尾部。第59頁,共169頁,2023年,2月20日,星期一7.8.4程序優(yōu)化以下選擇對提高程序效率有很大影響:(1)盡量選擇小存儲模式以避免使用MOVX指令。(2)使用大模式(COMPACT/LARGE)應(yīng)仔細考慮要放在內(nèi)部數(shù)據(jù)存儲器的變量要求是經(jīng)常用的或是用于中間結(jié)果的。訪問內(nèi)部數(shù)據(jù)存儲器要比訪問外部數(shù)據(jù)存儲器快得多。內(nèi)部RAM由寄存器組、位數(shù)據(jù)區(qū)和其它用戶用“data”類型定義的變量共享。由于內(nèi)部RAM容量的限制(128~256字節(jié),由使用的單片機決定),必須權(quán)衡利弊以解決訪問效率和這些對象的數(shù)量之間的矛盾。第60頁,共169頁,2023年,2月20日,星期一(3)要考慮操作順序,完成一件事后再做一件事。(4)注意程序編寫細則。例如,若使用for(;;)循環(huán),DJNZ指令比CJNE指令更有效,可減少重復(fù)循環(huán)次數(shù)。(5)若編譯器不能使用左移和右移完成乘除法,應(yīng)立即修改,例如,左移為乘2。(6)用邏輯AND/&取模比用MOD/%操作更有效。(7)因計算機基于二進制,仔細選擇數(shù)據(jù)存儲器和數(shù)組大小可節(jié)省操作。第61頁,共169頁,2023年,2月20日,星期一(8)盡可能使用最小的數(shù)據(jù)類型,MCS-51系列是8位機,顯然對具有"char"類型的對象的操作比"int"或"long"類型的對象的操作要方便得多。(9)盡可能使用"unsigned"數(shù)據(jù)類型。MCS-51系列CPU并不直接支持有符號數(shù)的運算。因而C51編譯器必須產(chǎn)生與之相關(guān)的更多的程序代碼以解決這個問題。(10)盡可能使用局部函數(shù)變量。編譯器總是嘗試在寄存器里保持局部變量。這樣,將循環(huán)變量(如for和while循環(huán)中的計數(shù)變量)說明為局部變量是最好的。使用"unsignedchar/int"的對象通常能獲得最好的結(jié)果。第62頁,共169頁,2023年,2月20日,星期一7.9MCS-51內(nèi)部資源使用的C語言編程7.9.1中斷應(yīng)用的C語言編程C51編譯器支持在C源程序中直接開發(fā)中斷程序。中斷服務(wù)程序是通過按規(guī)定語法格式定義的一個函數(shù)。中斷服務(wù)程序的函數(shù)定義的語法格式如下:返回值函數(shù)名([參數(shù)])interruptm[usingn]{
}…第63頁,共169頁,2023年,2月20日,星期一表7.11MCS-51中斷源編號編號中斷源入口地址0外部中斷00003H1定時器/計數(shù)器0000BH2外部中斷10013H3定時器/計數(shù)器1001BH4串行口中斷0023H第64頁,共169頁,2023年,2月20日,星期一
usingn選項用于實現(xiàn)工作寄存器組的切換,n是中斷服務(wù)子程序中選用的工作寄存器組號(0~3)。在許多情況下,響應(yīng)中斷時需保護有關(guān)現(xiàn)場信息,以便中斷返回后,能使中斷前的源程序從斷點處繼續(xù)正確地執(zhí)行下去。這在MCS-51單片機中,能很方便地利用工作寄存器組的切換來實現(xiàn)。即在進入中斷服務(wù)程序前的程序中使用一組工作寄存器,進入中斷服務(wù)程序后,由"usingn"切換到另一組寄存器,中斷返回后又恢復(fù)到原寄存器組。這樣互相切換的兩組寄存器中的內(nèi)容彼此都沒有被破壞。第65頁,共169頁,2023年,2月20日,星期一圖7.5擴展多個中斷源例3圖7.5所示是利用優(yōu)先權(quán)解碼芯片,在單片機8031的一個外部中斷INT1上擴展多個中斷源的原理電路圖。圖中是以開關(guān)閉合來模擬中斷請求信號。當(dāng)有任一中斷源產(chǎn)生中斷請求,能給8031的INT1引腳送一個有效中斷信號,由P1的低3位可得對應(yīng)中斷源的中斷號。第66頁,共169頁,2023年,2月20日,星期一在中斷服務(wù)程序中僅設(shè)置標志,并保存I/O口輸入狀態(tài)。FranklinC51編譯器提供定義特定MCS-51系列成員的寄存器頭文件。MCS-51頭文件為reg51.h。C51程序如下:#include<reg51.h>unsignedcharstatus;bitflag;voidservice_int1()interrupt2using2 /*INT1中斷服務(wù)程序,使用第2組工 作寄存器*/{flag=1; /*設(shè)置標志*/status=p1; /*存輸入口狀態(tài)*/}voidmain(void){IP=0x04; /*置INT1為高優(yōu)先級中斷*/IE=-0x84; /*INT1開中斷,CPU開中斷*/第67頁,共169頁,2023年,2月20日,星期一for(;;){if(flag) /*有中斷*/{switch(status) /*根據(jù)中斷源分支*/{case0:break; /*處理IN0*/case1:break; /*處理IN1*/case2:break; /*處理IN2*/case3:break; /*處理IN3*/default:;}flag=0; /*處理完成清標志*/}}}第68頁,共169頁,2023年,2月20日,星期一7.9.2定時器/計數(shù)器(T/C)應(yīng)用的C語言編程例4設(shè)單片機的fosc=12MHz晶振,要求在P1.0腳上輸出周期為2ms的方波。周期為2ms的方波要求定時時間隔1ms,每次時間到P1.0取反。機器周期=12/fosc=1μs需計數(shù)次數(shù)=1000/(12/fosc)=1000/1=1000由于計數(shù)器是加1計數(shù),為得到1000個計數(shù)之后的定時器溢出,必須給定時器置初值為-1000(即1000的補數(shù))。第69頁,共169頁,2023年,2月20日,星期一(1)用定時器0的方式1編程,采用查詢方式,程序如下:
#include<reg51.h>sbitP1_0=P1^0;voidmain(void){TMOD=0x01; /*設(shè)置定時器1為非門控制方式1*/TR0=1; /*啟動T/C0*/for(;;){TH0=-(1000/256); /*裝載計數(shù)器初值*/TL0=-(1000%256);do{}while(!TF0); /*查詢等待TF0置位*/P1_0=!P1_0; /*定時時間到P1.0反相*/TF0=0; /*軟件清TF0*/}}第70頁,共169頁,2023年,2月20日,星期一(2)用定時器0的方式1編程,采用中斷方式。程序如下:#include<reg51.h>sbitP1_0=P1^0;voidtime(void)interrupt1using1/*T/C0中斷服務(wù)程序入口*/{P1_0=!P1_0; /*P1.0取反*/TH0=-(1000/256); /*重新裝載計數(shù)初值*/}voidmain(void){TMOD=0x01; /*T/C0工作在定時器非門控制方式1*/P1_0=0;TH0=-(1000/256); /*預(yù)置計數(shù)初值*/TL0=-(1000%256);EA=1; /*CPU中斷開放*/ET0=1; /*T/C0中斷開放*/TR0=1; /*啟動T/C0開始定時*/do{}while(1); /*等待中斷*/}第71頁,共169頁,2023年,2月20日,星期一例5采用10MHz晶振,在P1.0腳上輸出周期為2.5s,占空比20%的脈沖信號。10MHz晶振,使用定時器最大定時幾十毫秒。取10ms定時,周期2.5s需250次中斷,占空比20%,高電平應(yīng)為50次中斷。10ms定時,晶振fosc=10MHz。需定時器計數(shù)次數(shù)=10×103×10/12=8333#include<reg51.h>#defineucharunsignedcharucharperiod=250;ucharhigh=50;第72頁,共169頁,2023年,2月20日,星期一timer0()interrupt1using1 /*T/C0中斷服務(wù)程序*/{TH0=-8333/256; /*重置計數(shù)值*/TL0=-8333%256;if(++time==high)P1=0; /*高電平時間到變低*/elseif(time==period) /*周期時間到變高*/{time=0;P1=1;}}第73頁,共169頁,2023年,2月20日,星期一main(){TMOD=0x01; /*定時器0方式1*/TH0=-8333/256; /*預(yù)置計數(shù)初值*/TL0=-8333%256;EA=1; /*開CPU中斷*/ET0=1; /*開T/C0中斷*/TR0=1; /*啟動T/C0*/do{}while(1);}第74頁,共169頁,2023年,2月20日,星期一圖7.6中斷服務(wù)程序流程圖第75頁,共169頁,2023年,2月20日,星期一產(chǎn)生一個占空比變化脈沖信號的程序,它產(chǎn)生的脈寬調(diào)制信號用于電機變速控制。#include<reg51.h>#defineucharunsignedchar#defineuintunsignedintunchartime,status,percent,period;bitone_round;uintoldcount,target=500;voidpulse(void)interrupt1using1 /*T/C0中斷服務(wù)程序*/{TH0=-833/256; /*1ms--10MHz*/第76頁,共169頁,2023年,2月20日,星期一TL0=-833%256;ET0=1;if(++time=percent)P1=0;elseif(time==100){time=0;P1=1;}}voidtachmeter(void)interrupt2using2 /*外中斷1服務(wù)程序*/{union{unitword;struct{ucharhi;ucharlo;}byte;}第77頁,共169頁,2023年,2月20日,星期一newcount;newcount.byte.hi=TH1;newcount.byte.lo=TL1;period=newcount.word-oldcount;/*測得周期*/oldcount=newcount.word;one_round=1; /*每轉(zhuǎn)一圈,引起中斷,設(shè)置標志*/}voidmain(void){IP=0x04; /*置INT1為高位優(yōu)先級*/TMOD=0x11; /*T0,T116位方式*/TCON=0x54; /*T0,T1運行,IT1邊沿觸發(fā)*/第78頁,共169頁,2023年,2月20日,星期一TH1=0;TL1=0; /*設(shè)置初始計數(shù)值*/IE=0x86; /*允許中斷EX1,ET0*/for(;;){if(one_round) /*每轉(zhuǎn)一圈,調(diào)整*/{if(period<target){if(percent<100)++percent; /*占空比增*/}elseif(percent>0)--percent; /*占空比減*/one_round=0;}}}第79頁,共169頁,2023年,2月20日,星期一7.9.3串行口使用的C語言編程例6單片機fosc=11.0592MHz,波特率為9600,各設(shè)置32字節(jié)的隊列緩沖區(qū)用于發(fā)送接收。設(shè)計單片機和終端或另一計算機通信的程序。單片機串行口初始化成9600波特,中斷程序雙向處理字符,程序雙向緩沖字符。背景程序可以"放入"和"提取"在緩沖區(qū)的字符串,而實際傳入和傳出SBUF的動作由中斷完成。Loadmsg函數(shù)加載緩沖數(shù)組,標志發(fā)送開始。緩沖區(qū)分發(fā)(t)和收(r)緩沖,緩沖區(qū)通過兩種指示(進in和出out)和一些標志(滿full,空empty,完成done)管理。隊列緩沖區(qū)32字節(jié)接收緩沖(r_buf)區(qū)滿,不能再有字符插入。當(dāng)t_in=t_out,發(fā)送緩沖區(qū)(t_buf)空,發(fā)送中斷清除,停止UART請求。具體程序如下:第80頁,共169頁,2023年,2月20日,星期一#include<reg51.h>#defineucharunsignedcharucharxdatar_buf[32]; /*item1*/ucharxdatat_buf[32];ucharr_in,r_out,t_in,t_done; /*隊列指針*/bitr_full,t_empty,t_done; /*item2*/codeucharm[]={"thisisatestprogram\r\n"};serial()interrupt4using1 /*item3*/{if(RI&&~r_full){r_buf[r_in]=SBUF;RI=0;第81頁,共169頁,2023年,2月20日,星期一r_in=++r_in&ox1f;if(r_in==r_out)r_full=1;}elseif(TI&&~t_empty){SBUF=t_buf[t_out];TI=0;t_out=++t_out&0x1f;if(t_out==t_in)t_empty=1;}elseif(TI){TI=0;t_done=1;}}第82頁,共169頁,2023年,2月20日,星期一voidloadmsg(ucharcode*msg) /*item4*/{while((*msg!=0)&&((((t_in+1)^t_out)&0x1f)!=0)) /*測試緩沖區(qū)滿*/{t_buf[t_in]=*msg;msg++;t_in=++t_in&0x1f;if(t_done){TI=1;t_empty=t_done=0; /*完成重新開始*/}}}第83頁,共169頁,2023年,2月20日,星期一voidprocess(ucharch){return;} /*item5*//*用戶定義*/voidprocessmsg(void) /*item6*/{while(((r_out+1)^r_in)!=0)/*接收非緩沖區(qū)*/{process(r_buf[r_out]);r_out=++r_out&0x1f;}}第84頁,共169頁,2023年,2月20日,星期一main() /*item7*/{TMOD=0x20; /*定時器1方式2*/TH1=0xfd; /*9600波特11.0592MHz*/TCON=0x40; /*啟動定時器1*/SCON=0x50; /*允許接收*/IE=0x90; /*允許串行口中斷*/t_empty=t_done=1;r_full=0;r_out=t_in=0;r_in=1; /*接收緩沖和發(fā)送緩沖置空*/for(;;){loadmsg(&m);processmsg();}}第85頁,共169頁,2023年,2月20日,星期一item1:背景程序"放入"和"提取"字符隊列緩沖區(qū)。item2:緩沖區(qū)狀態(tài)標志。item3:串行口中斷服務(wù)程序,從RI,TI判別接收或發(fā)送中斷,由軟件清除。判別緩沖區(qū)狀態(tài)(滿full,空empty)和全部發(fā)送完成(done)。item4:此函數(shù)把字符串放入發(fā)送緩沖區(qū),準備發(fā)送。item5:接受字符的處理程序,實際應(yīng)用自定義。item6:此函數(shù)逐一處理接收緩沖區(qū)的字符。item7:主程序即背景程序,進行串行口的初始化,載入字符串,處理接收的字符串。第86頁,共169頁,2023年,2月20日,星期一7.10MCS-51片外擴展的C語言編程7.10.18255與8031接口C應(yīng)用程序舉例
例78255控制打印機。圖7.7是8031擴展8255與打印機接口的電路。8255的片選線為P0.7,打印機與8031采用查詢方式交換數(shù)據(jù)。打印機的狀態(tài)信號輸入給PC7,打印機忙時BUSY=1,微型打印機的數(shù)據(jù)輸入采用選通控制,當(dāng)STB上負跳變時數(shù)據(jù)被輸入。8255采用方式0由PC0模擬產(chǎn)生STB信號。按照接口電路,口A地址為7CH,口C地址為7EH,命令口地址為7FH,PC7~PC4輸入,PC3~PC0輸出。方式選擇命令字為8EH。第87頁,共169頁,2023年,2月20日,星期一圖7.78031擴展8255與打印機接口的電路第88頁,共169頁,2023年,2月20日,星期一向打印機輸出字符串"WELCOME"的程序如下:#include<absacc.h>#include<reg51.h>#defineucharunsignedchar#defineCOM8255XBYTE[0x007f] /*命令口地址*/#definePA8255XBYTE[0x007c] /*口A地址*/#definePC8255XBYTE[0x007e] /*口C地址*/voidtoprn(uchar*p) /*打印字符串函數(shù)*/{while(*p!='\0'){while((0x80&PC8255)!=0); /*查詢等待打印機的BUSY狀態(tài)*/第89頁,共169頁,2023年,2月20日,星期一PA8255=*p; /*輸出字符*/COM8255=0x00; /*模擬STB脈沖*/COM8255=0x01;p++;}}voidmain(void){ucharidataprn[]="WELCOME"; /*設(shè)測試用字符串*/COM8255=0x8e; /*輸出方式選擇命令*/toprn(prn); /*打印字符串*/}第90頁,共169頁,2023年,2月20日,星期一例8EPROM編程器。由8031擴展1片EPROM2716、2片SRAM6116及1片8255構(gòu)成EPROM編程器,編程對象是EPROM2732。擴展編程系統(tǒng)中2716用來存放固化用監(jiān)控程序,用戶的待固化程序放在2片6116中。8255的口A作編程器數(shù)據(jù)口,口B輸出2732的低8位地址,PC3~PC0輸出2732高4位地址,PC7作2732啟動保持控制器與PGM連接。譯碼地址為:6116(1):0800H;6116(2):1000H~17FFH;8255的口A:07FCH;口B:07FDH;口C:07FEH;命令口:07FFH。第91頁,共169頁,2023年,2月20日,星期一8255的口A、口B、口C均工作在方式0輸出,方式選擇命令字為80H;2732的啟動編程和停止編程,由PC7的復(fù)位/置位控制,當(dāng)PC7=0時啟動編程,PC7=1時,編程無效。EPROM編程如下所示,參數(shù)為RAM起始地址、EPROM起始地址和編程字節(jié)數(shù)。#include<absacc.h>#include<reg51.h>#defineCOM8255XBYTE[0x07ff]#definePA8255XBYTE[0x07fc]#definePB8255XBYTE[0x07fd]#definePC8255XBYTE[0x07fe]#defineucharunsignedchar#defineuintunsignedint第92頁,共169頁,2023年,2月20日,星期一voidd1_ms(unitx);voidprogram(ram,eprom,con)ucharxdata*ram; /*RAM起始地址*/uinteprom,con; /*EPROM起始固化地址,固化長度*/{inti;COM8255=0x08; /*送方式選擇命令字*/COM8255=0x0f; /*PC7=1*/for(i=0;i<con;i++){PA8255=*ram;
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《腔鏡技術(shù)簡介》課件
- 四下營養(yǎng)午餐教學(xué)設(shè)計及評課
- 新質(zhì)生產(chǎn)力造紙
- 新質(zhì)生產(chǎn)力與物流
- 韋格納肉芽腫性鞏膜炎的臨床護理
- 人教版九年級化學(xué)上冊《二氧化碳制取的研究》思維導(dǎo)圖課件
- 2025年家裝工程合同范本
- 沈陽英語三年級試卷及答案
- 山東聊城中考試卷及答案
- 2025果園土地承包經(jīng)營權(quán)轉(zhuǎn)讓合同范本
- PTIO和ABTS自由基清除實驗操作指南-李熙燦-曾婧媛
- PCI患者的術(shù)后護理課件
- 2024年供應(yīng)鏈可持續(xù)性培訓(xùn)資料
- 丁麗娟《數(shù)值計算方法》五章課后實驗題答案(源程序很詳細-且運行無誤)
- WS-T 10001-2023 疾病預(yù)防控制機構(gòu)實驗室儀器設(shè)備配置和管理
- 成人住院患者跌倒評估與預(yù)防(團體標準)解讀
- 通止規(guī)設(shè)計公差自動計算表
- 靜設(shè)備安裝質(zhì)量控制過程
- 橋梁亮化施工流程圖
- 深基坑巡視記錄
- 現(xiàn)代偵察監(jiān)視技術(shù)講課教案
評論
0/150
提交評論