Keil C51學(xué)習(xí)過程
51實時系統(tǒng)
RTX-51 Tiny
搶先任務(wù)切換
RTX51 Full 提供了搶先的任務(wù)切換,RTX51 Tiny 不具備這個功能。為了對多任務(wù)的概念有一個完整的了解,在這里對搶先任務(wù)切換加以解釋。
在上一個例子中,任務(wù)1收到一個信號后不會立即開始,只有當(dāng)任務(wù)0 發(fā)生了時間到事件后,任務(wù)1才會啟動。如果任務(wù)1被賦予了比任務(wù)0 高的優(yōu)先級,通過搶先任務(wù)切換,如果任務(wù)1收到了信號,就會立即開始。優(yōu)先級在任務(wù)定義中被指定(默認的優(yōu)先級是0)
51規(guī)則看法
1.數(shù)據(jù)類型
C51 編譯器支持下表列出的數(shù)據(jù)類型除了這些標量類型外還可以將變量組合到結(jié)構(gòu)聯(lián)合及
陣列中除了指明的類型可通過指針訪問這些數(shù)據(jù)類型
數(shù)據(jù)類型 位 字節(jié) 值的范圍
bit 1 1 0~1
帶符號char 8 1 -128~+127
無符號char 8 1 0~255
enum 16 2 -32768~+32767
short 16 2 -32768~+32767
short 16 2 0~65535
int 16 2 -32768~+32767
int 16 2 0~65535
long 32 4 -2147483648~+2147483647
long 32 4 0~4294967295
float 32 4 +1.175494E-38~+3.402823E+38
sbit 1 1 0~1
sfr 8 1 0~255
sfr16 16 2 0~65535
1). bit sbit sfrs 和sfr16 數(shù)據(jù)類型專門用于8051 硬件和C51 編譯器并不是ANSI C 的一部分,不能通過指針進行訪問bit sbit sfrs 和sfr16 數(shù)據(jù)類型用于訪問8051 的特殊功能寄存器。例如:sfr P0 = 0x80 定義變量P0 并將其分配特殊功能寄存器地址0x80 在8051 上是P0 口的地址。
當(dāng)結(jié)果表示不同的數(shù)據(jù)類型時C51 編譯器自動轉(zhuǎn)換數(shù)據(jù)類型例如位變量在整數(shù)分配中就被轉(zhuǎn)換成一個整數(shù)除了數(shù)據(jù)類型的轉(zhuǎn)換之外帶符號變量的符號擴展也是自動完成的。
2.存儲器類型
C51 編譯器支持8051 及其派生器件結(jié)構(gòu)并提供對8051 所有存儲區(qū)的訪問每個變量可以明確地分配到指定的存儲空間對內(nèi)部數(shù)據(jù)存儲器的訪問比對外部數(shù)據(jù)存儲器的訪問快許多因此應(yīng)當(dāng)將頻繁使用的變量放在內(nèi)部數(shù)據(jù)存儲器而把較少用的變量放在外部數(shù)據(jù)存儲器中變量的定義包括了存儲器類型的指定可以指定變量存放的位置存儲器類型描述
code 程序存儲器64K 字節(jié)通過操作碼 MOVC @A+DPTR 進行訪問
data 直接尋址內(nèi)部數(shù)據(jù)存儲器對變量的最快訪問128 字節(jié)
idata 間接尋址內(nèi)部數(shù)據(jù)存儲器訪問整個內(nèi)部地址空間256 字節(jié)
bdata 位尋址內(nèi)部數(shù)據(jù)存儲器允許位和字節(jié)混合尋址16 字節(jié)
xdata 外部數(shù)據(jù)存儲器64K 字節(jié)通過 MOVX @DPTR 訪問
pdata 頁外部數(shù)據(jù)存儲器256 字節(jié)通過 MOVX @Rn 訪問
3.再入函數(shù)
再入函數(shù)可以同時由幾個程序共用當(dāng)執(zhí)行再入函數(shù)時其它程序可以中斷執(zhí)行并開始執(zhí)行同一個再入函數(shù)通常C51 函數(shù)不能遞歸調(diào)用或用于導(dǎo)致重入的方式受到該限制是因為函數(shù)自變量和局部變量都存放在固定的存儲器位置再入函數(shù)屬性允許說明那些可以重入的函數(shù)因此可以實現(xiàn)遞歸調(diào)用例如
int calc (char i, int b) reentrant
{
int x;
x=table [i]
return (x * b)
}
再入函數(shù)可以遞歸調(diào)用也可以同時被兩個或更多程序調(diào)用它經(jīng)常用于實時應(yīng)用或中斷代碼和非中斷代碼必須共用一個函數(shù)的情況對于每個再入函數(shù)根據(jù)存儲器的模型在內(nèi)部或外部存儲器模擬再入堆棧區(qū)。
4.代碼優(yōu)化
C51 編譯器是一個主動優(yōu)化編譯器意思是說編譯器采取一定的步驟確定產(chǎn)生的代碼和輸出的目標文件是高效的代碼編譯器分析所產(chǎn)生的代碼并使之成為最高效的指令序列這確保了C 程序在最小程序空間內(nèi)實現(xiàn)盡可能高效的運行C51 編譯器提供6 種不同級別的優(yōu)化高級優(yōu)化包含低級優(yōu)化下面列出了C51 編譯器可執(zhí)行的所有優(yōu)化
常量合并一個表達式或地址計算式內(nèi)的幾個常量合并成一個常量
跳轉(zhuǎn)優(yōu)化跳轉(zhuǎn)反演或擴展為最終目標地址使程序效率得以提高
無用代碼消除將不可能執(zhí)行的代碼無用碼從程序中刪除
寄存器變量自動變量和函數(shù)自變量盡可能放在寄存器中沒有為這些變量保留數(shù)據(jù)存儲器空間
參數(shù)通過寄存器傳遞通過寄存器最多可傳遞3 個函數(shù)自變量
全局共用的子表達式消除將在一個函數(shù)中多次出現(xiàn)的子表達式和地址計算式盡可能只計算一次
5.8051 特殊優(yōu)化
窺孔優(yōu)化當(dāng)存儲器空間或時間可作為結(jié)果保存時用簡化操作代替復(fù)雜操作
訪問優(yōu)化在操作中直接計算并包含常量和變量
數(shù)據(jù)覆蓋數(shù)據(jù)和位段函數(shù)被認為是可覆蓋的并通過BL51 連接器/定位器用其它數(shù)據(jù)和位段覆蓋
Case/Switch 優(yōu)化Case 和Switch 語句根據(jù)它們的數(shù)據(jù)序列和位置可以使用跳轉(zhuǎn)表或跳轉(zhuǎn)串進行優(yōu)化
6.代碼產(chǎn)生選項
OPTIMIZE SIZE 子程序代替共用的C 操作在降低程序運行速度的前提下減小了程序代碼占用的空間
OPTIMIZE SPEED 共用的C 操作內(nèi)嵌擴展增加程序代碼的規(guī)模換取程序速度的提高
NOAREGS C51 編譯器不再使用絕對寄存器訪問程序代碼獨立于寄存器組
NOREGPARMS 參數(shù)傳遞總是在局部數(shù)據(jù)段內(nèi)而不是在專門寄存器內(nèi)進行使用pragma創(chuàng)建的程序代碼和C51編譯器PL/M-51 編譯器和ASM-51 匯編器的較早版本兼容
7.全局寄存器優(yōu)化
C51 編譯器支持寬范圍的寄存器優(yōu)化。 編譯器知道由外部函數(shù)使用的寄存器不由外部函數(shù)改變的寄存器用于寄存器變量這樣所產(chǎn)生的代碼占用更少的數(shù)據(jù)和代碼空間并且執(zhí)行得更快。
8.BL51 代碼連接/定位器
BL51 代碼連接/定位器將一個或多個目標模塊組合成一個可執(zhí)行的8051 程序。連接器還解析外部和其它共用的引用并將絕對地址分配給浮動的程序段。
BL51 代碼連接/定位器處理由Keil C51 編譯器和A51 匯編器以及Intel PL/M-51 編譯器和ASM-51匯編器所創(chuàng)建的目標模塊。BL51 自動選擇所需要的合適的庫和連接。
9.數(shù)據(jù)地址管理
BL51 連接器通過重疊不相關(guān)的函數(shù)變量管理8051 有限的內(nèi)部存儲器。對大多數(shù)8051 應(yīng)用系統(tǒng)來說極大地降低了所需要的存儲空間。
BL51 分析函數(shù)間的引用并實現(xiàn)存儲器的重疊。可以使用OVERLAY 命令人為地控制函數(shù)引用使用。NOOVERLAY 可以完全禁止存儲器重疊。當(dāng)使用間接調(diào)用函數(shù)或調(diào)試時,使用這些命令禁止重疊是很有效的。
10.代碼排序
BL51 支持創(chuàng)建大于64K 的應(yīng)用程序由于8051 不直接支持超過64K 字節(jié)的代碼地址空間,必須外部硬件交換代碼區(qū)。該硬件必須由8051 軟件進行控制。該處理稱作代碼空間切換。
BL51 可讓用戶管理一個公共區(qū)域和32 個存儲區(qū)(每個區(qū)最多可達64K 字節(jié))總共高達2M 字節(jié)的存儲空間。支持外部硬件的軟件包含一個短的匯編文件,用戶可在專門的硬件平臺上編輯。
BL51 使用戶可在指定的區(qū)域放置特定的程序模塊。謹慎地使用不同區(qū)域的分組函數(shù)可使用戶創(chuàng)建出一個大而有效的應(yīng)用程序。
11.公共區(qū)域
存儲區(qū)切換程序中的公共區(qū)域是一個所有存儲區(qū)隨時可訪問的區(qū)域。公共區(qū)域在物理上不可交換或移動。公共區(qū)域的代碼復(fù)制在每個存儲區(qū)或位于一個單獨的EPROM 區(qū)(如果公共區(qū)域沒有交換)。
公共區(qū)域包含可隨時訪問的程序段和常量。還可包含頻繁使用的代碼。默認情況下,下列為自動位于公共區(qū)域的代碼段。
12.復(fù)位和中斷向量
代碼常量
C51 中斷函數(shù)
存儲區(qū)切換跳轉(zhuǎn)表
一些C51 實時庫函數(shù)
13.其它存儲區(qū)的執(zhí)行功能
代碼存儲區(qū)由額外的軟件控制地址線進行選擇。這些地址線是由8051I/O 口線或存儲器映射鎖存器進行模擬。BL51 在其它代碼存儲區(qū)中產(chǎn)生一個函數(shù)跳轉(zhuǎn)表。當(dāng)調(diào)用不同的存儲區(qū)的函數(shù)時,程序?qū)Υ鎯^(qū)進行切換,跳轉(zhuǎn)到所需要的函數(shù),并在調(diào)用完成后回到原來的存儲區(qū)。
存儲區(qū)切換處理大約需要50 個CPU 周期和額外的兩個字節(jié)堆??臻g。通過同一存儲區(qū)中互相關(guān)聯(lián)的函數(shù)可提高系統(tǒng)的性能。多個存儲區(qū)頻繁調(diào)用的函數(shù)應(yīng)當(dāng)放置在公共區(qū)域。
C51中的關(guān)鍵字
關(guān)鍵字 用 途 說 明
auto ;存儲種類說明 ;用以說明局部變量,缺省值為此
break ;程序語句 ;退出最內(nèi)層循環(huán)
case ;程序語句 ;Switch語句中的選擇項
char ;數(shù)據(jù)類型說明 ;單字節(jié)整型數(shù)或字符型數(shù)據(jù)
const ;存儲類型說明 ;在程序執(zhí)行過程中不可更改的常量值
continue ;程序語句 ;轉(zhuǎn)向下一次循環(huán)
default ;程序語句 ;Switch語句中的失敗選擇項
do ;程序語句 ;構(gòu)成do..while循環(huán)結(jié)構(gòu)
double ;數(shù)據(jù)類型說明 ;雙精度浮點數(shù)
else ;程序語句 ;構(gòu)成if..else選擇結(jié)構(gòu)
enum ;數(shù)據(jù)類型說明 ;枚舉
extern ;存儲種類說明 ;在其他程序模塊中說明了的全局變量
flost ;數(shù)據(jù)類型說明 ;單精度浮點數(shù)
for ;程序語句 ;構(gòu)成for循環(huán)結(jié)構(gòu)
goto ;程序語句 ;構(gòu)成goto轉(zhuǎn)移結(jié)構(gòu)
if ;程序語句 ;構(gòu)成if..else選擇結(jié)構(gòu)
int ;數(shù)據(jù)類型說明 ;基本整型數(shù)
long ;數(shù)據(jù)類型說明 ;長整型數(shù)
register ;存儲種類說明 ;使用CPU內(nèi)部寄存的變量
return ;程序語句 ;函數(shù)返回
short ;數(shù)據(jù)類型說明 ;短整型數(shù)
signed ;數(shù)據(jù)類型說明 ;有符號數(shù),二進制數(shù)據(jù)的最高位為符號位
sizeof ;運算符 ;計算表達式或數(shù)據(jù)類型的字節(jié)數(shù)
static ;存儲種類說明 ;靜態(tài)變量
struct ;數(shù)據(jù)類型說明 ;結(jié)構(gòu)類型數(shù)據(jù)
swicth ;程序語句 ;構(gòu)成switch選擇結(jié)構(gòu)
typedef ;數(shù)據(jù)類型說明 ;重新進行數(shù)據(jù)類型定義
union ;數(shù)據(jù)類型說明 ;聯(lián)合類型數(shù)據(jù)
unsigned ;數(shù)據(jù)類型說明 ;無符號數(shù)數(shù)據(jù)
void ;數(shù)據(jù)類型說明 ;無類型數(shù)據(jù)
volatile ;數(shù)據(jù)類型說明 ;該變量在程序執(zhí)行中可被隱含地改變
while ;程序語句 ;構(gòu)成while和do..while循環(huán)結(jié)構(gòu)
附表1-1 ANSIC標準關(guān)鍵字
關(guān)鍵字 ;用 途 ;說 明
bit ;位標量聲明 ;聲明一個位標量或位類型的函數(shù)
sbit ;位標量聲明 ;聲明一個可位尋址變量
Sfr ;特殊功能寄存器聲明 ;聲明一個特殊功能寄存器
Sfr16 ;特殊功能寄存器聲明 ;聲明一個16位的特殊功能寄存器
data ;存儲器類型說明 ;直接尋址的內(nèi)部數(shù)據(jù)存儲器
bdata ;存儲器類型說明 ;可位尋址的內(nèi)部數(shù)據(jù)存儲器
idata ;存儲器類型說明 ;間接尋址的內(nèi)部數(shù)據(jù)存儲器
pdata ;存儲器類型說明 ;分頁尋址的外部數(shù)據(jù)存儲器
xdata ;存儲器類型說明 ;外部數(shù)據(jù)存儲器
code ;存儲器類型說明 ;程序存儲器
interrupt ;中斷函數(shù)說明 ;定義一個中斷函數(shù)
reentrant ;再入函數(shù)說明 ;定義一個再入函數(shù)
using ;寄存器組定義 ;定義芯片的工作寄存器
附表1-2 C51編譯器的擴展關(guān)鍵字
附錄二 AT89C51特殊功能寄存器列表(適用于同一架構(gòu)的芯片)
符 號 ;地 址 ;注 釋
*ACC ;E0H ;累加器
*B ;F0H ;乘法寄存器
*PSW ;D0H ;程序狀態(tài)字
SP ;81H ;堆棧指針
DPL ;82H ;數(shù)據(jù)存儲器指針低8位
DPH ;83H ;數(shù)據(jù)存儲器指針高8位
*IE ;A8H ;中斷允許控制器
*IP ;D8H ;中斷優(yōu)先控制器
*P0 ;80H ;端口0
*P1 ;90H ;端口1
*P2 ;A0H ;端口2
*P3 ;B0H ;端口3
PCON ;87H ;電源控制及波特率選擇
*SCON ;98H ;串行口控制器
SBUF ;99H ;串行數(shù)據(jù)緩沖器
*TCON ;88H ;定時器控制
TMOD ;89H ;定時器方式選擇
TL0 ;8AH ;定時器0低8位
TL1 ;8BH ;定時器1低8位
TH0 ;8CH ;定時器0低8位
TH1 ;8DH ;定時器1高8位
帶*號的特殊功能寄存器都是可以位尋址的寄存
有關(guān)C51的再入函數(shù) 重入函數(shù)
有關(guān)C51的再入函數(shù) 重入函數(shù)
重入函數(shù),又叫再入函數(shù),是一種可以在函數(shù)體內(nèi)不直接或間接調(diào)用其自身的一種函數(shù)。再入函數(shù)可被遞歸調(diào)用,無論何時,包括中斷函數(shù)在內(nèi)的任何函數(shù)都可以調(diào)入。再入函數(shù)在C51編譯時使用的是模擬棧。
{
允許被嵌套調(diào)用的函數(shù)必須是可重入函數(shù)。函數(shù)的嵌套調(diào)用是指當(dāng)一個函數(shù)正被調(diào)用尚未返回。又被本函數(shù)或其他函數(shù)再次調(diào)用,只有等到后次調(diào)用返回到了本次,本次被暫時擱置的程序才得以正確地恢復(fù)接續(xù)原來的正常運行,直到本次返回。一般的函數(shù)做不到這一點,因為它不是可重入的函數(shù)。重入函數(shù)必須具有分層保護參數(shù)和局部變量的專門重入堆棧機制,才可被嵌套調(diào)用。多任務(wù)系統(tǒng)的不同任務(wù)之間經(jīng)常發(fā)生對一個函數(shù)的嵌套調(diào)用。對于單任務(wù)系統(tǒng),本函數(shù)被直接或間接地自我遞歸調(diào)用也是函數(shù)的嵌套調(diào)用。’只有重入函數(shù)才允許嵌套調(diào)用。
重入函數(shù)不使用一般函數(shù)位于存儲模式缺省空間的覆蓋式堆棧,而是在此同一缺省空間內(nèi)從頂端另行分配一個非覆蓋的重入堆棧。它與覆蓋式堆棧相向,但自上而下地堆放。重入堆棧將嵌套調(diào)用的每層參數(shù)及局部變量一直保留到控制由深層返回本層,而又終止于本層的返回。
}
函數(shù)說明: 函數(shù)名(形式參數(shù)表) reentrant
注意事項:
1、再入函數(shù)不能傳遞bit類型參數(shù)。
2、與PL/M51兼容的函數(shù)不能具有reentrant,這樣也不能調(diào)用再入函數(shù)。
3、在編譯時:再入函數(shù)建立的是模擬堆棧區(qū),small模式下模擬堆棧區(qū)位于idata區(qū),compact模式下模擬堆棧區(qū)位于pdata區(qū),large模式下模擬堆棧區(qū)位于xdata區(qū)。
4、在同一程序中可以定義和使用不同存儲器模式的再入函數(shù),任意模式的再入函數(shù)不能調(diào)用不同存儲器模式的再入函數(shù),但可以調(diào)用普通函數(shù)。
5、實際參數(shù)可以傳遞給間接調(diào)用的再入函數(shù)。無再入屬性的間接調(diào)用函數(shù)不能包含調(diào)用參數(shù)。
6、再入函數(shù)實質(zhì)就是函數(shù)的參數(shù)傳遞用堆棧來傳,非再入函數(shù)是使用RX寄存器來傳的,在C51中是如此。
7、中斷中想用這個來解決:中斷中的函數(shù)和中斷外的函數(shù)調(diào)用時寄存器不在同一個區(qū)的時候,函數(shù)參數(shù)不能正確傳遞的問題。但吾對此持不以為然的想法。
8、中斷中使用不同的區(qū),使用using x,是為了加快速度,避免RX入棧。再入函數(shù)后,這個加快速度的優(yōu)勢蕩然無存,還不如中斷不指定using,這樣也沒必要使用再入函數(shù)。使用using又不使用再入函數(shù),才能體現(xiàn)加快速度的優(yōu)??梢詫瘮?shù)做一些處理,但這是更高深的問題,一個不小心會犯錯誤,非高手不要使用。
9、在中斷函數(shù)里一般不調(diào)用函數(shù),只處理與硬件有關(guān)的處理或者標志位的處理,然后在中斷外部定義相關(guān)的函數(shù)來檢測該標志位并進行相關(guān)處理。
10、一個函數(shù)被嵌套調(diào)用時,重入棧的空間消耗很大,對于8051微控制器應(yīng)有節(jié)制使用。
內(nèi)部函數(shù)(很多人都不知道呢)
1、內(nèi)部函數(shù)
有這樣一些函數(shù),用匯編語言編寫,非常直接、簡單而且目標碼很短;而用C語言編寫,卻目標碼很長。對于用匯編語言編寫的這類庫函數(shù)叫做內(nèi)部函數(shù)。內(nèi)部函數(shù),在C51中,已經(jīng)按C的規(guī)范用匯編語言寫好。用戶可以直接當(dāng)作C語言函數(shù)調(diào)用它們。內(nèi)部函數(shù)已經(jīng)放在庫中,供程序員使用。內(nèi)部函數(shù)的原型說明放在intrins.h頭文件中。
{
#ifndef __INTRINS_H__
#define __INTRINS_H__
extern void _nop_ (void);
extern bit _testbit_ (bit);
extern unsigned char _cror_ (unsigned char, unsigned char);
extern unsigned int _iror_ (unsigned int, unsigned char);
extern unsigned long _lror_ (unsigned long, unsigned char);
extern unsigned char _crol_ (unsigned char, unsigned char);
extern unsigned int _irol_ (unsigned int, unsigned char);
extern unsigned long _lrol_ (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
#endif
}
2、擴充內(nèi)部函數(shù)
偽本征函數(shù)—Keil C51頭文件INTRINS.H的擴容工程
/*--------------------------------------------------------------------------
INTRINS.H
Intrinsic functions for C51.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/
#ifndef __INTRINS_H__
#define __INTRINS_H__
extern void _nop_ (void);
extern bit _testbit_ (bit);
extern unsigned char _cror_ (unsigned char, unsigned char);
extern unsigned int _iror_ (unsigned int, unsigned char);
extern unsigned long _lror_ (unsigned long, unsigned char);
extern unsigned char _crol_ (unsigned char, unsigned char);
extern unsigned int _irol_ (unsigned int, unsigned char);
extern unsigned long _lrol_ (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
#endif
/*----------------------------------------------------------------------------------------
偽本征函數(shù)——Keil C51頭文件INTRINS.H的擴容工程
----------------------------------------------------------------------------------------*/
#define _setc_() CY = 1
#define _clrc_() CY = 0
#define _setb_(RBIT) RBIT = 1
#define _clrb_(RBIT) RBIT = 0
#define _clra_() ACC = 0
#define _movcb_(RBIT) CY = RBIT
#define _movbc_(RBIT) RBIT = CY
#define _movra_(RX) RX = ACC
#define _movar_(RX) ACC = RX
#define _movb0_(RBIT, RX) RBIT = RX & 0x01 //用于取RX的最低位
#define _movb7_(RBIT, RX) RBIT = RX & 0x80 //用于取RX的最高位
#define _rrca_() CY = ACC & 0x01 //產(chǎn)生RRC A指令
#define _rlca_() CY = ACC & 0x80 //產(chǎn)生RLC A指令
#define _rrcar_(RX) CY = RX & 0x01
#define _rlcar_(RX) CY = RX & 0x80
#define _xorr_(RX) RX ^= RX //用于取奇偶位P,且RX=0
#define _andr_(RX) RX &= RX //用于取奇偶位P,且RX=不變
#define _orr_(RX) RX |= RX //用于取奇偶位P,且RX=不變
#define _notr_(RX) RX =~RX
/*------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
累加器帶進位右移指令 RRC A
#define _rrca_() CY = ACC & 0x01
匯編代碼 rrc a
--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
累加器帶進位左移指令 RLC A
#define _rlca_() CY = ACC & 0x80
匯編代碼 rlc a
--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
寄存器帶進位右移指令 RRC REG
#define _rrcar_(RX) CY = RX & 0x01
#define _movra_(RX) RX = ACC
/*--------------------------------------------------------------------------
例:
C51程序
unsigned char i;
i = 0x55;
_setc_();//CY=1
_rrcar_(i);//i=0x55,ACC=0xaa,CY=1
_movra_(i);//或用i = ACC;//i=0xaa,ACC=0xaa,CY=1
匯編代碼
mov r7,#055h
setb c
mov a,r7
rrc a
mov r7,a
--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
寄存器帶進位右移指令 RRC REG
#define _rlcar_(RX) CY = RX & 0x80
#define _movra_(RX) RX = ACC
例:
C51程序
unsigned char i;
i = 0x55;
_setc_();//CY=1
_rlcar_(i);//i=0x55,ACC=0xab,CY=0
_movra_(i);//或用i = ACC;//i=0xaa,ACC=0xaa,CY=0
匯編代碼
mov r7,#055h
setb c
mov a,r7
rlc a
mov r7,a
--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
偽本征函數(shù)"匯編級"應(yīng)用
----------------------------------------------------------------------------
1.寫串行數(shù)據(jù)
C51程序
void writedata(unsigned char val)
{
_movar_(val);//或用ACC = val;
for (val = 8; val > 0; val--)
{
_clrb_(TXD);//或用TXD = 0;
_rrca_();
_movbc_(RXD);//或用RXD = CY;
_setb_(TXD);//或用TXD = 1;
_nop_();
}
}
A51代碼
writedata:
mov a,r7
mov r7,#8
writedata_loop:
clr txd
rrc a
mov rxd,c
setb txd
nop
djnz r7,writedata_loop
ret
----------------------------------------------------------------------------
2.讀串行數(shù)據(jù)
C51程序
unsigned char readdata(void)
{
unsigned char val;
for (val = 8; val > 0; val--)
{
_clrb_(TXD);//或用TXD = 0;
_nop_();
_movcb_(RXD);//或用CY = RXD;
_rrca_();
_setb_(TXD);//或用TXD = 1;
_nop_();
}
_movra_(val);//或用val = ACC;
return val;
}
A51代碼
readdata:
mov r7,#8
readdata_loop:
clr txd
nop
mov c,rxd
rrc a
setb txd
nop
djnz r7,readdata_loop
mov r7,a
ret
--------------------------------------------------------------------------*/
其他實用例子:
/*
詳解:
函數(shù)名: _crol_,_irol_,_lrol_
原 型: unsigned char _crol_(unsigned char val,unsigned char n);
unsigned int _irol_(unsigned int val,unsigned char n);
unsigned int _lrol_(unsigned int val,unsigned char n);
功 能:_crol_,_irol_,_lrol_以位形式將val 左移n 位,該函數(shù)與8051“RLA”指令
相關(guān),上面幾個函數(shù)不同于參數(shù)類型。
例:
#include
main()
{
unsigned int y;
C-5 1 程序設(shè)計 37
y=0x00ff;
y=_irol_(y,4); y=0x0ff0
}
函數(shù)名: _cror_,_iror_,_lror_
原 型: unsigned char _cror_(unsigned char val,unsigned char n);
unsigned int _iror_(unsigned int val,unsigned char n);
unsigned int _lror_(unsigned int val,unsigned char n);
功 能:_cror_,_iror_,_lror_以位形式將val 右移n 位,該函數(shù)與8051“RRA”指令
相關(guān),上面幾個函數(shù)不同于參數(shù)類型。
例:
#include
main()
{
unsigned int y;
y=0x0ff00;
y=_iror_(y,4); ////y=0x0ff0
}
函數(shù)名: _nop_
原 型: void _nop_(void);
功 能:_nop_產(chǎn)生一個NOP 指令,該函數(shù)可用作C 程序的時間比較。C51 編譯器在_nop_
函數(shù)工作期間不產(chǎn)生函數(shù)調(diào)用,即在程序中直接執(zhí)行了NOP 指令。
例:
P()=1;
_nop_();
P()=0;
函數(shù)名: _testbit_
原 型:bit _testbit_(bit x);
功 能:_testbit_產(chǎn)生一個JBC 指令,該函數(shù)測試一個位,當(dāng)置位時返回1,否則返回0。
如果該位置為1,則將該位復(fù)位為0。8051 的JBC 指令即用作此目的。
_testbit_只能用于可直接尋址的位;在表達式中使用是不允許的
*/
C51的極限值
C51的極限值
標識符最長255個字符,一般取32個字符。大小寫不敏感。 case語句的變量個數(shù)沒有限制,僅受可用內(nèi)存容量和函數(shù)的最大長度的限制。 函數(shù)嵌套調(diào)用最大深度為10。 功能塊{--------}的最大嵌套深度為15。 宏最多嵌套深度為8。 函數(shù)級宏的參數(shù)最多32個。 語句行和宏定義行最多510個字符《宏擴展后是510個字符》。 頭文件嵌套深度為20。 預(yù)處理器中的條件編譯層最多為20。 關(guān)于Intel目標模塊格式(OMF- 51)的極限值:
函數(shù)類型段總和最多255個;
全局符號(PUBLIC)最多256個;
外部符號(extern)最多25b個。
51類型等
ANSI C標準的關(guān)鍵字
關(guān) 鍵 字
用 途
說 明
auto
存儲種類說明
用以說明局部變量,缺省值為此
break
程序語句
退出最內(nèi)層循環(huán)體
case
程序語句
Switch語句中的選擇項
char
數(shù)據(jù)類型說明
單字節(jié)整形數(shù)或字符行數(shù)據(jù)
const
存儲類型說明
在程序執(zhí)行過程中不可修改的變量值
continue
程序語句
轉(zhuǎn)向下一次循環(huán)
default
程序語句
Switch語句中的失敗選擇項
do
程序語句
構(gòu)成do…while循環(huán)結(jié)構(gòu)
double
數(shù)據(jù)類型說明
雙精度浮點數(shù)
else
程序語句
構(gòu)成if…else選擇結(jié)構(gòu)
enum
數(shù)據(jù)類型說明
枚舉
extern
存儲類型說明
在其它程序中說明了的全局變量
float
數(shù)據(jù)類型說明
單精度浮點數(shù)
for
程序語句
構(gòu)成for循環(huán)結(jié)構(gòu)
got
程序語句
構(gòu)成goto轉(zhuǎn)移結(jié)構(gòu)
if
程序語句
構(gòu)成if…else選擇結(jié)構(gòu)
int
數(shù)據(jù)類型說明
基本整形數(shù)
long
數(shù)據(jù)類型說明
長整形數(shù)
register
存儲類型說明
使用CPU內(nèi)部寄存器的變量
return
程序語句
函數(shù)返回
short
數(shù)據(jù)類型說明
短整形數(shù)
signed
數(shù)據(jù)類型說明
有符號數(shù),二進制數(shù)據(jù)的最高位為符號位
sizeof
運算符
計算表達式或數(shù)據(jù)類型的字節(jié)數(shù)
static
存儲類型說明
靜態(tài)變量
struct
數(shù)據(jù)類型說明
結(jié)構(gòu)類型數(shù)據(jù)
switch
程序語句
構(gòu)成switch選擇結(jié)構(gòu)
typedef
數(shù)據(jù)類型說明
重新進行數(shù)據(jù)類型定義
union
數(shù)據(jù)類型說明
聯(lián)合類型數(shù)據(jù)
unsigned
數(shù)據(jù)類型說明
無符號數(shù)據(jù)
viod
數(shù)據(jù)類型說明
無類型數(shù)據(jù)
volatile
數(shù)據(jù)類型說明
說明該變量在程序執(zhí)行中可被隱含地改變
while
程序語句
構(gòu)成while和do…while循環(huán)結(jié)構(gòu)
C51編譯器的擴展關(guān)鍵字
關(guān) 鍵 字
用 途
說 明
bit
位標量聲明
聲明一個位標量或位類型的函數(shù)
sbit
位變量聲明
聲明一個可位尋址變量
sfr
特殊功能寄存器聲明
聲明一個特殊功能寄存器(8位)
sfr16
特殊功能寄存器聲明
聲明一個特殊功能寄存器(16位)
data
存儲器類型說明
直接尋址的8051內(nèi)部數(shù)據(jù)存儲器
bdata
存儲器類型說明
可位尋址的8051內(nèi)部數(shù)據(jù)存儲器
idata
存儲器類型說明
間接尋址的8051內(nèi)部數(shù)據(jù)存儲器
pdata
存儲器類型說明
“分頁”尋址的8051外部數(shù)據(jù)存儲器
xdata
存儲器類型說明
8051外部數(shù)據(jù)存儲器
code
存儲器類型說明
8051程序存儲器
interrupt
中斷函數(shù)聲明
定義一個中斷函數(shù)
reentrant
再入函數(shù)聲明
定義一個再入函數(shù)
using
寄存器組定義
定義8051的工作寄存器組
Franklin C51編譯器能夠識別的數(shù)據(jù)類型
數(shù)據(jù)類型
長 度
值 域
unsigned char
單字節(jié)
0~255
signed char
單字節(jié)
-128~127
unsigned int
雙字節(jié)
0~65536
signed int
雙字節(jié)
-32768~32767
unsigned long
四字節(jié)
0~4294967295
signed long
四字節(jié)
-2147483648~2147483647
float
四字節(jié)
±1.175494E-38~±3.402823E+38
*
1~3字節(jié)
對象的地址
bit
位
0或1
sfr
單字節(jié)
0~255
sfr16
雙字節(jié)
0~65536
sbit
位
0或1
常用轉(zhuǎn)移字符表
轉(zhuǎn) 移 字 符
含 義
ASCII碼(16進制數(shù))
\0
空字符(NULL)
00H
\n
換行符(LF)
0AH
\r
回車符(CR)
0DH
\t
水平制表符(HT)
09H
\b
退格符(BS)
08H
\f
換頁符(FF)
0CH
\’
單引號
27H
\”
雙引號
22H
\\
反斜杠
5CH
Franklin C51編譯器所能識別的存儲器類型
存儲器類型
data
可直接訪問內(nèi)部數(shù)據(jù)存儲器(128字節(jié)),訪問速度最快。
bdata
可位尋址內(nèi)部數(shù)據(jù)存儲器(16字節(jié)),允許位與字節(jié)混合訪問。
idata
間接訪問內(nèi)部數(shù)據(jù)存儲器(256字節(jié)),允許訪問全部內(nèi)部地址。
pdata
“分頁”訪問外部數(shù)據(jù)存儲器(256字節(jié)),用MOVX @Ri指令訪問。
xdata
外部數(shù)據(jù)存儲器(64K字節(jié)),用MOVX @DPTR指令訪問。
code
程序存儲器(64K字節(jié)),用MOVC @A+DPTR指令訪問。
運算賦與表達式
類
運 算 符
說 明
運 算 符
賦值運算符
=
算術(shù)運算符
+
加或取正值運算符
-
減或取負值運算符
*
乘運算符
/
除運算符
%
取余運算符
增量和減量運算符
++
增量運算符
--
減量運算符
關(guān)系運算符
>
大于
>
小于
>=
大于等于
<=
小于等于
==
等于
!=
不等于
邏輯運算符
||
邏輯“或”
&&
邏輯“與”
!
邏輯“非”
位運算符
~
按位“取反”
<<
左移
>>
右移
&
按位“與”
^
按位“異或”
|
按位“或”
復(fù)合賦值運算符
+=
加法賦值
-=
減法賦值
*=
乘法賦值
/=
除法賦值
%=
取模賦值
<<=
左移位賦值
>>=
右移位賦值
&=
邏輯“與”賦值
|=
邏輯“或”賦值
^=
邏輯“異或”賦值
~=
邏輯“非”賦值
逗號運算符
,
條件運算符
?:
指針和地址運算賦
*
&
強制類型轉(zhuǎn)換運算符<span
指針和地址運算賦
*
&
強制類型轉(zhuǎn)換運算符
()
sizeof
sizeof
語 句
表達式語句
表達式;
復(fù)合語句
{
}
條件語句
if
else
開關(guān)語句
switch
case
循環(huán)語句
while
do…while語句
do
while
for語句
for
goto語句
goto
continue語句
continue
return語句
return
flags標志符及其意義
flags
意 義
*
輸入被忽略
b,h
用作格式類型d,I,o,u和x的前綴,輸入數(shù)據(jù)為char型
l
用作格式類型d,I,o,u和x的前綴,輸入數(shù)據(jù)為long型
輸出格式轉(zhuǎn)換字符type的內(nèi)容和定義
type字 符
數(shù) 據(jù) 類 型
輸 入 格 式
d
int指針
帶符號十進制數(shù)
u
int指針
無符號十進制數(shù)
o
int指針
無符號八進制數(shù)
x
int指針
無符號十六進制數(shù)
f,e,g
float指針
浮點數(shù)
c
char指針
字符
s
string指針
字符串
本頁上的內(nèi)容是
Google 筆記本用戶提供的,Google 對這些內(nèi)容不負任何責(zé)任。