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:

Memory Space Modifier

[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 所支援的記憶體空間修飾字:

Memory Space: (of Data type or Variable)
修飾字 範圍 說明
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

Keil C51 支援三種記憶體模型, 預設使用的記憶體空間
model 函數參數及自動變數 預設全體變數 預設常數 預設指標佔用空間
small data data data 3 Bytes
compact pdata pdata pdata 3 Bytes
large xdata xdata xdata 3 Bytes

LX51連結器認識的 記憶體類別(classes)
類別 有效定址範圍 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 的位置,而且在做讀取寫入時,需要另外執行一個函數來轉換位址,沒必要就少用一點吧。

    MagicJackTing 發表在 痞客邦 留言(3) 人氣()