版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
《基于MSP430單片機(jī)原理及應(yīng)用》第二章MSP430單片機(jī)指令系統(tǒng)與程序設(shè)計(jì)目錄2.1尋址模式2.2匯編指令系統(tǒng)2.3C語言程序設(shè)計(jì)2.4MSP430C語言擴(kuò)展特性2.5MSP430開發(fā)工具簡介2.6CCSv5.5軟件開發(fā)環(huán)境目錄2.1尋址模式2.1.1寄存器尋址模式2.1.2變址尋址模式2.1.3符號尋址模式
2.1.4絕對尋址模式2.1.5寄存器間接尋址模式2.1.6間接增量尋址模式
2.1.7立即數(shù)尋址模式尋址模式MSP430支持7種源操作數(shù)尋址模式和4種目的操作數(shù)尋址模式,如表所示。本節(jié)將對每一種模式進(jìn)行簡單介紹。模式源操作數(shù)目的操作數(shù)描述寄存器尋址XX一個(gè)時(shí)鐘周期變址尋址XX表處理符號尋址XX容易閱讀代碼,PC相關(guān)絕對尋址XX直接訪問任意存儲單元寄存器間接尋址X
使用指針訪問內(nèi)存自增間接尋址X
表處理立即數(shù)尋址X
不限常量值表2-1MSP430尋址模式描述寄存器尋址模式可以直接操作通用寄存器(R4~R15)或特殊功能寄存器,如程序計(jì)數(shù)器或狀態(tài)寄存器。就指令速度和代碼空間而言,這種模式很高效。描述:寄存器內(nèi)容是操作數(shù)源模式位:As=00(操作碼定義源寄存器)語法:Rn長度:一個(gè)或兩個(gè)字注釋:源或目的均有效例:編源程序ROM中的內(nèi)容MOVR10,R11MOVR10,11操作:將R10的內(nèi)容移動(dòng)到R11中。執(zhí)行前執(zhí)行后R10123HR10123HR110FA00HR11123HPCPC_oldPCPC_old+2寄存器尋址模式變址尋址模式適合查表類應(yīng)用,其構(gòu)成是X(Rn),其中X是常量,Rn是CPU寄存器。絕對地址是X+Rn。描述:(X+Rn)指出操作數(shù)地址。X存儲在緊鄰的字中源模式位:As=01(操作碼后緊鄰的字定義了存儲單元地址)目的模式位:Ad=1(操作碼后緊鄰的字定義了存儲單元地址)語法:X(Rn)長度:兩個(gè)或三個(gè)字注釋:源和目的均有效例:匯編源程序ROM中的內(nèi)容MOV2(R5),3(R6)MOVX(R5),Y(R6)X=2Y=3操作:將地址為(R5)+2的存儲單元內(nèi)容移動(dòng)到地址為(R6)+3的存儲單元中。執(zhí)行前執(zhí)行后R501080HR501080HR60108CHR60108CH內(nèi)存單元01082H1234H內(nèi)存單元01082H1234H內(nèi)存單元01090H5678H內(nèi)存單元01090H1234H變址尋址模式符號尋址模式可以給固定的存儲單元添加標(biāo)簽,適用于嵌入式程序的開發(fā)。描述(PC+X)指出操作數(shù),X存儲在下一個(gè)字中。使用變址尋址表示是X(PC)源模式位:As=01(操作碼后緊鄰的字定義了存儲單元地址)目的模式位:Ad=1(操作碼后緊鄰的字定義了存儲單元地址)語法:ADDR長度:兩個(gè)或三個(gè)字注釋:源和目的均有效例:匯編源程序ROM中的內(nèi)容MOVEDE,TON1MOVX(PC),Y(PC)X=EDE-PCY=TON1-PC
操作:將地址為EDE的單元內(nèi)容移動(dòng)到地址為TON1的單元中。其中EDE=PC+X,TON1=PC+Y。執(zhí)行前執(zhí)行后內(nèi)存單元01234H67H內(nèi)存單元01234H67H內(nèi)存單元02345H8BC0H內(nèi)存單元02345H67H符號尋址模式絕對尋址模式與符號尋址相似,區(qū)別是其標(biāo)簽前有“&”。描述:指令后字中包含絕對地址,X存儲在下一個(gè)字中,使用變址尋址表示是X(SR)源模式位:As=01(操作碼后緊鄰的字定義了存儲單元地址)目的模式位:Ad=1(操作碼后緊鄰的字定義了存儲單元地址)語法:&ADDR長度:兩個(gè)或三個(gè)字注釋:源和目的均有效例:匯編源程序ROM中的內(nèi)容MOV&EDE,&TON1MOVX(0),Y(0)X=EDEY=TON1操作:將地址為EDE的內(nèi)容移動(dòng)到地址為TON1中。如果EDE=1234H,TON1=2345H,則:執(zhí)行前執(zhí)行后內(nèi)存單元01234H67H內(nèi)存單元01234H67H內(nèi)存單元02345H8BC0H內(nèi)存單元02345H67H絕對尋址模式數(shù)據(jù)字存儲單元地址由Rn指出,寄存器間接尋址模式不適用于目的操作數(shù),但可通過變址尋址格式0(Rn)模擬。描述:Rn用來指出操作數(shù)源模式位:As=10語法:&Rn長度:一個(gè)或兩個(gè)字注釋:僅適用于源操作數(shù),目的操作數(shù)替代是0(Rn)例:匯編源程序ROM中的內(nèi)容
MOV@R10,0(R11)MOV@(R10),0(R11)操作:將地址為R10的單元中內(nèi)容移動(dòng)到地址為R11的單元中。R10和R11本身的值在執(zhí)行前后不變。執(zhí)行前執(zhí)行后R100123HR100123HR110FA00HR110FA00H內(nèi)存單元0123H1234H內(nèi)存單元0123H1234H內(nèi)存單元0FA00H5678H內(nèi)存單元0FA00H1234H寄存器間接尋址模式數(shù)據(jù)字存儲單元地址由Rn指出,寄存器間接尋址模式不適用于目的操作數(shù),但可通過變址尋址格式0(Rn)模擬。描述:Rn用來指出操作數(shù)源模式位:As=10語法:&Rn長度:一個(gè)或兩個(gè)字注釋:僅適用于源操作數(shù),目的操作數(shù)替代是0(Rn)例:匯編源程序ROM中的內(nèi)容
MOV@R10,0(R11)MOV@(R10),0(R11)操作:將地址為R10的單元中內(nèi)容移動(dòng)到地址為R11的單元中。R10和R11本身的值在執(zhí)行前后不變。執(zhí)行前執(zhí)行后R100123HR100123HR110FA00HR110FA00H內(nèi)存單元0123H1234H內(nèi)存單元0123H1234H內(nèi)存單元0FA00H5678H內(nèi)存單元0FA00H1234H寄存器間接尋址模式間接增量尋址模式同寄存器間接尋址相似,但間接增量尋址模式中操作數(shù)是指令中數(shù)字的自增值。操作數(shù)格式是@Rn+,這種模式適用于數(shù)據(jù)塊處理。間接增量尋址模式與寄存器間接尋址相似,但指令執(zhí)行完成后,源操作數(shù)自動(dòng)增加一個(gè)字節(jié)或一個(gè)字。描述:Rn用來指出操作數(shù),字節(jié)指令中Rn自增1而字指令中Rn自增2源模式位:As=11語法:@Rn+長度:一個(gè)或兩個(gè)字注釋:僅適用于源操作數(shù),目的操作數(shù)替代是0(Rn)加上第二條指令I(lǐng)NCDRn例:匯編源程序ROM中的內(nèi)容
MOV@R10+,0(R11)MOV@(R10)+,0(R11)操作:將地址為R10的單元中內(nèi)容移動(dòng)到地址為R11的單元中。執(zhí)行后R10內(nèi)容變?yōu)镽10+2,R11本身的值在執(zhí)行前后不變。執(zhí)行前執(zhí)行后R100123HR100125HR110FA00HR110FA00H內(nèi)存單元0123H1234H內(nèi)存單元0123H1234H內(nèi)存單元0FA00H5678H內(nèi)存單元0FA00H1234H間接增量尋址模式立即數(shù)尋址模式用來將常量值賦給寄存器或內(nèi)存單元。描述:指令后的字中包含立即數(shù)常量N,
使用自增間接尋址表示是@PC+源模式位:As=11語法:#N長度:兩個(gè)或三個(gè)字,如果常量CG1或CG2可用就少一個(gè)字注釋:僅適用于源操作數(shù)例:MOV#23H,TON1;將常數(shù)23移動(dòng)到目的地址TON1中。立即數(shù)尋址模式目錄2.2匯編指令系統(tǒng)2.2.1雙操作數(shù)指令2.2.2單操作數(shù)指令2.2.3程序流控制--跳轉(zhuǎn)2.2.4仿真指令MS430指令集包括27種內(nèi)核指令,還支持24種仿真指令。CPU將內(nèi)核指令解碼成唯一的操作碼,匯編器和編譯器用來生成仿真指令的助記符。有3種內(nèi)核指令格式:雙操作數(shù),單操作數(shù)和程序流控制—跳轉(zhuǎn)。可使用“B”,“W”和“.A”擴(kuò)展來訪問字節(jié),字和地址指令。如果沒有擴(kuò)展,就把指令解釋為字指令。匯編指令系統(tǒng)雙操作數(shù)指令雙操作數(shù)指令格式如下:1514131211109876543210opcodeS-RegAdB/WAsD-Reg位
簡介15~12opcode操作碼11~8S-Reg工作寄存器用于存儲操作數(shù)(src)7Ad負(fù)責(zé)尋址模式的尋址位,用于表示目標(biāo)操作數(shù)(dst)6B/WByte或Word操作:B/W=0,Word操作;B/W=1,Byte操作5~4As負(fù)責(zé)尋址模式的尋址位,用于表示源操作數(shù)(src)3~0D-Reg工作寄存器用于存儲目的操作數(shù)(dst)雙操作數(shù)指令助記符操作簡介算術(shù)指令A(yù)DD(.Bor.w)src,dstsrc+dst->dst源操作數(shù)加到目的操作數(shù)ADDC(.Bor.w)src,dstsrc+dst+C->dst源操作數(shù)和進(jìn)位加到目的操作數(shù)DADD(.Bor.w)src,dstsrc+dst+C->dst(dec)源操作數(shù)和進(jìn)位用十進(jìn)制加到目的操作數(shù)SUB(.Bor.w)src,dstdst+.not.src+1->dst從目的操作數(shù)減去源操作數(shù)SUBC(.Bor.w)src,dstdst+.not.src+C->dst從目的操作數(shù)減去源操作數(shù)和進(jìn)位邏輯和寄存器控制指令A(yù)ND(.Bor.w)src,dstsrc.and.dst->dst源操作數(shù)與目的操作數(shù)進(jìn)行與運(yùn)算BIC(.Bor.w)src,dst.not.src.and.dst->dst清除目的操作數(shù)對應(yīng)的比特位BIS(.Bor.w)src,dstsrc.or.dst->dst設(shè)置目的操作數(shù)位BIT(.Bor.w)src,dstsrc.and.dst測試目的操作數(shù)位XOR(.Bor.w)src,dstsrc.xor.dst->dst源操作數(shù)與目的操作數(shù)進(jìn)行異或運(yùn)算數(shù)據(jù)指令CMP(.Bor.w)src,dstdst-src源操作數(shù)與目的操作數(shù)進(jìn)行比較MOV(.Bor.w)src,dstsrc->dst源操作數(shù)移動(dòng)到目的操作數(shù)表2-2雙操作數(shù)內(nèi)核指令單操作數(shù)指令單操作數(shù)指令格式如下:1514131211109876543210opcodeB/WAdD/S-Reg位
簡介15~7opcode操作碼6B/WByte或Word操作:B/W=0,Word操作;B/W=1,Byte操作5~4Ad負(fù)責(zé)尋址模式的尋址位,用于表示源操作數(shù)(src)3~0D/S-Reg工作寄存器用于存儲目的操作數(shù)(dst)或源操作數(shù)(src)單操作數(shù)指令助記符操作簡介邏輯和寄存器控制指令RRA(.Bor.w)dstMSB->MSB->…LSB->C目的操作數(shù)右移RRC(.Bor.w)dstc->MSB->…LSB->C目的操作數(shù)帶進(jìn)位右移SWPB(.Bor.w)dstSwapbytes目的操作數(shù)進(jìn)行字節(jié)交換SXTdstbit7->bit8…bit15目的操作數(shù)符號擴(kuò)展PUSH(.Bor.w)srcSP-2->SP,src->@sp源操作數(shù)壓入棧程序流控制指令CALL(.Bor.w)dstSP-2->SP,PC+2->@SPdst->PC子程序調(diào)用目的地址RETITOS->SR,SP+2->SPTOS->PC,SP+2->SP中斷返回表2-4單操作數(shù)內(nèi)核指令程序流控制--跳轉(zhuǎn)跳轉(zhuǎn)指令格式如下:位
簡介15~13opcode操作碼12~10C
9~0PCoffsetPCnew=PCold+2+PCoffset×21514131211109876543210opcodeC10bitPCoffset程序流控制--跳轉(zhuǎn)助記符簡介程序流控制指令JEQ/JZlabel零標(biāo)志置位就跳轉(zhuǎn)到標(biāo)簽處JNE/JNZlabel零標(biāo)志不置位就跳轉(zhuǎn)到標(biāo)簽處JClabel進(jìn)位標(biāo)志置位就跳轉(zhuǎn)到標(biāo)簽處JNClabel進(jìn)位標(biāo)志不置位就跳轉(zhuǎn)到標(biāo)簽處JNlabel求反標(biāo)志置位就跳轉(zhuǎn)到標(biāo)簽處JGElabel大于或等于就跳轉(zhuǎn)到標(biāo)簽處JLlabel小于就跳轉(zhuǎn)到便簽處JMPlabel無條件跳轉(zhuǎn)表2-6程序流控制指令(跳轉(zhuǎn))目錄2.3C語言程序設(shè)計(jì)2.3.1標(biāo)示符與關(guān)鍵字2.3.2數(shù)據(jù)類型2.3.3運(yùn)算符2.3.4函數(shù)2.3.5數(shù)組2.3.6指針2.3.7位運(yùn)算2.3.8存儲寄存器2.3.9預(yù)處理2.3.10程序的基本結(jié)構(gòu)C語言程序設(shè)計(jì)MSP430程序設(shè)計(jì)除了可以使用匯編語言外,還可以采用C語言編程。使用C語言進(jìn)行程序設(shè)計(jì)是當(dāng)今單片機(jī)系統(tǒng)開發(fā)和應(yīng)用的主流,這主要有兩個(gè)方面的因素:一方面是隨著芯片工業(yè)的快速發(fā)展,單片機(jī)能夠以較低的成本提供較快的預(yù)算速度和更多的存儲空間;另外一方面,現(xiàn)在的單片機(jī)系統(tǒng)處理的任務(wù)越來越復(fù)雜,產(chǎn)品更新的周期也越來越短,這也對開發(fā)的進(jìn)度提出了較高的要求。在這種情況下,使用匯編程序設(shè)計(jì)已經(jīng)不能滿足要求,C語言由于其可移植性好、硬件控制能力強(qiáng)、表達(dá)和運(yùn)算能力強(qiáng)的特點(diǎn),能夠充分地發(fā)揮單片機(jī)的豐富功能,提高軟件的開發(fā)效率,增強(qiáng)其可讀性和可移植性。MSP430單片機(jī)使用的一套應(yīng)用C語言的集成開發(fā)環(huán)境和調(diào)試器是由IAR公司提供的。MSP430C語言與標(biāo)準(zhǔn)C語言的不同之處,主要表現(xiàn)在以下幾個(gè)方面:C語言程序設(shè)計(jì)外圍模塊變量外圍模塊變量也被稱作特殊功能寄存器變量,其直接位于內(nèi)部的RAM中。sfrb:用于定義地址范圍為0x00~0xFF的片內(nèi)外圍模塊的功能寄存器以及特殊功能寄存器。例如,P1端口的輸入寄存器地址為0x0020,則可定義為:sfrbP1IN=0x20sfrw:用于定義地址范圍為0x100~0x1FF的片內(nèi)外模塊的功能寄存器。例如,ADC12模塊的控制寄存器的地址為0x01A2,則sfrwADC12CTL1=0x1A2
指針變量MSP430C語言的指針變量包括代碼指針和數(shù)據(jù)指針,都可以指向0000H~0FFFFH范圍的存儲空間。 枚舉類型用enum關(guān)鍵字,可以使聲明的每一個(gè)變量具有適合它的值所需的最短整數(shù)類型,包括char、short、int或long。 浮點(diǎn)類型在標(biāo)準(zhǔn)IEEE格式中,浮點(diǎn)使用4字節(jié)數(shù)來表示。低于最小極限的浮點(diǎn)數(shù)被看作零而溢出。標(biāo)示符與關(guān)鍵字(1)標(biāo)示符標(biāo)示符用來定義變量、函數(shù)、標(biāo)號以及用戶定義對象的名稱。標(biāo)示符由字母和數(shù)字組成,但第一個(gè)字符必須是字母或下劃線。C語言中大、小寫字母被認(rèn)為是不同的字符。如:at、AT、At就是3種不同的標(biāo)示符。標(biāo)示符與保留的關(guān)鍵字都不能與庫函數(shù)名和自定義的函數(shù)名相同。(2)關(guān)鍵字關(guān)鍵字是一種已經(jīng)被編譯器定義過的標(biāo)示符,具有特定的定義,因此也稱作保留字,意思是不可以再被用戶定義了。
另外,針對不同的微處理器,還有一些擴(kuò)展的關(guān)鍵字,擴(kuò)展關(guān)鍵字將在后續(xù)章節(jié)中介紹。數(shù)據(jù)類型數(shù)據(jù)類型有基本型、構(gòu)造型、指針型。(1)基本型 基本型數(shù)據(jù)類型如表2-10所示。數(shù)據(jù)類型位數(shù)范圍char8bit0~255signedchar8bit-128~127unsignedchar8bit0~255short16bit-32768~32767unsignedshort16bit0~65535int16bit-32768~32767unsignedint16bit0~65535long32bit-231~231-1unsignedlong16bit0~232-1longlong64bit-263~263-1unsignedlonglong64bit0~264-1float32bit±1.18E-38~±3.39E+38Double*32bit±1.18E-38~±3.39E+38Double*64bit±2.23E-308~±1.79E+308表2-10基本型數(shù)據(jù)類型*依賴編譯器數(shù)據(jù)類型(2)構(gòu)造型構(gòu)造型是由基本數(shù)據(jù)類型組成的集合體。有數(shù)組、結(jié)構(gòu)、聯(lián)合、枚舉4種形式。在對單片機(jī)的編程中,使用的最多的是數(shù)組。枚舉用于定義一組常量,增加程序的可讀性。由于包含結(jié)構(gòu)的程序運(yùn)行效率低,因此結(jié)構(gòu)很少使用。聯(lián)合的應(yīng)用范圍有限,所以也很少用到。 數(shù)組數(shù)組是同一種數(shù)據(jù)類型的集合體,如unsignedcharDa[5],表示5個(gè)unsignedchar類型的數(shù)據(jù)組成了Moon數(shù)組。使用時(shí)通過下標(biāo)來存取數(shù)組中的數(shù)據(jù),如Da[2]=100的含義為為數(shù)組Da中的第三個(gè)元素賦值100。數(shù)組的第一個(gè)元素的下標(biāo)為0,Da[0]為第一個(gè)元素。按照數(shù)組Da的定義,數(shù)組Da只有5個(gè)元素,所以,其后一個(gè)元素為Da[4]。數(shù)據(jù)類型 結(jié)構(gòu)結(jié)構(gòu)是可以有多種數(shù)據(jù)類型組成的混合數(shù)據(jù)集合體。使用時(shí)首先定義結(jié)構(gòu)類型,如:structMoon{unsignedcharData,//無符號8位字符類型unsignedintYear//無符號16位整數(shù)類型};以上代碼定義了結(jié)構(gòu)類型Moon,其中Data和Year的數(shù)據(jù)類型。struct為定義結(jié)構(gòu)的關(guān)鍵字。使用結(jié)構(gòu)類型時(shí)首先定義結(jié)構(gòu)變量。如:StructMoonMo;//定義結(jié)構(gòu)體變量Mo為Moon類型存取結(jié)構(gòu)變量時(shí),通過結(jié)構(gòu)類型中的變量名來進(jìn)行,結(jié)構(gòu)變量的名稱和結(jié)構(gòu)中的變量名中間用“.”隔開,如:Mo.Data=15;//Mo中的Data元素被賦值為15Mo.Year=3;//Mo中的Year元素被賦值為3數(shù)據(jù)類型 聯(lián)合聯(lián)合是可以有多種數(shù)據(jù)類型組成的混合數(shù)據(jù)集合體。聯(lián)合與結(jié)構(gòu)的區(qū)別在于放置在內(nèi)存中的數(shù)據(jù)的存放方式不同。結(jié)構(gòu)中的每個(gè)成員是順序存放的,都擁有自己的內(nèi)存單元,結(jié)構(gòu)所占用的內(nèi)存長度為所有成員占用內(nèi)存長度的和。聯(lián)合的內(nèi)存長度為占用內(nèi)存最多的成員的長度,所有的成員都放在同一內(nèi)存地址,每次只能存放成員中的一種,而且有效的只能是最后一次放置的成員。使用時(shí)首先定義聯(lián)合類型,如:UnionYear{unsignedcharda0;//無符號8位字符類型unsignedintda1;//無符號16位整數(shù)類型};代碼中定義了聯(lián)合類型Year,其中da0和da1的數(shù)據(jù)類型不同。Union為定義聯(lián)合的關(guān)鍵字。使用聯(lián)合類型是首先定義聯(lián)合變量。如:UnionYearYe;//定義聯(lián)合變量Ye為Year類型存取聯(lián)合變量時(shí),通過聯(lián)合類型中的變量名來進(jìn)行,聯(lián)合變量的名稱和聯(lián)合中的變量名中間用“.”隔開,如:Ye.da0=15;//Ye中的da0元素被賦值為15Ye.da1=3;//Ye中的da1元素被賦值為3數(shù)據(jù)類型 枚舉枚舉就是列舉一個(gè)變量所有的取值。這樣做的好處是增加程序的可讀性。舉例:menuweek{Mon,Tues,Wed,Thurs,F(xiàn)ri,Sta,Sun}編譯器按照順序?yàn)樗鼈內(nèi)≈?,Mon=0,Tues=1......Sun=6。也可以強(qiáng)制定義枚舉的取值。舉例:menuweek{Mon,Tues=5,Wed,Thurs,F(xiàn)ri,Sta,Sun}程序運(yùn)行的結(jié)果為:Mon=0,Tues=5,Wed=6,Thurs=7......數(shù)據(jù)類型(3)指針型指針型用來存儲地址,也可以是變量的地址,也可以是函數(shù)的地址。指針的應(yīng)用非常靈活,能夠提高程序的效率。舉例:unsignedcharSun;unsignedchar*Moon=Sun;Moon中存放了變量Sun的地址。運(yùn)算符運(yùn)算符是進(jìn)行基本運(yùn)算的符號。(1)賦值運(yùn)算符賦值運(yùn)算符為“=”,作用是把等號右邊的值賦給等號左邊的變量舉例:Moon=100;變量Moon的值為100。除了“=”,還有復(fù)合賦值運(yùn)算符:+=、—=、*=、/=、%=、<<=、>>=、&=、|=、~=。舉例:q0+=5;//q0=q0+5 q0—=5;//q0=q0-5q0*=5;//q0=q0*5 q0/=5;//q0=q0/5q0%=5;//q0=q0%5 q0<<5;//q0=q0<<5q0>>=5;//q0=q0>>5 q0&=5;//q0=q0&5q0|=5;//q0=q0|5 q0~=5;//q0=q0~5運(yùn)算符(2)算術(shù)運(yùn)算符算術(shù)運(yùn)算符有+、—、*、%、——、++、——,下面分別加以解釋:+加法運(yùn)算—減法運(yùn)算*乘法運(yùn)算/除法運(yùn)算,結(jié)果只保留整數(shù),小數(shù)部分被舍去。%取余運(yùn)算,要求兩個(gè)運(yùn)算對象都為整數(shù),如9%8,結(jié)果為1。++增量運(yùn)算,自加1。例如Moon++等價(jià)于Moon=Moon+1。——減量運(yùn)算,自減1。例如Moon——等于Moon=Moon—1。(3)關(guān)系運(yùn)算符關(guān)系運(yùn)算符用于判別兩個(gè)值之間的關(guān)系,判別的結(jié)果只有真和假兩種結(jié)果。判別結(jié)果如果為真,則表示為1,判別結(jié)果為假則表示為0。關(guān)系運(yùn)算符有以下幾種:>大于 >=大于等于<小于 <=小與等于==等于 !=不等于運(yùn)算符(4)邏輯運(yùn)算符常用的邏輯運(yùn)算符有以下幾種:&&邏輯與,相與的兩個(gè)表達(dá)式同時(shí)為真,則輸出為真,否則輸出假|(zhì)|邏輯或,相或的兩個(gè)表達(dá)式同時(shí)為假,則輸出假,否則輸出真!邏輯非。表達(dá)式為真,則輸出假,否則輸出真。(5)位運(yùn)算符按位運(yùn)算符應(yīng)用于字節(jié)對字節(jié),或者字對字的操作,不能應(yīng)用于float、double、void和結(jié)構(gòu)類型。位運(yùn)算符有以下幾種:&按位與
〡按位或~按位取反>>位右移<<位左移(6)地址運(yùn)算符地址運(yùn)算符與指針有密切關(guān)系。地址運(yùn)算符有以下幾種:&取地址運(yùn)算符*取值運(yùn)算符舉例:unsignedchar*Moon,Day=10,See;Moon=&Day;//指針Moon中保存了變量Day的地址,*Moon的值為10See=*Moon;//變量See取得了Moon中保存的地址中所保存的值,See=10運(yùn)算符(7)條件運(yùn)算符條件運(yùn)算符的一般表達(dá)式為:表達(dá)式1?表達(dá)式2:表達(dá)式3運(yùn)算的含義是:先判斷表達(dá)式1的值,如果是真,則把表達(dá)式2的值作為運(yùn)算結(jié)果,否則把表達(dá)式3的值作為運(yùn)算結(jié)果。(8)逗號運(yùn)算符逗號運(yùn)算符把幾個(gè)表達(dá)式串在一起,各表達(dá)式從左往右運(yùn)算,最后一個(gè)表達(dá)式的結(jié)果作為最終的運(yùn)算結(jié)果。舉例:Moon=(Day=10,Year=5,Day+Year);運(yùn)算結(jié)果為Moon=15。運(yùn)算符(9)強(qiáng)制轉(zhuǎn)換運(yùn)算符算術(shù)運(yùn)算中不同的數(shù)據(jù)類型不可避免地會(huì)進(jìn)行混合運(yùn)算,編譯器要求不同的數(shù)據(jù)類型必須轉(zhuǎn)換為同一種數(shù)據(jù)類型才能夠進(jìn)行運(yùn)算,所以運(yùn)算時(shí)不同類型的數(shù)據(jù)必須轉(zhuǎn)換為同一數(shù)據(jù)類型。有兩種數(shù)據(jù)轉(zhuǎn)換類型方式:隱式轉(zhuǎn)換和顯式轉(zhuǎn)換。隱式轉(zhuǎn)換是在沒有進(jìn)行強(qiáng)制轉(zhuǎn)換時(shí)由編譯器進(jìn)行的自動(dòng)類型轉(zhuǎn)換。轉(zhuǎn)換遵循以下規(guī)則
所有char類型轉(zhuǎn)換成int型。 運(yùn)算符兩邊的兩個(gè)不同的數(shù)據(jù)類型的操作數(shù)按照以下規(guī)則轉(zhuǎn)換:如果一個(gè)操作數(shù)float型,則另外一個(gè)也轉(zhuǎn)換成float型;如果一個(gè)操作數(shù)long型,則另外一個(gè)也轉(zhuǎn)換成long型;如果一個(gè)操作數(shù)unsigned型,則另外一個(gè)也轉(zhuǎn)換成unsigned型; 對變量賦值時(shí),將“=”右邊表達(dá)式的類型換成“=”左邊變量的數(shù)據(jù)類型。例如:把整型(16位)的數(shù)據(jù)賦給字符型(8位)的變量,整型數(shù)據(jù)的高8位會(huì)丟失。把浮點(diǎn)型的數(shù)據(jù)賦給整型變量,小數(shù)部分會(huì)丟失。 能夠進(jìn)行隱式轉(zhuǎn)換的只有基本數(shù)據(jù)類型,即char、int、long、float。其余的數(shù)據(jù)類型不能進(jìn)行隱式轉(zhuǎn)換。運(yùn)算符如果需要將某種數(shù)據(jù)類型轉(zhuǎn)換成另一種特定的數(shù)據(jù)類型,就要進(jìn)行強(qiáng)制類型轉(zhuǎn)換,即顯式轉(zhuǎn)換。例如,從數(shù)據(jù)存儲器中的某個(gè)地址通過指針讀出數(shù)據(jù),表示地址的變量是整數(shù),可以通過強(qiáng)制類型轉(zhuǎn)換把地址變量轉(zhuǎn)換成指針變量。強(qiáng)制轉(zhuǎn)換運(yùn)算符的一般形式是:
(數(shù)據(jù)類型)表達(dá)式括號中的數(shù)據(jù)類型是要轉(zhuǎn)換成為的數(shù)據(jù)類型。強(qiáng)制轉(zhuǎn)換并不改變變量原來的數(shù)據(jù)類型,只是輸出一個(gè)之間的具有新數(shù)據(jù)類型的值。如:floatfday;unsignedintMoon;Moon=(unsignedint)fday;fday的數(shù)據(jù)類型不會(huì)改變,仍然是浮點(diǎn)數(shù)據(jù)類型,Moon的值為fday的整數(shù)部分,前提是fday的整數(shù)部分的值不能大于整數(shù)類型的數(shù)據(jù)范圍65535,否則結(jié)果仍然不正確。當(dāng)多個(gè)運(yùn)算符出現(xiàn)在一個(gè)表達(dá)式中時(shí),運(yùn)算符的先后次序按照運(yùn)算符的優(yōu)先級來進(jìn)行。函數(shù)函數(shù)是具有一定功能的程序模塊,一個(gè)用C語言編寫程序?qū)嶋H上就是由多個(gè)函數(shù)組成。函數(shù)的一般形式是:返回值數(shù)據(jù)類型函數(shù)名(參數(shù)數(shù)據(jù)類型形式參數(shù),…,參數(shù)數(shù)據(jù)類型形式參數(shù)){
變量說明語句返回值}舉例:intaddit(intx,inty)//函數(shù)定義,x,y為形參
{intz;z=x+y;returnz;}voidmain(){inta=10,b=30,c;c=addit(a,b);//函數(shù)的調(diào)用,a,b為實(shí)參}函數(shù)函數(shù)必須先定義,然后才可以調(diào)用。在定義函數(shù)時(shí)聲明的參數(shù)叫做“形式參數(shù)”,簡稱形參。在調(diào)用函數(shù)時(shí),被調(diào)用函數(shù)的參數(shù)成為“實(shí)際參數(shù)”,簡稱實(shí)參。實(shí)參必須與形參的類型保持一致。函數(shù)的參數(shù)傳遞方式分為值傳遞和地址傳遞。當(dāng)參數(shù)是基本類型變量時(shí),主調(diào)函數(shù)傳遞給被調(diào)函數(shù)參數(shù)值的過程,就是為被調(diào)函數(shù)重新分配內(nèi)存,將參數(shù)的值復(fù)制到內(nèi)存中。函數(shù)執(zhí)行過程中對參數(shù)的任何修改都不會(huì)改變主調(diào)函數(shù)中原來的值。函數(shù)調(diào)用結(jié)束時(shí),函數(shù)分配的空間被釋放,復(fù)制的參數(shù)也就不存在了。地址傳遞時(shí),主調(diào)函數(shù)同樣傳遞參數(shù)的值給被調(diào)函數(shù)。不過由于參數(shù)是指向某個(gè)內(nèi)存的地址,此內(nèi)存不是函數(shù)調(diào)用時(shí)分配的,因此也不會(huì)在函數(shù)結(jié)束時(shí)釋放。所以,被調(diào)函數(shù)對此地址指向的內(nèi)存的數(shù)值進(jìn)行的修改在函數(shù)結(jié)束后仍然有效。如果定義的函數(shù)沒有參數(shù),可以沒有形式參數(shù)表,但圓括號不能省略。返回值數(shù)據(jù)類型定義了函數(shù)結(jié)束時(shí)返回(return)的值的數(shù)據(jù)類型。如果沒有返回值,那么最后可以沒有return語句。對應(yīng)的返回值數(shù)據(jù)類型要為void。
Main函數(shù)是程序的起點(diǎn),是C語言的規(guī)定。用戶所編寫的程序是從main的第一行開始執(zhí)行的。數(shù)組數(shù)組是由同一數(shù)據(jù)類型組成的集合體。數(shù)組在使用前必須先聲明,聲明的一般形式為:數(shù)據(jù)類型數(shù)組名[常量表達(dá)式]數(shù)據(jù)類型說明了數(shù)組中的各個(gè)元素的類型。數(shù)組名代表整個(gè)數(shù)組。常量表達(dá)式說明了數(shù)組中元素的個(gè)數(shù)。舉例:unsignedcharMoon[5];以上代碼的含義名字叫作Moon的數(shù)組中保存了5個(gè)元素,元素的數(shù)據(jù)類型為unsignedchar。使用數(shù)組的方法是通過下標(biāo)確定元素,規(guī)定數(shù)組的下標(biāo)從0開始。如上例中Moon[0]代表數(shù)組Moon的第一個(gè)元素,Moon[4]代表最后一個(gè)即第5個(gè)元素。數(shù)組可以是多維的,只要在聲明數(shù)組時(shí)增加[常量表達(dá)式]就可以了。如Moon[5][6]代表一個(gè)5行6列的矩陣。數(shù)組在聲明的時(shí)候可以賦初值,也可以不賦值。舉例:unsignedcharMoon[5]={0,1,2,3,4};以上代碼表示Moon中的5個(gè)元素都被賦了初值。指針指針特點(diǎn)是靈活、高效。指針表示的是一個(gè)地址,保存指針的變量稱為指針變量。指針變量的一般形式為:數(shù)據(jù)類型*指針變量名;舉例:unsignedintiq0=0;//聲明一個(gè)無符號整數(shù)變量iq0且賦值為0unsignedcharMoon0=5;//聲明一個(gè)無符號字符變量Moon0且賦值為5unsignedintMoon1=500;//聲明一個(gè)無符號整數(shù)變量Moon1切賦值為500unsignedchar*pq0;//聲明一個(gè)無符號字符的指針變量pq0unsignedint*piq0;//聲明一個(gè)無符號整數(shù)指針變量piq0pq0=&Moon0;//pq0指向變量Moon0,即取得了Moon0的地址piq0=&Moon1;//piq0指向變量Moon1,即取得了Moon1的地址iq0=*pq0;//iq0的值不再是0,而是5iq0=*piq0;//iq0的值不再是5,而是500*pq0=100;//Moon的值不再是5,而是100*piq0=0;//Moon1的值不再是500,而是0這個(gè)例子使用了前面提到的地址運(yùn)算符*和&。指針可以進(jìn)行幾種基本運(yùn)算,以上例的指針為例:pq0++;//指針+1,由于是unsignedchar類型指針,所以,pq0內(nèi)的值+1piq0++;//指針+1,由于是unsignedint類型指針,所以,piq0內(nèi)的值+2(*pq0)++;//pq0所指的變量的值+1*(pq0+1);//pq0內(nèi)的值+1,然后再取pq0所指變量的值指針可以用指針對數(shù)組進(jìn)行操作:unsignedcharMoon[5];unsignedchar*pq0=Moon;//指針指向數(shù)組MoonC語言規(guī)定數(shù)組的名字為數(shù)組第一個(gè)元素的地址,上例中下列幾種情況左邊表達(dá)式與右邊表達(dá)式的值是等價(jià)的。pq0Moon*pq0Moon[0]*(pq0+1)Moon[1]也可以直接獲取數(shù)組某個(gè)元素的地址,賦給指針:pq0=&Moon[4];//pq0的值是Moon[4]的地址pq0--;//pq0的值是Moon[3]的地址指向數(shù)組的指針可以超出數(shù)組的邊界進(jìn)行運(yùn)算,而編譯器不會(huì)提出警告。這需要非常小心,因?yàn)橛锌赡芷茐某绦蛑衅渌糠炙褂玫淖兞炕蛘咦x取到錯(cuò)誤的值,造成程序運(yùn)行混亂。這是使用指針不利的一面。指針同樣也可以對結(jié)構(gòu)和聯(lián)合進(jìn)行操作。操作方法與數(shù)組類似。舉例:structli//定義結(jié)構(gòu)li{unsignedcharka;floatdae;};structlisst,*psst;//聲明結(jié)構(gòu)li的實(shí)例sst和結(jié)構(gòu)li類型的指針psstpsst=&sst;//psst指向sst(*psst).ka=100;//為結(jié)構(gòu)體sst中的變量ka賦值100psst->ka=100;//為結(jié)構(gòu)體sst中的變量ka賦值100(*psst).ka=100與psst->ka=100的含義完全相同。“->”的含義為通過指針獲取結(jié)構(gòu)中的變量。數(shù)組和結(jié)構(gòu)、聯(lián)合的成員也可以是指針。位運(yùn)算位運(yùn)算通過位運(yùn)算符進(jìn)行。舉例:unsignedcharq0=0x35,q1=0x47;q0=q0<<3;//q0的值左移3位q1=q1>>5;//q1的值右移5位執(zhí)行結(jié)果為:q0=0x1A8q1=0x2有些處理器寄存器中的每一位也有其位地址,所以可以對寄存器中的位單獨(dú)操作,如MCS51系列微處理器。MSP430沒有位地址,所以,只能采取位屏蔽的方法對寄存器中某一位進(jìn)行操作,而避免改變同一寄存器中其他位的內(nèi)容。如:P1DIR=P1DIR|0x1;P1OUT=P1OUT&0XFE;P1DIR為MSP430的P1口的方向寄存器,P1OUT為P1口的輸出寄存器。以上代碼中第一行語句將P1口的最低位(一共8位)輸入輸出方向改為輸出,其他位方向不變。第二行語句是將最低位輸出0,其他位不變。存儲寄存器變量和函數(shù)都有其有效區(qū)域,稱為作用域。程序如果使用范圍之外的變量和函數(shù),則編譯會(huì)出錯(cuò)。(1)變量變量包括局部變量、全局變量、外部變量、靜態(tài)變量。局部變量在函數(shù)內(nèi)部定義的變量稱為局部變量,它只在函數(shù)內(nèi)有效,退出函數(shù)時(shí)所分分配的內(nèi)存將被釋放。全局變量在程序開始執(zhí)行的時(shí)候就被分配了內(nèi)存,一直保持到程序結(jié)束,可以被任何模塊調(diào)用。在函數(shù)之外定義的變量為全局變量。外部變量在其他文件中定義但在本文件中使用的變量,稱為外部變量,用extern標(biāo)識。靜態(tài)變量壽命相當(dāng)于全局變量,但只允許在定義的函數(shù)內(nèi)使用的變量稱為靜態(tài)變量,靜態(tài)變量在退出定義的函數(shù)時(shí),其值仍然存在,直至下一次進(jìn)入定義它的函數(shù)中,執(zhí)行程序?qū)λM(jìn)行修改。變量的聲明形式為:作用域類型數(shù)據(jù)類型變量名;舉例:externintMoon;存儲寄存器(2)函數(shù)函數(shù)的存儲類型有static和extern兩種。聲明形式為:作用域類型返回?cái)?shù)據(jù)類型函數(shù)名(參數(shù)名)聲明為static的函數(shù)稱為內(nèi)部函數(shù)或者靜態(tài)函數(shù)。靜態(tài)函數(shù)只能在定義此函數(shù)的文件中被調(diào)用,而不能被其他文件的函數(shù)調(diào)用。extern稱為外部函數(shù)。除非被聲明為靜態(tài)函數(shù),函數(shù)都可以在其他文件中被調(diào)用。編譯器函數(shù)默認(rèn)為外部函數(shù),因此,extern通常可以忽略。類型作用域和壽命說明auto局部變量變量默認(rèn)類型為autoregister局部變量、只是提示編譯器將此變量分配在CPU的寄存器中寄存器中變量的使用速度比較快,但寄存器個(gè)數(shù)有限,最終還是由編譯器決定是否為變量分配寄存器extern全局變量外部變量static全局變量靜態(tài)變量表2-12變量作用域預(yù)處理編譯器在編譯過程之前先進(jìn)行預(yù)處理。預(yù)處理包括宏文件、條件編譯和文件包含。(1)宏定義宏定義的命令為#define。如:
#defineCAR100
以上代碼的含義是定義CAR為100,執(zhí)行預(yù)處理時(shí)編譯器將有效范圍內(nèi)所有的CAR替換成100。這樣做的好處是增加程序的可讀性和可維護(hù)性。也可以使用帶參數(shù)的宏,例如:
#defineSUM(x,y)(x+y)Moon=SUM(1,2)*2;
以上宏定義在預(yù)處理時(shí)會(huì)將SUM(1,2)替換成(1+2),成為:
Moon=(1+2)*2;
注意括號的重要性,如果宏寫為:
#defineSUM(x,y)x+y
則替換的結(jié)果為:
Moon=1+2*2;
即使運(yùn)算的順序發(fā)生了變化,結(jié)果也會(huì)不同。預(yù)處理(1)條件編譯由于某些原因,編譯時(shí)會(huì)想要得到不同的結(jié)果。比如某一系列的產(chǎn)品所使用的程序,絕大部分都是相同的,只是由于型號不同需要在某處根據(jù)不同的型號做不同的處理,因此就需要條件編譯,由編譯器根據(jù)所選的型號(條件編譯的條件)自動(dòng)選擇所需要的程序段。條件編譯器的命令有#if、#ifdef、#ifndef、#endif。格式1:
#ifdef標(biāo)識符程序段1#else
程序段2#endif判斷是否定義了標(biāo)識符,如果定義了標(biāo)識符,則選擇程序段1編譯,忽略程序段2;否則選擇程序段2,忽略程序段1。預(yù)處理格式2:#ifndef標(biāo)識符程序段1;#else
程序段2;#endif判斷是否定義了標(biāo)識符,如果定義了標(biāo)識符,則選擇程序段1編譯,忽略程序段2;否則選擇程序段2,忽略程序段1。格式3:#if常量表達(dá)式1
程序段1#elif常量表達(dá)式2
程序段2。。。#else
程序段n#endif以上格式的代碼順序判斷哪一個(gè)常量表達(dá)式為真,并編譯相應(yīng)的程序段,忽略其他的程序段。預(yù)處理(2)文件包含由于各種原因,不會(huì)將一個(gè)程序的所有部分都放置在一個(gè)文件中。另外,C語言和編譯也定義了很多常量、數(shù)據(jù)結(jié)構(gòu)以及函數(shù)。編譯器在編譯時(shí)必須要知道一個(gè)文件中的程序使用到的這些內(nèi)容在什么文件中作出了定義,一般編寫每一個(gè)c文件(程序文件以.c為后綴)都會(huì)編寫一個(gè)頭文件(.h為后綴),c文件中用到的常量、數(shù)據(jù)結(jié)構(gòu)、函數(shù)都在頭文件中聲明。需要調(diào)用此c文件的內(nèi)容的文件只需要用#include***.h>或者#include“***.h”語句調(diào)用就可以了。<>與“”的作用一樣,不過習(xí)慣上在包含編譯器定義的庫時(shí)用<>,包含用戶自己定義的文件時(shí)用“”。在頭文件中,往往還會(huì)看到一種宏指令,如在msp430x14x.h中有:#ifndef__msp430x14x#define__msp430x14x…#endif其中msp430x14x是這個(gè)頭文件的文件名,含義是如果未定義__msp430x14x,則定義__msp430x14x,并編譯隨后的內(nèi)容。以后編譯器遇到其他的文件也包含此頭文件時(shí),由于__msp430x14x已經(jīng)被定義過了,不符合#ifndef__msp430x14x條件,所以不會(huì)再次編譯頭文件的內(nèi)容。它的作用是防止同一個(gè)頭文件被重復(fù)包含,從而避免頭文件中的內(nèi)容重復(fù)定義。編譯器會(huì)對重復(fù)定義提出警告或者報(bào)錯(cuò)。程序的基本結(jié)構(gòu)程序有4種基本的結(jié)構(gòu):順序結(jié)構(gòu)、選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)和跳轉(zhuǎn)結(jié)構(gòu)。(1)順序結(jié)構(gòu)在順序結(jié)構(gòu)中語句依次順序執(zhí)行。順序結(jié)構(gòu)是程序的基本結(jié)構(gòu)。(2)選擇結(jié)構(gòu)選擇結(jié)構(gòu)由判斷和分支兩部分組成,選擇結(jié)構(gòu)有兩種:if結(jié)構(gòu)和switch結(jié)構(gòu)。if有3種形式,如果表達(dá)式為真則執(zhí)行程序段,否則跳過程序段執(zhí)行本選擇結(jié)構(gòu)之后的程序,形式為:if(表達(dá)式){
程序段}如果表達(dá)式為真則執(zhí)行程序段1,否則執(zhí)行程序段2,形式為:if(表達(dá)式){
程序段1}else{
程序段2}程序的基本結(jié)構(gòu)如果表達(dá)式1為真則執(zhí)行程序段1,然后執(zhí)行本選擇結(jié)構(gòu)之后的程序;如果表達(dá)式2為真,則執(zhí)行程序段2,然后執(zhí)行本結(jié)構(gòu)之后的程序。如此依次判斷表達(dá)式是否為真,如果為真則執(zhí)行相應(yīng)的程序段,然后執(zhí)行本結(jié)構(gòu)后的程序,形式為:if(表達(dá)式1){
程序段1}elseif(表達(dá)式2){
程序段2}…else{
程序段n}程序的基本結(jié)構(gòu)計(jì)算表達(dá)式的值,判斷與哪一個(gè)常量相等,則執(zhí)行哪一段程序,然后執(zhí)行本結(jié)構(gòu)后的程序。如果沒有一個(gè)值與表達(dá)式相等,則執(zhí)行程序段default。break指令的含義為跳出選擇體,如果省去,則在執(zhí)行完某程序段后就不會(huì)跳出來,而是繼續(xù)進(jìn)行下面的判斷。在多個(gè)不同的常量都使表達(dá)式執(zhí)行同一段程序時(shí)可以寫為:case常量1:case常量2;程序段break;形式為:switch(表達(dá)式){case常量1:程序段1break;case常量2:程序段2break;…default:
程序段default}程序的基本結(jié)構(gòu)(3)循環(huán)結(jié)構(gòu)for形式為:for(初值設(shè)定表達(dá)式;循環(huán)條件表達(dá)式;更新表達(dá)式){
程序段}執(zhí)行過程如圖2-1所示圖2-1for循環(huán)程序的基本結(jié)構(gòu)while形式為:while(條件表達(dá)式){
程序段}執(zhí)行過程如圖2-2所示。Do…while形式為:do{
程序段}while(條件表達(dá)式);執(zhí)行過程如圖2-3所示。圖2-2while循環(huán)圖2-3do…while循環(huán)程序的基本結(jié)構(gòu)(4)跳轉(zhuǎn)goto形式為:goto語句標(biāo)號;語句標(biāo)號是一個(gè)帶冒號“:”的標(biāo)識符。執(zhí)行g(shù)oto語句要將使程序無條件跳轉(zhuǎn)到語句標(biāo)號標(biāo)示的那一句程序。goto語句可以從循環(huán)結(jié)構(gòu)中跳出來,但不能跳入循環(huán)結(jié)構(gòu)。結(jié)構(gòu)化編程不推薦此語句,但在某些情況下,使用它可以使程序表現(xiàn)得更為簡潔。舉例:tt:x=1;…goto:tt;continue形式為:continue;一般用在循環(huán)結(jié)構(gòu)中,功能是忽略循環(huán)結(jié)構(gòu)中本語句之后尚未執(zhí)行的程序,直接進(jìn)入下一個(gè)循環(huán)周期。是否退出循環(huán)仍需由循環(huán)條件來確定。舉例:for(q0=0;q0<100;q0++){if(q1[q0]==50)continue;elseq1[q0]=0}
結(jié)果:依次判斷數(shù)組q1中下標(biāo)從0~99的元素的值,如果值等于50,則忽略(continue),否則這些元素被賦值為0。程序的基本結(jié)構(gòu)break形式為:break;在前面遇到過此語句。break語句一般用在循環(huán)結(jié)構(gòu)中,其作用就是無條件跳出循環(huán)結(jié)構(gòu)。在switch結(jié)構(gòu)中的break即是此含義。return形式為return(表達(dá)式);或:return;return語句的作用為中止函數(shù)的執(zhí)行,程序返回到調(diào)用函數(shù)的位置的下一句執(zhí)行。對于需要返回值的函數(shù)返回一個(gè)值,所以return后要跟表達(dá)式。不需要返回值的函數(shù)使用return即可。目錄2.4MSP430C語言擴(kuò)展特性2.4.1MSP430C語言的擴(kuò)展特性2.4.2MSP430C語言擴(kuò)展關(guān)鍵字2.4.3MSP430#pragma編譯命令2.4.4MSP430的預(yù)定義符號2.4.5MSP430的本征函數(shù)2.4.6MSP430的段定義
MSP430C語言的擴(kuò)展特性MSP430的C語言在標(biāo)準(zhǔn)C語言的基礎(chǔ)上主要在關(guān)鍵字、#pragma編譯命令、預(yù)定義符號、本征函數(shù)及其他擴(kuò)展特性等方面進(jìn)行了擴(kuò)展。下面就各個(gè)部分加以簡要說明。(1)擴(kuò)展關(guān)鍵字在默認(rèn)情況下,MSP430的C語言編譯器遵守C語言規(guī)范,MSP430的C語言擴(kuò)展關(guān)鍵字都不能使用。但是編譯器選項(xiàng)“-e”能使擴(kuò)展關(guān)鍵字可以使用。同時(shí),它們也就不能用作變量名了。擴(kuò)展關(guān)鍵字有以下幾類:
與I/O訪問有關(guān)的關(guān)鍵字:sfrb、sfrw。 非易失RAM關(guān)鍵字:no_init。 函數(shù)類型關(guān)鍵字:interrupt、monitor。
MSP430C語言的擴(kuò)展特性(2)#pragma編譯命令#pragma編譯命令控制編譯器的存儲器分配,控制是否允許用擴(kuò)展關(guān)鍵字,以及是否輸出警告消息。它提供符合標(biāo)準(zhǔn)語法的擴(kuò)展特性。#pragma編譯命令是否可用與“-e”選項(xiàng)無關(guān)。#pragma編譯命令主要分為以下幾類:位域取向#pragmabitfields=default#pragmabitfields=reversed代碼段#pragmacodeseg(段名)擴(kuò)展控制#pragmalanguage=default#pragmalanguage=extended
函數(shù)屬性#pragmafunction=default#pragmafunction=interrupt#pragmafunction=monitor存儲器用法#pragmamemory=default#pragmamemory=constseg#pragmamemory=dataseg#pragmamemory=no_init警告消息控制#pragmawarnings=default#pragmawarnings=off#pragmawarnings=on
MSP430C語言的擴(kuò)展特性(3)預(yù)定義符號的預(yù)定義符號允許檢查編譯時(shí)的環(huán)境,注意它們都用雙下劃線字符表示。_DATE_格式為MMddyyyy格式的當(dāng)前日期_FILE_當(dāng)前源文件名_IAR_SYSTEMS_ICCIARC編譯器的標(biāo)志符_LINE_當(dāng)前源程序行號_STDC_ANSI-C編譯器的標(biāo)識符_TID_目前標(biāo)志符_TIME_格式為hh:mm:ss的當(dāng)前時(shí)間_VER_返回整型版本號(4)本征函數(shù)本征函數(shù)允許對MSP430作底層的控制。為了使它們能在C語言程序中使用,程序文件應(yīng)該包含頭文件(In430.h)。經(jīng)編譯,本征函數(shù)成為內(nèi)嵌代碼,可能是單個(gè)指令,也可能是一段指令序列。關(guān)于本征函數(shù)的功能細(xì)節(jié),可以參看具體的芯片技術(shù)文檔。下面給出一些本征函數(shù)。_args$返回參數(shù)數(shù)組給函數(shù)_argt$返回參數(shù)類型_NOP空操作指令_EINT允許中斷_DINT禁止中斷_BIS_SR對狀態(tài)寄存器中某一位置位_BIC_SR對狀態(tài)寄存器中某一位置位_OPC插入DW常數(shù)說明偽指令
MSP430C語言的擴(kuò)展特性(5)其他擴(kuò)展特性$字符,為了與DEC公司的VMS-C兼容,將$加入到有效字符集中,編譯時(shí)用SIZEOF取消限制,SIZEOF運(yùn)算符不能用在#if和#elif表達(dá)式內(nèi)。
MSP430C語言擴(kuò)展關(guān)鍵字通過前面的概述部分知道MSP430的C語言的擴(kuò)展關(guān)鍵字,下面具體對各個(gè)關(guān)鍵字進(jìn)行介紹(1)interrupt該關(guān)鍵字用于中斷函數(shù)。中斷函數(shù)的定義如下。語法:interruptvoid函數(shù)名()或者interrupt[中斷向量]void函數(shù)名()參數(shù):中斷函數(shù)沒有參數(shù)。中斷函數(shù)可能需要指定中斷向量。返回:中斷函數(shù)一般是void,沒有返回。說明:interrupt關(guān)鍵字聲明了在處理器發(fā)生中斷時(shí)調(diào)用。函數(shù)的參數(shù)必須為空,如果說明了中斷向量,函數(shù)地址將插入該向量;如果未說明中斷向量,用戶必須在向量表中為中斷函數(shù)提供適當(dāng)?shù)娜肟?,最好在cstartup模塊中提供。下面舉例說明:#include<msp430x14x.h>//初始化定時(shí)器模塊voidInit_TimerB(void){TBCTL=TBSSEL0+TBCLR;TBCCTL0=CCIE;TBCCR0=32768;TBCTL|=MC0;//初始化端口P1DIR=0;P1SEL=0;P1DIR|=BIT0;return;}//定時(shí)器中斷interrupt[TIMERB0_VECTOR]voidTimerB_ISR(void){inti;//翻轉(zhuǎn)P1.0管腳if(P1OUT&BIT0)PIOUT&=~(BIT0);elseP1OUT|=BIT0;for(i=100;i>0;i--);}上面的例子說明了interrupt定義的中斷函數(shù)的使用。
MSP430C語言擴(kuò)展關(guān)鍵字(2)monitor該關(guān)鍵字是使函數(shù)進(jìn)入原型(atomic)操作狀態(tài)。語法:monitor函數(shù)類型函數(shù)名(參數(shù)表)參數(shù):該函數(shù)可以有參數(shù),也可以沒有參數(shù)。返回:函數(shù)可以有返回,也可以沒有返回。說明:monitor關(guān)鍵字使得在函數(shù)執(zhí)行期間禁止中斷,使函數(shù)執(zhí)行不可中斷。在其他所有方面,有monitor聲明的函數(shù)與普通函數(shù)相同。下面舉例說明monitor關(guān)鍵字的用法。下面的例子演示在測試標(biāo)志時(shí)禁止中斷。如果標(biāo)志沒有設(shè)置,函數(shù)將設(shè)置,當(dāng)退出函數(shù)時(shí),中斷狀態(tài)恢復(fù)到原先的狀態(tài)。charprint_flag;monitorintGetFlag(charpFlag){if(*pFlag==0){*pFlag=1;}else{*pFlag=0;}return;}voidTest(){if(GetFlag(&print_flag)){……}}上面的例子演示了monitor的用法。
MSP430C語言擴(kuò)展關(guān)鍵字(3)no_init該關(guān)鍵字是非易失變量的類型修正符。語法:no_init變量聲明說明:在默認(rèn)情況下,MSP430的C語言編譯器將變量存放于主RAM中,并在啟動(dòng)時(shí)對其進(jìn)行初始化。no_init類型修正符使編譯器把變量放在非易失RAM區(qū)中(如EEPROM、FLASH等),在啟動(dòng)時(shí)也不對它們作初始化。在no_init變量的聲明中,不能含有初始化。如果用了非易失RAM,連接時(shí)要安排在非易失RAM區(qū),地址范圍為0x0000~0xFFFF,而實(shí)際可用范圍是0x200~0xFFDF。下面舉例說明。no_initintA[20];no_initn;通過上面的例子知道了no_init的使用方法。(4)sfrb該關(guān)鍵字用于聲明單字節(jié)I/O數(shù)據(jù)類型對象。語法:sfrb標(biāo)識符=常數(shù)表達(dá)式說明:sfrb表示一個(gè)I/O寄存器,具有以下特點(diǎn):
它等價(jià)于無符號字符。 它只能直接尋址。 它駐留在地址范圍0x00~0xFF之內(nèi)。下面舉例說明:sfrbP1OUT=0x0021;上面的例子定義了P1口的輸出寄存器。
MSP430C語言擴(kuò)展關(guān)鍵字(5)sfrw該關(guān)鍵字用于聲明雙字節(jié)I/O數(shù)據(jù)類型對象。語法:sfrw標(biāo)識符=常量表達(dá)式說明:sfrw表示一個(gè)I/O寄存器,具有以下特點(diǎn):
它等價(jià)于無符號字符。 它只能直接尋址。 它駐留在地址范圍0x100~0x1FF之內(nèi)。下面舉例說明:sfrwWDTCTL=0x0021;上面的例子定義了看門狗的寄存器。
MSP430#pragma編譯命令#pragma編譯命令是給MSP430的C編譯器的指令,使MSP430的C編器完成特定的編譯功能。下面具體介紹各個(gè)#pragma編譯命令。(1)bitfields=default恢復(fù)默認(rèn)的位域存儲次序。語法:#pragmabitfields=default說明:使編譯器按照正常次序分配位域。(2)bitfields=reversed
翻轉(zhuǎn)位域的存儲次序。語法:#pragmabitfields=reversed說明:使編譯器從域的最高有效位開始分配位域,而非從最低有效位開始。標(biāo)準(zhǔn)C語言允許存儲順序與執(zhí)行相關(guān),用此關(guān)鍵字可避免移植性問題。例如:下列結(jié)構(gòu)類型在存儲器中的默認(rèn)存儲順序如下。struct{shortN0:3;shortN1:5;shortN2:4;shortN3:4;}bits
MSP430#pragma編譯命令實(shí)際結(jié)構(gòu)如圖2-4所示3:4N2:4N1:5N0:3圖2-4默認(rèn)存儲順序#pragmabitfields=reversedstruct{shortN0:3;shortN1:5;shortN2:4;shortN3:4;}bits如圖2-5所示為翻轉(zhuǎn)位域的存儲順序0:3N1:5N2:4N3:4圖2-5翻轉(zhuǎn)存儲順序通過圖2-4和圖2-5的比較可以理解默認(rèn)存儲順序和翻轉(zhuǎn)存儲順序。
MSP430#pragma編譯命令(3)codeseg設(shè)置代碼段名。語法:#pragmacodeseg(段名)其中,段名一定不能與數(shù)據(jù)段發(fā)生沖突。說明:此編譯命令將后續(xù)代碼放在命名的段內(nèi)。它等價(jià)于使用“-e”選項(xiàng)。此編譯命令只能被編譯器執(zhí)行一次。例如:把代碼段定義為ROM。#pragmacodeseg(ROM)(4)function=default將函數(shù)定義恢復(fù)為默認(rèn)類型。語法:#pragmafunction=default說明:取消function=interrupt和function=monitor編譯命令。例如:聲明外部函數(shù)fun1為中斷函數(shù),fun2為普通函數(shù)。#pragmafunction=interruptexternvoidfun1();#pragmafunction=defaultexternvoidfun2();
MSP430#pragma編譯命令(5)function=interrupt將函數(shù)定義為interrupt。語法:#pragmafunction=interrupt 說明:此編譯命令使后續(xù)函數(shù)定義為中斷類型。這是說明函數(shù)屬性為中斷的另一種形式但是該編譯命令不提供矢量選項(xiàng)。例如:下面為中斷函數(shù),函數(shù)的地址必須放入中斷向量表中。#pragmafunction=interrupt voidTimer_ISR(){……}#pragmafunction=default上面的例子演示了中斷函數(shù)的定義。(6)function=monitor將函數(shù)定義為不可中斷(atomic)狀態(tài)。語法:#pragmafunction=monitor說明:使后續(xù)函數(shù)定義為monitor類型,這是說明函數(shù)屬性為monitor的另一種形式。例如:下面函數(shù)執(zhí)行期間,暫時(shí)禁止中斷。#pragmafunction=monitorvoidfun(){……}#pragmafunction=default上面的例子表明在定義完了monitor函數(shù)后需要恢復(fù)函數(shù)為一般屬性,
MSP430#pragma編譯命令(7)language=default將可用的關(guān)鍵字設(shè)置恢復(fù)為默認(rèn)狀態(tài)。語法:#pragmalanguage=default說明:將C編譯器“-e”選項(xiàng)設(shè)置的擴(kuò)展關(guān)鍵字可用狀態(tài)恢復(fù)到默認(rèn)狀態(tài)。(8)language=extended
設(shè)置擴(kuò)展關(guān)鍵字為可用狀態(tài)。語法:#pragmalanguage=extended說明:使擴(kuò)展關(guān)鍵字可用,與C編譯器的“-e”選項(xiàng)無關(guān)。例如:將擴(kuò)展關(guān)鍵字設(shè)置為可用。#pragmalanguage=extendedno_initintuser_info;#pragmalanguage=defaultintflag;上面的例子演示了#pragmalanguage=extended的作用(9)memory=constseg在默認(rèn)情況下,將常量放入所命名的段中。語法:#pragmamemory=constseg(段名)說明:在默認(rèn)情況下,將常數(shù)放入所命名的段中。后續(xù)聲明隱含取得const存儲類??捎藐P(guān)鍵字no_init和const跨越此設(shè)置。另外,段名一定不能是編譯器保留的段名之一。例如:將常量數(shù)組const_a放入ROM段的TABLE中。#pragmamemory=constseg(TABLE)charconst_a[]={1,2,3,4,5,6,7,8,9};#pragmamemory=default上面的例子演示了#pragmamemory=constseg(段名)的使用
MSP430#pragma編譯命令(10)memory=dataseg在默認(rèn)情況下,將變量放入所命名的段中。語法:#pragmamemory=dataseg(段名)說明:在默認(rèn)情況下,將變量放入所命名的段中。可用關(guān)鍵字no_init和const跨越此設(shè)置。如果省略,變量將放入U(xiǎn)DATA0(非初始化變量)或IDATA0(初始化變量)中。在變量定義中不提供初始化值。在模塊中預(yù)備有10個(gè)不同的數(shù)據(jù)段,用戶可以在程序中的任何位置切換到任意一個(gè)已經(jīng)定義的數(shù)據(jù)段。例如:下面將5個(gè)變量放入名為UART的讀/寫區(qū)域。#pragmamemory=dataseg(UART)charTX_LEN;charRX_LEN;charTX_FLAG;charRX_FLAG;intRate;#pragmamemory=default上面的例子演示了#pragmamemory=dataseg(段名)的使用。(11)memory=default將存儲器的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年蘭州資源環(huán)境職業(yè)技術(shù)大學(xué)單招綜合素質(zhì)筆試模擬試題含詳細(xì)答案解析
- 2026年湖南石油化工職業(yè)技術(shù)學(xué)院單招職業(yè)技能考試備考題庫含詳細(xì)答案解析
- 2026年甘肅林業(yè)職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試備考試題及答案詳細(xì)解析
- 2026年寧波衛(wèi)生職業(yè)技術(shù)學(xué)院單招綜合素質(zhì)考試模擬試題含詳細(xì)答案解析
- 2026年閩江師范高等專科學(xué)校單招綜合素質(zhì)考試備考試題含詳細(xì)答案解析
- 2026年鄭州旅游職業(yè)學(xué)院單招綜合素質(zhì)筆試參考題庫含詳細(xì)答案解析
- 2026西藏華勤互聯(lián)科技股份有限公司(人保財(cái)險(xiǎn)色尼支公司)招聘考試參考試題及答案解析
- 2026年河南科技職業(yè)大學(xué)高職單招職業(yè)適應(yīng)性測試備考題庫及答案詳細(xì)解析
- 2026年廣西現(xiàn)代職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試模擬試題及答案詳細(xì)解析
- 2026年上海海洋大學(xué)單招綜合素質(zhì)考試模擬試題含詳細(xì)答案解析
- 《筑牢安全防線 歡度平安寒假》2026年寒假安全教育主題班會(huì)課件
- 2026國家國防科技工業(yè)局所屬事業(yè)單位第一批招聘62人備考題庫及答案詳解(新)
- 信息技術(shù)應(yīng)用創(chuàng)新軟件適配測評技術(shù)規(guī)范
- 2026版安全隱患排查治理
- 道路施工安全管理課件
- (2025年)吉林事業(yè)單位考試真題附答案
- 肉瘤的課件教學(xué)課件
- VTE患者并發(fā)癥預(yù)防與處理
- 車輛救援合同協(xié)議書
- 貴州省遵義市匯川區(qū)2024-2025學(xué)年八年級上學(xué)期12月期末數(shù)學(xué)試題
- 疾病產(chǎn)生分子基礎(chǔ)概論
評論
0/150
提交評論