Keil C51 特定功能
1. 如何產生 'RLC A' 指令: (Keil C51 適用)
CY = ACC & 0X80;
那 RRC A 呢? 還沒找到, 只能先用 {asm}
2. 如何把 C51 程式移值到別的 CPU 架構?
在 header file 中定義類似以下的 define, 同時程式中只能用這些定義 (也就是把程式中的 data, xdata... 先都改成 _DATA_, _XDATA_, ...). 因為別的 CPU 沒有這些 '記憶體空間修飾字'.
註:
- 我把 _BIT_ 定義成: 不是用 KEIL_C51 時轉成 BOOL 但使用 KEIL_C51 時, 對應到 bit. 建議你在 C51 的程式中 (變數或函式回傳值) 明確的區分 _BIT_ 和 BOOL, 因為用 bit 可以讓你的程式小一些, 也快一些. (但是 bit 只有 128 個, 所以要區分一下)
- reentrant 是 Keil C51 特有的修飾字.
typedef unsigned char BOOL
// While the compiler is not Keil C51,
// Comment out the following line
#define KEIL_C51
#ifdef KEIL_C51
#define _BIT_ bit
#define _BDATA_ bdata
#define _DATA_ data
#define _IDATA_ idata
#define _XDATA_ xdata
#define _CODE_ code
#define _FAR_ far
#define _REENTRANT_ reentrant
#else
#define _BIT_ BOOL
#define _BDATA_
#define _DATA_
#define _IDATA_
#define _XDATA_
#define _CODE_
#define _FAR_
#define _REENTRANT_
#endif
3. 如何消除 Keil C51 對未使用之函數參數之告警
無法以修改原型宣告的方式來取消函數之未用參數, 但又想消除 Keil C51 編譯它所產生的告警時, 可以用如下的方法:
#define UNUSED(x) if(x){}
void f(int x, int y) {
UNUSED(x); // x 是沒有用到的參數
...
}
4. 如何指定 Keil C51 指標變數 所使用的記憶體空間
由於 8051 的記憶體可分為 程式空間(code space)及資料空間(data space), 資料空間又有
- 外部記憶體
- 可直接定址的內部暫存器
- 只能間接定址的內部暫存器
- 特殊功能暫存器
你可以依據實際上的需要把變數安置在不同的記憶體中. 所以,定義指標變數來指向這些變數時問題會有一點複雜.
一般變數的宣告語法:
Data_type [Variable_Memory_Space] Variable_name;
指標變數的宣告語法:
Data_type [Data_type_Memory_Space] * [Variable_Memory_Space] Variable_name;
Example:
Keil C51 指定指標變數所使用的記憶體空間
[Data_type_Memory_Space]及[Variable_Memory_Space]是多出來的記憶體空間修飾字, 一般的 C 語言沒有這二個修飾字(所以需要移值到別的 CPU 需要利用上面第二點所提的方法)
- [Data_type_Memory_Space] 是指定指標變數指到哪一種記憶體空間
- [Variable_Memory_Space] 是指定(指標/一般)變數本身所在的記憶體空間
所以, 我們可以依據需要把上面的 [Data_type_Memory_Space] 及 [Variable_Memory_Space] 換成下表中的修飾字, 或者是空白. 如果是用空白的話, 就是使用預設值. 各種變數依照你使用的記憶體模型 (memory model) 不同, 有不同的預設值. 另外, 如果 [Data_type_Memory_Space] 是空白的話, 意指該指標變數是通用指標, 也就是這個指標可以指向任何一種記憶體空間.
Keil C51 所支援的記憶體空間修飾字:
修飾字 | 範圍 | 說明 |
---|---|---|
code | 64KB | accessed by MOVC @A+DPTR , program memory |
data | 128B | direct accessable, internal data memory |
idata | 256B | indirect accessable, internal data memory, access by MOV @Rn |
bdata | 16B | bit-addressable internal data memory |
xdata | 64KB | external data memory |
far | 16MB | extended RAM/ROM memory (DS390擴充) |
pdata | 256B | accessed by MOVX @Rn , external data memory |
model | 函數參數及 |
預設 |
預設 |
預設指標 |
---|---|---|---|---|
small | data | data | data | 3 Bytes |
compact | pdata | pdata | pdata | 3 Bytes |
large | xdata | xdata | xdata | 3 Bytes |
類別 | 有效定址範圍 | SIZE |
---|---|---|
BIT | I:000020h.0~I:00002Fh.7 | 128bit |
CODE | C:000000h ~C:00FFFFh | 64KB |
CONST | C:000000h ~C:00FFFFh | 64KB |
SROM | C:000000h ~C:00FFFFh | 64KB |
ECODE | C:000000h ~C:FFFFFFh | 16MB |
HCONST | C:000000h ~C:FFFFFFh | 16MB |
DATA | D:000000h ~D:00007Fh | 128B |
IDATA | D:000000h ~D:0000FFh | 256B |
XDATA | X:000000h ~X:00FFFFh | 64KB |
HDATA | X:000000h ~X:FFFFFFh | 16MB |
語法 | 變數指向 | 變數存放在 |
---|---|---|
unsigned char xdata * data ptr; | 外部記憶體 | 內部記憶體 |
unsigned char data * xdata ptr; | 內部記憶體 | 外部記憶體 |
unsigned char code * xdata ptr; | 程式記憶體 | 外部記憶體 |
unsigned char code * code ptr; | 程式記憶體 | 程式記憶體,唯讀,必須先設定初始值。 |
通用指標用法:(generic pointer) | ||
unsigned char * xdata ptr; | 任何記憶體 | 外部記憶體 |
unsigned char * ptr; | 任何記憶體 | 由 memory model 決定 |
函數指標變數用法:只能指向程式記憶體空間。 | ||
char (* data fptr)(void); | 程式記憶體 | 內部記憶體 |
備註: 由於內部記憶體指標讀取都是使用間接定址 (indirect addressing),所以無法存取 SFR 空間的記憶體內容。 |
指標變數佔用的記憶體大小是由其所指向的記憶體空間決定
指標變數指向 | 大小 |
---|---|
data | 1 Byte |
xdata | 2 Bytes |
code | 2 Bytes |
generic pointer | 3 Bytes |
generic pointer 是設計用來可以做通用指標變數使用,可以任意變換指標指向任何一種位址空間 (data, idata, xdata, hdata, code, ecode, ...),但是相對的需要佔用 3 個 bytes 的位置,而且在做讀取寫入時,需要另外執行一個函數來轉換位址,沒必要就少用一點吧。
留言列表