- 單片機C語言程序設(shè)計實訓100例
- 彭偉編著
- 1446字
- 2018-12-27 05:11:56
1.6 變量、存儲類型與存儲模式
全局變量定義在函數(shù)外面,生命期從所定義的地方開始,其后面的所有函數(shù)都可以讀/寫該全局變量,本書案例在使用定時器時,為得到更大的延時值,程序中定義了全局變量tCount,在定時器中斷內(nèi)對該變量累加,從而得到更大的延時間隔,如果程序中其他地方不需要使用tCount,該變量可以不必放在程序最前面,而是放在定時器中斷函數(shù)的上一行。
局部變量定義在函數(shù)內(nèi)部,對于循環(huán)及其他的臨時計算,應(yīng)盡可能使用局部變量,作為優(yōu)化處理的一部分,編譯程序會試圖將局部變量維持在寄存器中,寄存器訪問是最快的內(nèi)存訪問類型,特別是unsigned char和unsigned int類型的變量。
對于剛才討論的tCount變量,在C語言程序設(shè)計時,還可以定義在中斷函數(shù)內(nèi)部實現(xiàn)計時累加,但要注意在定義前面加上static,因靜態(tài)變量僅在函數(shù)首次調(diào)用時被初始化一次,此后不再被初始化。
8051系列單片機中,程序存儲器與數(shù)據(jù)存儲器嚴格分開,特殊功能寄存器與片內(nèi)數(shù)據(jù)存儲器統(tǒng)一編址,這與一般微型計算機的存儲結(jié)構(gòu)是不同的。
Keil C51編譯器完全支持8051單片機硬件結(jié)構(gòu),可完全訪問8051硬件系統(tǒng)的所有部分,編譯器通過將變量、常量定義成不同的存儲類型(data、bdata、idata、pdata、xdata、code),從而將它們定位在不同的存儲區(qū)中。表1-4列出了Keil C51存儲類型與8051存儲空間的對應(yīng)關(guān)系。
表1-4 Keil C51存儲類型與8051存儲空間的對應(yīng)關(guān)系

讀者在閱讀表1-4時可參考圖1-1所示的8051單片機存儲器結(jié)構(gòu)。
上述存儲類型指示符data、bdata、idata將數(shù)據(jù)定位在內(nèi)部數(shù)據(jù)存儲器中,訪問內(nèi)部數(shù)據(jù)速度很快,它們只需要8位地址。
Keil C51編譯器提供了兩種外部存儲類型:xdata和pdata,指定為xdata存儲器類型的數(shù)據(jù)保存在最大空間為64KB的外部數(shù)據(jù)存儲器空間中,通過P0與P2端口給出的16位地址可訪問外部空間中的任意位置,但是,并非64KB地址空間總是用于存儲器,單片機的外圍設(shè)備也可以映射到存儲器空間,在這種情況下,程序?qū)耘c訪問外部數(shù)據(jù)內(nèi)存同樣的方法編程控制外圍設(shè)備,這種技術(shù)被稱為內(nèi)存映射的I/O技術(shù),本書有關(guān)8255和部分液晶顯示案例使用的就是這種技術(shù)。第二種存儲類型pdata可訪問外部數(shù)據(jù)內(nèi)存一頁中的256B,頁地址則由P2提供。
本書有關(guān)案例在擴展外部存儲器或外部設(shè)備時,程序中包含了絕對內(nèi)存訪問(Absolute Memory Access)頭文件absacc.h,該文件中有宏定義:
#define XBYTE ((unsigned char volatile xdata *) 0)
由其中的XBYTE定義可知,表達式XBYTE[16位字地址]可用來讀/寫外部RAM空間的字節(jié)數(shù)據(jù),本書6264擴展內(nèi)存案例就使用了XBYTE訪問外部數(shù)據(jù)存儲器,它相當于匯編語言中的MOVX @DPTR語句。
在8255接口擴展實驗中,C語言程序內(nèi)有:
#define PA XBYTE[0x0000] #define PB XBYTE[0x0001] #define PC XBYTE[0x0002] #define COM XBYTE[0x0003]
這里PA、PB、PC、COM分別用于訪問8255的4個不同端口。
上述定義還可以寫成:
#define PA *(XBYTE + 0x0000) #define PB *(XBYTE + 0x0001) #define PC *(XBYTE + 0x0002) #define COM *(XBYTE + 0x0003)
本書涉及數(shù)碼管顯示和圖像與文字顯示的案例中,由于數(shù)碼管段碼固定,待顯示的圖像或文字點陣數(shù)據(jù)也是固定的,將這些數(shù)據(jù)全部保存在RAM中會占用太多寶貴的空間,而且數(shù)據(jù)RAM空間本來就很有限,因此,在用C語言開發(fā)單片機程序時,可以將這些運行過程中不會發(fā)生變化的數(shù)據(jù)定義為code存儲類型,將這些數(shù)據(jù)保存在程序內(nèi)存而不是數(shù)據(jù)內(nèi)存。
在定義變量時,如果省略存儲類型,編譯程序會自動選擇默認存儲類型,默認存儲類型有小模式(Small)、緊縮模式(Compact)和巨模式(Large)限制,存儲模式?jīng)Q定了變量的默認存儲類型、參數(shù)傳遞區(qū)和未指明存儲類型變量的存儲類型。表1-5列出了這3種存儲模式及相關(guān)說明。
表1-5 3種存儲模式及相關(guān)說明

在固定的存儲器地址上進行變量傳遞是Keil C51的特征之一,在Small模式下,參數(shù)傳遞在片內(nèi)數(shù)據(jù)存儲區(qū)完成,Compact和Large模式允許參數(shù)在外部存儲區(qū)中傳遞。模式選擇可在Keil C51項目選項窗口中的Target選項卡下完成,默認選擇的是Small模式。
- .NET之美:.NET關(guān)鍵技術(shù)深入解析
- Modular Programming with Python
- Beginning Java Data Structures and Algorithms
- Getting Started with ResearchKit
- 少年輕松趣編程:用Scratch創(chuàng)作自己的小游戲
- 看透JavaScript:原理、方法與實踐
- Java開發(fā)入行真功夫
- 高級C/C++編譯技術(shù)(典藏版)
- 持續(xù)輕量級Java EE開發(fā):編寫可測試的代碼
- Python編程快速上手2
- 現(xiàn)代C++語言核心特性解析
- Unity 3D UI Essentials
- Java王者歸來:從入門邁向高手
- Spark Cookbook
- Xamarin Mobile Application Development for Android(Second Edition)