




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第四章 單片機C語言程序設計4.1 C語言與MCS-51單片機4.1.1 C語言的特點及程序結構一C語言的特點1語言簡潔、緊湊,使用方便、靈活。2運算符豐富。3數據結構豐富。具有現代化語言的各種數據結構。4可進行結構化程序設計。5可以直接對計算機硬件進行操作。6生成的目標代碼質量高,程序執行效率高。7可移植性好。二C語言的程序結構 C語言程序采用函數結構,每個C語言程序由一個或多個函數組成,在這些函數中至少應包含一個主函數main(),也可以包含一個main()函數和假設干個其它的功能函數。不管main()函數放于何處,程序總是從main()函數開始執行,執行到main()函數結束那么結束。在
2、main()函數中調用其它函數,其它函數也可以相互調用,但main()函數只能調用其它的功能函數,而不能被其它的函數所調用。功能函數可以是C語言編譯器提供的庫函數,也可以是由用戶定義的自定義函數。在編制C程序時,程序的開始局部一般是預處理命令、函數說明和變量定義等。 C語言程序結構一般如下:預處理命令 include函數說明 long fun1(); float fun2();int x,y;float z;功能函數主函數功能函數功能函數1 fun1() 函數體 主函數 main() 主函數體 功能函數2 fun2() 函數體 其中,函數往往由“函數定義和“函數體兩個局部組成。函數定義局部包括
3、有函數類型、函數名、形式參數說明等,函數名后面必須跟一個圓括號,形式參數在內定義。函數體由一對花括號“組成,在“的內容就是函數體。如果一個函數內有多個花括號,那么最外層的一對“為函數體的內容。函數體內包含假設干語句,一般由兩局部組成:聲明語句和執行語句。聲明語句用于對函數中用到的變量進行定義。也可能對函數體中調用的函數進行聲明。執行語句由假設干語句組成,用來完成一定功能。當然也有的函數體僅有一對“,其中內部既沒有聲明語句,也沒有執行語句。這種函數稱為空函數。 C語言程序在書寫時格式十分自由,一條語句可以寫成一行,也可以寫成幾行;還可以一行內寫多條語句;但每條語句后面必須以分號“;作為結束符。C
4、語言程序對大小寫字母比較敏感,在程序中,同一個字母的大小寫系統是作不同的處理。在程序中可以用“/*/或“/對C程序中的任何局部作注釋,以增加程序的可讀性。 C語言本身沒有輸入輸出語句。輸入和輸出是通過輸入輸出函數scanf()和printf()來實現的。輸入輸出函數是通過標準庫函數形式提供給用戶。 4.1.2 C語言與MCS-51單片機 用C語言編寫MCS-51單片機程序與用匯編語言編寫MCS51單片機程序不一樣,用匯編語言編寫MCS51單片機程序必須要考慮其存儲器結構,尤其必須考慮其片內數據存儲器與特殊功能存放器的使用以及按實際地址處理端口數據。用C語言編寫的MCS51單片機應用程序,那么不
5、用像匯編語言那樣須具體組織、分配存儲器資源和處理端口數據,但在C語言編程中,對數據類型與變量的定義,必須要與單片機的存儲結構相關聯,否那么編譯器不能正確地映射定位。 用C語言編寫單片機應用程序與標準的C語言程序也有相應的區別:C語言編寫單片機應用程序時,需根據單片機存儲結構及內部資源定義相應的數據類型和變量,而標準的C語言程序不需要考慮這些問題;C51包含的數據類型、變量存儲模式、輸入輸出處理、函數等方面與標準的C語言有一定的區別。其它的語法規那么、程序結構及程序設計方法等與標準的C語言程序設計相同。 現在支持MCS-51系列單片機的C語言編譯器有很多種,如American Automatio
6、n、Avocet、BSO/TASKING、DUNFIELD SHAREWARE、KEIL/Franklin等。各種編譯器的根本情況相同,但具體處理時有一定的區別,其中KEIL/Franklin以它的代碼緊湊和使用方便等特點優于其它編譯器,現在使用特別廣泛。本書以KEIL/Franklin編譯器介紹MCS-51單片機C語言程序設計。4.1.3 C51程序結構C51的語法規定、程序結構及程序設計方法都與標準的C語言程序設計相同,但C51程序與標準的C程序在以下幾個方面不一樣:1C51中定義的庫函數和標準C語言定義的庫函數不同。標準的C語言定義的庫函數是按通用微型計算機來定義的,而C51中的庫函數是
7、按MCS-51單片機相應情況來定義的;2C51中的數據類型與標準C的數據類型也有一定的區別,在C51中還增加了幾種針對MCS-51單片機特有的數據類型;3C51變量的存儲模式與標準C中變量的存儲模式不一樣,C51中變量的存儲模式是與MCS-51單片機的存儲器緊密相關;4C51與標準C的輸入輸出處理不一樣,C51中的輸入輸出是通過MCS-51串行口來完成的,輸入輸出指令執行前必須要對串行口進行初始化;5C51與標準C在函數使用方面也有一定的區別,C51中有專門的中斷函數。4.2 C51的數據類型 C51的數據類型分為根本數據類型和組合數據類型,情況與標準C中的數據類型根本相同,但其中char型與
8、short型相同,float型與double型相同,另外,C51中還有專門針對于MCS-51單片機的特殊功能存放器型和位類型。 一字符型char 有signed char和unsigned char之分,默認為signed char。它們的長度均為一個字節,用于存放一個單字節的數據。對于signed char,它用于定義帶符號字節數據,其字節的最高位為符號位,“0表示正數,“1表示負數,補碼表示,所能表示的數值范圍是-128+127;對于unsigned char,它用于定義無符號字節數據或字符,可以存放一個字節的無符號數,其取值范圍為0255。unsigned char可以用來存放無符號數,
9、也可以存放西文字符,一個西文字符占一個字節,在計算機內部用ASCII碼存放。 二int整型 分singed int和unsigned int。默認為signed int。它們的長度均為兩個字節,用于存放一個雙字節數據。對于signed int,用于存放兩字節帶符號數,補碼表示,數的范疇為-32768+32767。對于unsigned int,用于存放兩字節無符號數,數的范圍為065535。三long長整型 分singed long和unsigned long。默認為signed long。它們的長度均為四個字節,用于存放一個四字節數據。對于signed long,用于存放四字節帶符號數,補碼表
10、示,數的范疇為-2147483648+2147483647。對于unsigned long,用于存放四字節無符號數,數的范圍為04294967295。四float浮點型 float型數據的長度為四個字節,格式符合IEEE-754標準的單精度浮點型數據,包含指數和尾數兩局部,最高位為符號位,“1表示負數,“0表示正數,其次的8位為階碼,最后的23位為尾數的有效數位,由于尾數的整數局部隱含為“1,所以尾數的精度為24位。 五* 指針型 指針型本身就是一個變量,在這個變量中存放的指向另一個數據的地址。這個指針變量要占用一定的內存單元,對不同的處理器其長度不一樣,在C51中它的長度一般為13個字節。六
11、特殊功能存放器型 這是C51擴充的數據類型,用于訪問MCS-51單片機中的特殊功能存放器數據,它分sfr和sfr16兩種類型,其中sfr為字節型特殊功能存放器類型,占一個內存單元,利用它可以訪問MCS-51內部的所有特殊功能存放器;sfr16為雙字節型特殊功能存放器類型,占用兩個字節單元,利用它可以訪問MCS-51內部的所有兩個字節的特殊功能存放器。在C51中對特殊功能存放器的訪問必須先用sfr或sfr16進行聲明。七位類型 這也是C51中擴充的數據類型,用于訪問MCS-51單片機中的可尋址的位單元。在C51中,支持兩種位類型:bit型和sbit型。它們在內存中都只占一個二進制位,其值可以是“
12、1或“0。其中用bit定義的位變量在C51編譯器編譯時,在不同的時候位地址是可以變化的,而用sbit定義的位變量必須與MCS-51單片機的一個可以尋址位單元或可位尋址的字節單元中的某一位聯系在一起,在C51編譯器編譯時,其對應的位地址是不可變化的。基本數據類型長度取值范圍unsigned char1字節0255signed char1字節-128+127unsigned int2字節065535signed int2字節-32768+32767unsigned long4字節04294967295signed long4字節-2147483648+2147483647float4字節1.175
13、494E-383.402823E+38bit1位0或1Sbit1位0或1sfr1字節0255sfr162字節065535在C51語言程序中,有可能會出現在運算中數據類型不一致的情況。C51允許任何標準數據類型的隱式轉換,隱式轉換的優先級順序如下:bitcharintlongfloatsignedunsigned也就是說,當char型與int型進行運算時,先自動對char型擴展為int型,然后與int型進行運算,運算結果為int型。C51除了支持隱式類型轉換外,還可以通過強制類型轉換符“對數據類型進行人為的強制轉換。C5l編譯器除了能支持以上這些根本數據類型之外,還能支持一些復雜的組合型數據類型
14、,如數組類型、指針類型、結構類型、聯合類型等這些復雜的數據類型,在本書的后面將相繼介紹。4.3 51的運算量4.3.1 常量常量是指在程序執行過程中其值不能改變的量。在C51中支持整型常量、浮點型常量、字符型常量和字符串型常量。一整型常量 整型常量也就是整型常數,根據其值范圍在計算機中分配不同的字節數來存放。在C51中它可以表示成以下幾種形式: 十進制整數。如234、-56、0等。 十六進制整數。以0 x開頭表示,如0 x12表示十六進制數12H。 長整數。在C51中當一個整數的值到達長整型的范圍,那么該數按長整型存放,在存儲器中占四個字節,另外,如一個整數后面加一個字母L,這個數在存儲器中也
15、按長整型存放。如123L在存儲器中占四個字節。二浮點型常量 浮點型常量也就是實型常數。有十進制表示形式和指數表示形式。 十進制表示形式又稱定點表示形式,由數字和小數點組成。如 0.123、34.645等都是十進制數表示形式的浮點型常量。 指數表示形式為: 數字 .數字 e 數字 例如:123.456e-3、-3.123e2等都是指數形式的浮點型常量。三字符型常量 字符型常量是用單引號引起的字符,如a、1、F等。可以是可顯示的ASCII字符,也可以是不可顯示的控制字符。對不可顯示的控制字符須在前面加上反斜杠“組成轉義字符。利用它可以完成一些特殊功能和輸出時的格式控制。常用的轉義字符如表4-2所示
16、。 轉義字符含 義ASCII碼(十六進制數) o空字符(null)00H n換行符(LF)0AH r回車符(CR)0DH t水平制表符(HT)09H b退格符(BS)08H f換頁符(FF)0CH 單引號27H ”雙引號22H 反斜杠5CH四字符串型常量 字符串型常量由雙引號“括起的字符組成。如“D、“1234、“ABCD等。注意字符串常量與字符常量是不一樣,一個字符常量在計算機內只用一個字節存放,而一個字符串常量在內存中存放時不僅雙引號內的字符一個占一個字節,而且系統會自動的在后面加一個轉義字符“o作為字符串結束符。因此不要將字符常量和字符串常量混淆,如字符常量A和字符串常量“A是不一樣的。
17、4.3.2 變量 變量是在程序運行過程中其值可以改變的量。一個變量由兩局部組成:變量名和變量值。 在C51中,變量在使用前必須對變量進行定義,指出變量的數據類型和存儲模式。以便編譯系統為它分配相應的存儲單元。定義的格式如下: 存儲種類 數據類型說明符 存儲器類型 變量名1=初值,變量名2初值;一數據類型說明符 在定義變量時,必須通過數據類型說明符指明變量的數據類型,指明變量在存儲器中占用的字節數。可以是根本數據類型說明符,也可以是組合數據類型說明符,還可以是用typedef定義的類型別名。 在C51中,為了增加程序的可讀性,允許用戶為系統固有的數據類型說明符用typedef起別名,格式如下:
18、typedef c51固有的數據類型說明符 別名; 定義別名后,就可以用別名代替數據類型說明符對變量進行定義。別名可以用大寫,也可以用小寫,為了區別一般用大寫字母表示。【例4-1】 typedef的使用。typedef unsigned int WORD;typedef unsigned char BYTE;BYTE a1=0 x12;WORD a2=0 x1234;二變量名 變量名是C51區分不同變量,為不同變量取的名稱。在C51中規定變量名可以由字母、數字和下劃線三種字符組成,且第一個字母必須為字母或下劃線。變量名有兩種:普通變量名和指針變量名。它們的區別是指針變量名前面要帶“*號。三存儲
19、種類存儲種類是指變量在程序執行過程中的作用范圍。C51變量的存儲種類有四種,分別是自動(auto)、外部(extern)、靜態(static)和存放器(register)。1auto:使用auto定義的變量稱為自動變量,其作用范圍在定義它的函數體或復合語句內部,當定義它的函數體或復合語句執行時,C51才為該變量分配內存空間,結束時占用的內存空間釋放。自動變量一般分配在內存的堆棧空間中。定義變量時,如果省略存儲種類,那么該變量默認為自動(auto)變量。2extern:使用extern定義的變量稱為外部變量。在一個函數體內,要使用一個已在該函數體外或別的程序中定義過的外部變量時,該變量在該函數體
20、內要用extern說明。外部變量被定義后分配固定的內存空間,在程序整個執行時間內都有效,直到程序結束才釋放。3static:使用static定義的變量稱為靜態變量。它又分為內部靜態變量和外部靜態變量。在函數體內部定義的靜態變量為內部靜態變量,它在對應的函數體內有效,一直存在,但在函數體外不可見,這樣不僅使變量在定義它的函數體外被保護,還可以實現當離開函數時值不被改變。外部靜態變量上在函數外部定義的靜態變量。它在程序中一直存在,但在定義的范圍之外是不可見的。如在多文件或多模塊處理中,外部靜態變量只在文件內部或模塊內部有效。4register:使用register定義的變量稱為存放器變量。它定義的
21、變量存放在CPU內部的存放器中,處理速度快,但數目少。C51編譯器編譯時能自動識別程序中使用頻率最高的變量,并自動將其作為存放器變量,用戶可以無需專門聲明。四存儲器類型存儲器類型是用于指明變量所處的單片機的存儲器區域情況。存儲器類型與存儲種類完全不同。C51編譯器能識別的存儲器類型有以下幾種,見表所示。存儲器類型描 述 data直接尋址的片內RAM低128B,訪問速度快 bdata片內RAM的可位尋址區(20H2FH),允許字節和位混合訪問 idata間接尋址訪問的片內RAM,允許訪問全部片內RAM pdata用Ri間接訪問的片外RAM的低256B xdata用DPTR間接訪問的片外RAM,允
22、許訪問全部64k片外RAM code程序存儲器ROM64k空間定義變量時也可以省“存儲器類型,省時C51編譯器將按編譯模式默認存儲器類型,具體編譯模式的情況在后面介紹。【例4-2】變量定義存儲種類和存儲器類型相關情況。 char data varl; /*在片內RAM低128B定義用直接尋址方式訪問的字符型變量var1*/ int idata var2; /*在片內RAM256B定義用間接尋址方式訪問的整型變量var2*/ auto unsigned long data var3; /*在片內RAM128B定義用直接尋址方式訪問的自動無符號長整型變量var3*/ extern float xd
23、ata var4; /*在片外RAM64KB空間定義用間接尋址方式訪問的外部實型變量var4*/ int code var5; /*在ROM空間定義整型變量var5*/ unsign char bdata var6; /*在片內RAM位尋址區20H2FH單元定義可字節處理和位處理的無符號字符型變量var6*/五特殊功能存放器變量 MCS-51系列單片機片內有許多特殊功能存放器,通過這些特殊功能存放器可以控制MCS-51系列單片機的定時器、計數器、串口、I/O及其它功能部件,每一個特殊功能存放器在片內RAM中都對應于一個字節單元或兩個字節單元。 在C51中,允許用戶對這些特殊功能存放器進行訪問,
24、訪問時須通過sfr或sfr16類型說明符進行定義,定義時須指明它們所對應的片內RAM單元的地址。格式如下: sfr或sfr16 特殊功能存放器名=地址; sfr用于對MCS-51單片機中單字節的特殊功能存放器進行定義,sfr16用于對雙字節特殊功能存放器進行定義。特殊功能存放器名一般用大寫字母表示。地址一般用直接地址形式,具體特殊功能存放器地址見前面內容。【例4-3】特殊功能存放器的定義。 sfr PSW=0 xd0; sfr SCON=0 x98; sfr TMOD=0 x89; sfr P1=0 x90; sfr16 DPTR=0 x82; sfr16 T1=0X8A;六位變量 在C51中
25、,允許用戶通過位類型符定義位變量。位類型符有兩個:bit和sbit。可以定義兩種位變量。 bit位類型符用于定義一般的可位處理位變量。它的格式如下: bit 位變量名; 在格式中可以加上各種修飾,但注意存儲器類型只能是bdata、data、idata。只能是片內RAM的可位尋址區,嚴格來說只能是bdata。【例4-4】 bit型變量的定義。bit data a1; /*正確*/bit bdata a2; /*正確*/bit pdata a3; /*錯誤*/bit xdata a4; /*錯誤*/ sbit位類型符用于定義在可位尋址字節或特殊功能存放器中的位,定義時須指明其位地址,可以是位直接地
26、址,可以是可位尋址變量帶位號,也可以是特殊功能存放器名帶位號。格式如下: sbit 位變量名=位地址; 如位地址為位直接地址,其取值范圍為0 x000 xff;如位地址是可位尋址變量帶位號或特殊功能存放器名帶位號,那么在它前面須對可位尋址變量或特殊功能存放器進行定義。字節地址與位號之間、特殊功能存放器與位號之間一般用“作間隔。【例4-5】sbit型變量的定義。sbit OV=0 xd2;sbit CY=oxd7;unsigned char bdata flag;sbit flag0=flag0;sfr P1=0 x90;sbit P1_0=P10;sbit P1_1=P11;sbit P1_2
27、=P12;sbit P1_3=P13;sbit P1_4=P14;sbit P1_5=P15;sbit P1_6=P16;sbit P1_7=P17; 在C51中,為了用戶處理方便,C51編譯器把MCS-51單片機的常用的特殊功能存放器和特殊位進行了定義,放在一個“reg51.h或“reg52.h的頭文件中,當用戶要使用時,只須要在使用之前用一條預處理命令#include 把這個頭文件包含到程序中,然后就可使用殊功能存放器名和特殊位名稱。4.3.3 存儲模式 C51編譯器支持三種存儲模式:SMALL模式、COMPACT模式和LARGE模式。不同的存儲模式對變量默認的存儲器類型不一樣。1SMAL
28、L模式。SMALL模式稱為小編譯模式,在SMALL模式下,編譯時,函數參數和變量被默認在片內RAM中,存儲器類型為data。2COMPACT模式。COMPACT模式稱為緊湊編譯模式,在COMPACT模式下,編譯時,函數參數和變量被默認在片外RAM的低256字節空間,存儲器類型為pdata。3LARGE模式。LARGE模式稱為大編譯模式,在LARGE模式下,編譯時函數參數和變量被默認在片外RAM的64K字節空間,存儲器類型為xdata。 在程序中變量的存儲模式的指定通過#pragma預處理命令來實現。函數的存儲模式可通過在函數定義時后面帶存儲模式說明。如果沒有指定,那么系統都隱含為SMALL模式
29、。【例4-6】變量的存儲模式。#pragma small /*變量的存儲模式為SMALL*/char k1;int xdata m1;#pragma compact /*變量的存儲模式為SMALL*/char k2;int xdata m2;int func1(int x1,int y1) large /*函數的存儲模式為LARGE*/return(x1+y1);int func2(int x2,int y2) /*函數的存儲模式隱含為SMALL*/ return(x2-y2); 程序編譯時,k1變量存儲器類型為data,k2變量存儲器類型為pdata,而m1和m2由于定義時帶了存儲器類型xd
30、ata,因而它們為xdata型;函數func1的形參x1和y1的存儲器類型為xdata型,而函數func2由于沒有指明存儲模式,隱含為SMALL模式,形參x2和y2的存儲器類型為data。4.3.4 絕對地址的訪問一使用C51運行庫中預定義宏 C51編譯器提供了一組宏定義來對51系列單片機的code、data、pdata和xdata空間進行絕對尋址。規定只能以無符號數方式訪問,定義了8個宏定義,其函數原型如下:#define CBYTE(unsigned char volatile*)0 x50000L)#define DBYTE(unsigned char volatile*)0 x4000
31、0L)#define PBYTE(unsigned char volatile*)0 x30000L)#define XBYTE(unsigned char volatile*)0 x20000L)#define CWORD(unsigned int volatile*)0 x50000L)#define DWORD(unsigned int volatile*)0 x40000L)#define PWORD(unsigned int volatile*)0 x30000L)#define XWORD(unsigned int volatile*)0 x20000L) 這些函數原型放在absa
32、cc.h文件中。使用時須用預處理命令把該頭文件包含到文件中,形式為:#include 。 其中:CBYTE以字節形式對code區尋址,DBYTE以字節形式對data區尋址,PBYTE以字節形式對pdata區尋址,XBYTE以字節形式對xdata區尋址,CWORD以字形式對code區尋址,DWORD以字形式對data區尋址,PWORD以字形式對pdata區尋址,XWORD以字形式對xdata區尋址。訪問形式如下: 宏名地址 宏名為CBYTE、DBYTE、PBYTE、XBYTE、CWORD、DWORD、PWORD或XWORD。地址為存儲單元的絕對地址,一般用十六進制形式表示。【例4-7】絕對地址對
33、存儲單元的訪問#include /*將絕對地址頭文件包含在文件中*/#include /*將存放器頭文件包含在文件中*/#define uchar unsigned char /*定義符號uchar為數據類型符unsigned char*/#define uint unsigned int /*定義符號uint為數據類型符unsigned int*/void main(void)uchar var1;uint var2;var1=XBYTE0 x0005; /*XBYTE0 x0005訪問片外RAM的0005字節單元*/var2=XWORD0 x0002; /*XWORD0 x0002訪問片外
34、RAM的000字單元*/.while(1); 在上面程序中,其中XBYTE0 x0005就是以絕對地址方式訪問的片外RAM 0005字節單元;XWORD0 x0002就是以絕對地址方式訪問的片外RAM 0002字單元。二通過指針訪問 采用指針的方法,可以實現在C51程序中對任意指定的存儲器單元進行訪問。【例4-8】 通過指針實現絕對地址的訪問。#define uchar unsigned char /*定義符號uchar為數據類型符unsigned char*/#define uint unsigned int /*定義符號uint為數據類型符unsigned int*/void func(v
35、oid)uchar data var1;uchar pdata *dp1; /*定義一個指向pdata區的指針dp1*/uint xdata *dp2; /*定義一個指向xdata區的指針dp2*/uchar data *dp3; /*定義一個指向data區的指針dp3*/dp1=0 x30; /*dp1指針賦值,指向pdata區的30H單元*/dp2=0 x1000; /*dp2指針賦值,指向xdata區的1000H單元*/*dp1=0 xff; /*將數據0 xff送到片外RAM30H單元*/*dp2=0 x1234; /*將數據0 x1234送到片外RAM1000H單元*/dp3=&va
36、r1; /*dp3指針指向data區的var1變量*/*dp3=0 x20; /*給變量var1賦值0 x20*/三使用C51擴展關鍵字_at_ 使用_at_對指定的存儲器空間的絕對地址進行訪問,一般格式如下: 存儲器類型 數據類型說明符 變量名 _at_ 地址常數; 其中,存儲器類型為data、bdata、idata、pdata等C51能識別的數據類型,如省略那么按存儲模式規定的默認存儲器類型確定變量的存儲器區域;數據類型為C51支持的數據類型。地址常數用于指定變量的絕對地址,必須位于有效的存儲器空間之內;使用_at_定義的變量必須為全局變量。【例4-9】通過_at_實現絕對地址的訪問。#d
37、efine uchar unsigned char /*定義符號uchar為數據類型符unsigned char*/#define uint unsigned int /*定義符號uint為數據類型符unsigned int*/void main(void)data uchar x1 _at_ 0 x40; /*在data區中定義字節變量x1,它的地址為40H*/xdata uint x2 _at_ 0 x2000; /*在xdata區中定義字變量x2,它的地址為2000H*/x1=0 xff;x2=0 x1234;.while(1);4.4 C51的運算符及表達式4.4.1 賦值運算符 賦值
38、運算符“=,在C51中,它的功能是將一個數據的值賦給一個變量,如x=10。利用賦值運算符將一個變量與一個表達式連接起來的式子稱為賦值表達式,在賦值表達式的后面加一個分號“;就構成了賦值語句,一個賦值語句的格式如下: 變量=表達式; 執行時先計算出右邊表達式的值,然后賦給左邊的變量。例如: x=8+9; /*將8+9的值賦紿變量x*/ x=y=5; /*將常數5同時賦給變量x和y*/ 在C51中,允許在一個語句中同時給多個變量賦值,賦值順序自右向左。 4.4.2 算術運算符C51中支持的算術運算符有:+ 加或取正值運算符- 減或取負值運算符* 乘運算符/ 除運算符% 取余運算符 加、減、乘運算相
39、比照較簡單,而對于除運算,如相除的兩個數為浮點數,那么運算的結果也為浮點數,如相除的兩個數為整數,那么運算的結果也為整數,即為整除。如25.0/20.0結果為1.25,而25/20結果為1。 對于取余運算,那么要求參加運算的兩個數必須為整數,運算結果為它們的余數。例如:x=5%3,結果x的值為2。4.4.3 關系運算符C51中有6種關系運算符: 大于= 大于等于3,結果為真1,而10= =100,結果為假0。注意:關系運算符等于“= =是由兩個“=組成。4.4.4 邏輯運算符C51有3種邏輯運算符:| 邏輯或& 邏輯與! 邏輯非 關系運算符用于反映兩個表達式之間的大小關系,邏輯運算符那么用于求
40、條件式的邏輯值,用邏輯運算符將關系表達式或邏輯量連接起來的式子就是邏輯表達式。 邏輯與,格式: 條件式1 & 條件式2 當條件式1與條件式2都為真時結果為真非0值,否那么為假0值。邏輯或,格式: 條件式1 | 條件式2 當條件式1與條件式2都為假時結果為假0值,否那么為真非0值。邏輯非,格式: !條件式 當條件式原來為真非0值,邏輯非后結果為假0值。當條件式原來為假0值,邏輯非后結果為真非0值。例如:假設a=8,b=3,c=0,那么!a為假,a & b為真,b & c為假。4.4.5 位運算符 C51語言能對運算對象按位進行操作,它與匯編語言使用一樣方便。位運算是按位對變量進行運算,但并不改變
41、參與運算的變量的值。如果要求按位改變變量的值,那么要利用相應的賦值運算。C51中位運算符只能對整數進行操作,不能對浮點數進行操作。C51中的位運算符有:& 按位與| 按位或 按位異或 按位取反 右移【例4-10】設a=0 x45=01010100B,b=0 x3b=00111011B,那么a&b、a|b、ab、a、a2分別為多少?a&b=00010000b=0 x10。a|b=01111111B=0 x7f。ab=01101111B=0 x6f。a=10101011B=0 xab。a2=00001110B=0 x0e。4.4.6 復合賦值運算符 C51語言中支持在賦值運算符“=的前面加上其它運
42、算符,組成復合賦值運算符。下面是C51中支持的復合賦值運算符:+= 加法賦值 + 減法賦值*= 乘法賦值 /= 除法賦值%= 取模賦值 &= 邏輯與賦值|= 邏輯或賦值 = 邏輯異或賦值= 邏輯非賦值 = 右移位賦值=2相當于x=x2。4.4.7 逗號運算符 在C51語言中,逗號“,是一個特殊的運算符,可以用它將兩個或兩個以上的表達式連接起來,稱為逗號表達式。逗號表達式的一般格式為: 表達式1,表達式2,表達式n 程序執行時對逗號表達式的處理:按從左至右的順序依次計算出各個表達式的值,而整個逗號表達式的值是最右邊的表達式表達式n的值。例如:x=(a=3,6*3)結果x的值為18。4.4.8 條
43、件運算符 條件運算符“?:是C51語言中唯一的一個三目運算符,它要求有三個運算對象,用它可以將三個表達式連接在一起構成一個條件表達式。條件表達式的一般格式為: 邏輯表達式?表達式1:表達式2 其功能是先計算邏輯表達式的值,當邏輯表達式的值為真非0值時,將計算的表達式1的值作為整個條件表達式的值;當邏輯表達式的值為假0值時,將計算的表達式2的值作為整個條件表達式的值。例如:條件表達式max=(ab)?a:b的執行結果是將a和b中較大的數賦值給變量max。4.4.9 指針與地址運算符 指針是C51語言中的一個十分重要的概念,在C51中的數據類型中專門有一種指針類型。指針為變量的訪問提供了另一種方式
44、,變量的指針就是該變量的地址,還可以定義一個專門指向某個變量的地址的指針變量。為了表示指針變量和它所指向的變量地址之間的關系,C51中提供了兩個專門的運算符:* 指針運算符& 取地址運算符 指針運算符“*放在指針變量前面,通過它實現訪問以指針變量的內容為地址所指向的存儲單元。例如:指針變量p中的地址為2000H,那么*p所訪問的是地址為2000H的存儲單元,x=*p,實現把地址為2000H的存儲單元的內容送給變量x。 取地址運算符“&放在變量的前面,通過它取得變量的地址,變量的地址通常送給指針變量。例如:設變量x的內容為12H,地址為2000H,那么&x的值為2000H,如有一指針變量p,那么
45、通常用p=&x,實現將x變量的地址送給指針變量p,指針變量p指向變量x,以后可以通過*p訪問變量x。4.5 表達式語句及復合語句4.5.1 表達式語句在表達式的后邊加一個分號“;就構成了表達式語句 ,如:a=+b*9;x=8;y=7;+k; 可以一行放一個表達式形成表達式語句,也可以一行放多個表達式形成表達式語句,這時每個表達式后面都必須帶“;號,另外,還可以僅由個分號“;占一行形成一個表達式語句,這種語句稱為空語句。 空語句在程序設計中通常用于兩種情況:1在程序中為有關語句提供標號,用以標記程序執行的位置。例如采用下面的語句可以構成一個循環。repeat:; ; goto repeat;2在
46、用while語句構成的循環語句后面加一個分號,形成一個不執行其它操作的空循環體。這種結構通常用于對某位進行判斷,當不滿足條件那么等待,滿足條件那么執行。【例4-11】下面這段子程序用于讀取8051單片機的串行口的數據,當沒有接收到那么等待,當接收到,接收數據后返回,返回值為接收的數據。#include char getchar()char c;while(!RI); /當接收中斷標志位RI為0那么等待,當接收中斷標志位為1那么結束等待。c=SBUF;RI=0;return(c);4.5.2 復合語句 復合語句是由假設干條語句組合而成的一種語句,在C51中,用一個大括號“將假設干條語句括在一起就
47、形成了一個復合語句,復合語句最后不需要以分號“;結束,但它內部的各條語句仍需以分號“;結束。復合語句的一般形式為:局部變量定義;語句l;語句2; 復合語句在執行時,其中的各條單語句按順序依次執行,整個復合語句在語法上等價于一條單語句,因此在C51中可以將復合語句視為一條單語句。通常復合語句出現在函數中,實際上,函數的執行局部即函數體就是一個復合語句;復合語句中的單語句一般是可執行語句,此外還可以是變量的定義語句說明變量的數據類型。在復合語句內部語句所定義的變量,稱為該復合語句中的局部變量,它僅在當前這個復合語句中有效。利用復合語句將多條單語句組合在起,以及在復合語句中進行局部變量定義是C51語
48、言的一個重要特征。4.6 C51的輸入輸出在C51語言中,它本身不提供輸入和輸出語句,輸入和輸出操作是由函數來實現的。在C51的標準函數庫中提供了一個名為“stdio.h的一般I/O函數庫,它當中定義了C51中的輸入和輸出函數。當對輸入和輸出函數使用時,須先用預處理命令“#include 將該函數庫包含到文件中。 在C51的一般I/O函數庫中定義的I/O函數都是通過串行接口實現,在使用I/O函數之前,應先對MCS-51單片機的串行接口進行初始化。選擇串口工作于方式28位自動重載方式,波特率由定時器/計數器1溢出率決定。例如,設系統時鐘為12MHZ,波特率為2400,那么初始化程序如下:SCON
49、=0 x52;TMOD=0X20;TH1=0 xf3;TR1=1;4.6.1 格式輸出函數printf()printf()函數的的作用是通過串行接口輸出假設干任意類型的數據,它的格式如下:printf(格式控制,輸出參數表)格式控制是用雙引號括起來的字符串,也稱轉換控制字符串,它包括三種信息:格式說明符、普通字符和轉義字符。1格式說明符,由“%和格式字符組成,它的作用是用于指明輸出的數據的格式輸出,如%d、%f等,它們的具體情況見表4-4。2普通字符,這些字符按原樣輸出,用來輸出某些提示信息。3轉義字符,就是前面介紹的轉義字符表4-2,用來輸出特定的控制符,如輸出轉義字符n就是使輸出換一行。輸
50、出參數表是需要輸出的一組數據,可以是表達式。格式字符數據類型輸出格式dint帶符號十進制數uint無符號十進制數oint無符號八進制數xint無符號十六進制數,用“af”表示Xint無符號十六進制數,用“AF”表示ffloat帶符號十進制數浮點數,形式為-dddd.dddde,Efloat帶符號十進制數浮點數,形式為-d.ddddEddg,Gfloat自動選擇e或f格式中更緊湊的一種輸出格式cchar單個字符s指針指向一個帶結束符的字符串p指針帶存儲器批示符和偏移量的指針,形式為M:aaaa其中,M可分別為:C(code),D(data),I(idata),P(pdata)如M為a,則表示的是
51、指針偏移量4.6.2 格式輸入函數scanfscanf函數的作用是通過串行接口實現數據輸入,它的使用方法與printf類似,scanf的格式如下:scanf格式控制,地址列表格式控制與printf函數的情況類似,也是用雙引號括起來的一些字符,可以包括以下三種信息:空白字符、普通字符和格式說明。1空白字符,包含空格、制表符、換行符等,這些字符在輸出時被忽略。2普通字符,除了以百分號“%開頭的格式說明符而外的所有非空白字符,在輸入時要求原樣輸入。3格式說明,由百分號“%和格式說明符組成,用于指明輸入數據的格式,它的根本情況與printf相同,具體情況見表4-5。地址列表是由假設干個地址組成,它可以
52、是指針變量、取地址運算符“&加變量變量的地址或字符串名表示字符串的首地址。格式字符數據類型輸出格式dint指針帶符號十進制數uint指針無符號十進制數oint指針無符號八進制數xint指針無符號十六進制數f,e,Efloat指針浮點數cchar指針字符sstring指針字符串【例4-12】 使用格式輸入輸出函數的例子#include /包含特殊功能存放器庫#include /包含I/O函數庫void main(void) /主函數int x,y; /定義整型變量x和ySCON=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;printf(“input x,y:n)
53、; /輸出提示信息scanf(“%d%d,&x,&y); /輸入x和y的值printf(“n); /輸出換行printf(“%d+%d=%d,x,y,x+y); /按十進制形式輸出printf(“n); /輸出換行printf(“%xH+%xH=%XH,x,y,x+y); /按十六進制形式輸出while(1); /結束4.7 C51程序根本結構與相關語句4.7.1 C51的根本結構一順序結構順序結構是最根本、最簡單的結構,在這種結構中,程序由低地址到高地址依次執行,圖4.3給出順序結構流程圖,程序先執行A操作,然后再執行B操作。AB圖4.3 順序結構流程圖 選擇結構可使程序根據不同的情況,選擇
54、執行不同的分支,在選擇結構中,程序先都對一個條件進行判斷。當條件成立,即條件語句為“真時,執行一個分支,當條件不成立時,即條件語句為“假時,執行另一個分支。如圖4.4,當條件S成立時,執行分支A,當條件P不成立時,執行分支B。二選擇結構條件P語句A語句B成立不成立 在C51中,實現選擇結構的語句為if/else,if/else if語句。另外在C51中還支持多分支結構,多分支結構既可以通過if和else if語句嵌套實現,可用swith/case語句實現。 在程序處理過程中,有時需要某一段程序重復執行屢次,這時就需要循環結構來實現,循環結構就是能夠使程序段重復執行的結構。循環結構又分為兩種:當
55、while型循環結構和直到do.while型循環結構。1當型循環結構當型循環結構如圖4-3,當條件P成立為“真時,重復執行語句A,當條件不成立為“假時才停止重復,執行后面的程序。三循環結構條件P語句A成立不成立圖4.5 當型循環結構 2直到型循環結構直到型循環結構如圖4-4,先執行語句A,再判斷條件P,當條件成立為“真時,再重復執行語句A,直到條件不成立為“假時才停止重復,執行后面的程序。條件P語句A成立不成立圖4.6 直到型循環結構構成循環結構的語句主要有:while、do while、for、goto等。4.7.2 if語句if語句是C51中的一個根本條件選擇語句,它通常有三種格式:1if
56、 表達式 語句;2if 表達式 語句1; else 語句2;3if 表達式1 語句1;else if 表達式2 語句2;else if 表達式3 語句3;else if 表達式n-1 語句n-1;else 語句n【例4-13】 if語句的用法。1if (x!=y) printf(“x=%d,y=%dn,x,y);執行上面語句時,如果x不等于y,那么輸出x的值和y的值。2if (xy) max=x;else max=y;執行上面語句時,如x大于y成立,那么把x送給最大值變量max,如x大于y不成立,那么把y送給最大值變量max。使max變量得到x、y中的大數。3if (score=90) pri
57、ntf(“Your result is an An);else if (score=80) printf(“Your result is an Bn);else if (score=70) printf(“Your result is an Cn);else if (score=60) printf(“Your result is an Dn);else printf(“Your result is an En);執行上面語句后,能夠根據分數score分別打出A、B、C、D、E五個等級。4.7.3 switch/case語句if語句通過嵌套可以實現多分支結構,但結構復雜。switch是C51中
58、提供的專門處理多分支結構的多分支選擇語句。它的格式如下:switch 表達式case 常量表達式1:語句1;break;case 常量表達式2:語句2;break;case 常量表達式n:語句n;break;default:語句n+1;說明如下:1switch后面括號內的表達式,可以是整型或字符型表達式。2當該表達式的值與某一“case后面的常量表達式的值相等時,就執行該“case后面的語句,然后遇到break語句退出switch語句。假設表達式的值與所有case后的常量表達式的值都不相同,那么執行default后面的語句,然后退出switch結構。3每一個case常量表達式的值必須不同否那么
59、會出現自相矛盾的現象。4case語句和default語句的出現次序對執行過程沒有影響。5每個case語句后面可以有“break,也可以沒有。有break語句,執行到break那么退出switch結構,假設沒有,那么會順次執行后面的語句,直到遇到break或結束。6每一個case語句后面可以帶一個語句,也可以帶多個語句,還可以不帶。語句可以用花括號括起,也可以不括。7多個case可以共用一組執行語句。【例4-14】 switch/case語句的用法。對學生成績劃分為AD,對應不同的百分制分數,要求根據不同的等級打印出它的對應百分數。可以通過下面的switch/case語句實現。switchgra
60、decase A;printf90100n;break;case B;printf8090n;break;case C;printf7080n;break;case D;printf6070n;break;case E;printf60n;break;default;printferrorn4.7.4 while語句 while語句在C51中用于實現當型循環結構,它的格式如下: while表達式 語句; /*循環體*/ while語句后面的表達式是能否循環的條件,后面的語句是循環體。當表達式為非0真時,就重復執行循環體內的語句;當表達式為0假,那么中止while循環,程序將執行循環結構之外的下
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 綿陽師范學院《臨床醫學工程技術》2023-2024學年第二學期期末試卷
- 上海市高境第一中學2024-2025學年高三第二次綜合考試試題含解析
- 四川民族學院《機器人學》2023-2024學年第二學期期末試卷
- 許昌學院《醫學科學研究導論》2023-2024學年第二學期期末試卷
- 宣化科技職業學院《新媒體藝術傳播》2023-2024學年第二學期期末試卷
- 四川工業科技學院《結構疲勞與斷裂力學》2023-2024學年第一學期期末試卷
- 邢臺學院《醫學人文導論》2023-2024學年第一學期期末試卷
- 山東省德州市齊河縣一中2025年高三教學測試(二)英語試題含解析
- 嘉應學院《創新方法與實踐(以競賽導向的信息技術創新實踐)》2023-2024學年第二學期期末試卷
- 石家莊二手房房屋買賣合同二零二五年
- 復旦大學附屬眼耳鼻喉醫院耳鼻喉進修匯報
- DB33-1036-2021《公共建筑節能設計標準》
- 巖芯鑒定手冊
- 快速排序算法高校試講PPT
- 甘肅歷史與甘肅文化
- 工程勘察設計收費標準
- 高邊坡施工危險源辨識及分析
- 江蘇工業企業較大以上風險目錄
- 《村衛生室管理辦法(試行)》課件(PPT 49頁)
- 監理質量評估報告(主體分部)
- 鍋爐爆炸事故演練方案(模板)
評論
0/150
提交評論