導航:首頁 > 源碼編譯 > keilc51編譯鍵

keilc51編譯鍵

發布時間:2022-05-16 14:31:46

❶ 「Keil C51」下如何讓編譯器優先使用片內「RAM」

C51內存結構深度剖析
在編寫應用程序時,定義一個變數,一個數組,或是說一個固定表格,到底存儲在什麼地方;當定義變數大小超過MCU的內存范圍時怎麼辦;如何控制變數定義不超過存儲范圍;以及如何定義變數才能使得變數訪問速度最快,寫出的程序運行效率最高。以下將一一解答。

1 六類關鍵字(六類存儲類型)
data idata xdata pdata code bdata

code: code memory (程序存儲器也即只讀存儲器)用來保存常量或是程序。code memory 採用16位地址線編碼,可以是在片內,或是片外,大小被限制在64KB
作用:定義常量,如八段數碼表或是編程使用的常,在定義時加上code 或明確指明定義的常量保存到code memory(只讀)
使用方法:
char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
此關鍵字的使用方法等同於const

data data memory (數據存儲區)只能用於聲明變數,不能用來聲明函數,該區域位於片內,採用8位地址線編碼,具有最快的存儲速度,但是數量被限制在128byte或更少。
使用方法:
unsigned char data fast_variable=0;

idata idata memory(數據存儲區)只能用於聲明變數,不能用來聲明函數. 該區域位於片內,採用8位地址線編碼,內存大小被限制在256byte或更少。該區域的低地址區與data memory地址一致;高地址區域是52系列在51系列基礎上擴展的並與特殊功能寄存器具有相同地址編碼的區域。即:data memory是idata memory的一個子集。

xdata xdata memory 只能用於聲明變數,不能用來聲明函數,該區域位於MCU
外部,採用16位地址線進行編碼,存儲大小被限制在64KB以內。
使用方法:
unsigned char xdata count=0;

pdata pdata memory 只能用於聲明變數,不能用來聲明函數,該區域位於MCU外部,採用8位地址線進行編碼。存儲大小限制在256byte. 是xdata memory的低256byte。為其子集。
使用方法
unsigned char pdata count=0;

bdata bdata memory 只能用於聲明變數,不能用來聲明函數。該區域位於8051內部位數據地址。定義的量保存在內部位地址空間,可用位指令直接讀寫。
使用方法:
unsigned char bdata varab=0

註:有些資料講,定義字元型變數時,在預設unsigned 時,字元型變數,默認為無符號,與標准C不同,但我在Keil uVision3中測試的時候發現並非如此。在預設的情況下默認為有符號。或許在以前的編譯器是默認為無符號。所以看到有的資料上面這樣講的時候,要注意一下,不同的編譯器或許不同。所以我們在寫程序的時候,還是乖乖的把unsigned signed 加上,咱也別偷這個懶。
2函數的參數和局部變數的存儲模式
C51 編譯器允許採用三種存儲器模式:SMALL,COMPACT 和LARGE。一個函數的存儲器模式確定了函數的參數的局部變數在內存中的地址空間。處於SMALL模式下的函數參數和局部變數位於8051單片機內部RAM中,處於COMPACT和LARGE模式下的函數參數和局部變數則使用單片機外部RAM。在定義一個函數時可以明確指定該函數的存儲器模式。方法是在形參表列的後面加上一存儲模式。

示例如下:
#pragma large //此預編譯必須放在所有頭文前面
int func0(char x,y) small;
char func1(int x) large;
int func2(char x);
註:
上面例子在第一行用了一個預編譯命令#pragma 它的意思是告訴c51編譯器在對程序進行編譯時,按該預編譯命令後面給出的編譯控制指令LARGE進行編譯,即本常式序編譯時的默認存儲模式為LARGE.隨後定義了三個函數,第一個定義為SMALL存儲模式,第二個函數定義為LARGE第三個函數未指定,在用C51進行編譯時,只有最後一個函數按LARGE存儲器模式處理,其它則分別按它們各自指定的存儲器模式處理。
本例說明,C51編譯器允許採用所謂的存儲器混合模式,即允許在一個程序中將一些函數使用一種存儲模式,而其它一些則按另一種存儲器模式,採用存儲器混合模式編程,可以充分利用8051系列單片機中有限的存儲器空間,同時還可以加快程序的執行速度。

3絕對地址訪問 absacc.h(相當重要)

#define CBYTE ((unsigned char volatile code *) 0)
#define DBYTE ((unsigned char volatile data *) 0)
#define PBYTE ((unsigned char volatile pdata *) 0)
#define XBYTE ((unsigned char volatile xdata *) 0)
功能:CBYTE 定址 CODE區
DBYTE 定址 DATA區
PBYTE 定址 XDATA(低256)區
XBYTE 定址 XDATA區
例: 如下指令在對外部存儲器區域訪問地址0x1000
xvar=XBYTE[0x1000];
XBYTE[0x1000]=20;

#define CWORD ((unsigned int volatile code *) 0)
#define DWORD ((unsigned int volatile data *) 0)
#define PWORD ((unsigned int volatile pdata *) 0)
#define XWORD ((unsigned int volatile xdata *) 0)

功能:與前面的一個宏相似,只是它們指定的數據類型為unsigned int .。
通過靈活運用不同的數據類型,所有的8051地址空間都是可以進行訪問。

DWORD[0x0004]=0x12F8;
即內部數據存儲器中(0x08)=0x12; (0x09)=0xF8

註:用以上八個函數,可以完成對單片機內部任意ROM和RAM進行訪問,非常方便。還有一種方法,那就是用指鍾,後面會對C51的指針有詳細的介紹。

4寄存器變數(register)
為了提高程序的執行效率,C語言允許將一些頻率最高的那些變數,定義為能夠直接使用硬體寄存器的所謂的寄存器變數。定義一個變數時,在變數類型名前冠以「register」 即將該變數定義成為了寄存器變數。寄存器變數可以認為是一自動變數的一種。有效作用范圍也自動變數相同。由於計算機寄存器中寄存器是有限的。不能將所有變數都定義成為寄存器變數,通常在程序中定義寄存器變數時,只是給編譯器一個建議,該變數是否真正成為寄存器變數,要由編譯器根據實際情況來確定。另一方面,C51編譯器能夠識別程序中使用頻率最高的變數,在可能的情況下,即使程序中並未將該變數定義為寄存器變數,編譯器也會自動將其作為寄存器變數處理。被定義的變數是否真正能成為寄存器變數,最終是由編譯器決定的。

5內存訪問雜談
1指鍾
指鍾本身是一個變數,其中存放的內容是變數的地址,也即特定的數據。8051的地址是16位的,所以指針變數本身佔用兩個存儲單元。指針的說明與變數的說明類似,僅在指針名前加上「*」即可。
如 int *int_point; 聲明一個整型指針
char *char_point; 聲明一個字元型指針
利用指針可以間接存取變數。實現這一點要用到兩個特殊運算符
& 取變數地址
* 取指針指向單元的數據

示例一:
int a,b;
int *int_point; //定義一個指向整型變數的指針
a=15;
int_point=&a; //int_point指向 a
*int_point=5; //給int_point指向的變數a 賦值5 等同於a=5;
示例二:
char i,table[6],*char_point;
char_point=table;
for(i=0;i<6;i++)
{
char_point=i;
char_point++;
}
註:
指針可以進行運算,它可以與整數進行加減運算(移動指針)。但要注意,移動指針後,其地址的增減量是隨指針類型而異的,如,浮點指針進行自增後,其內部將在原有的基礎上加4,而字元指針當進生自增的時候,其內容將加1。原因是浮點數,佔4個內存單元,而字元佔一個位元組。

宏晶科技最新一代STC12C5A360S2系列,每一個單片機出廠時都有全球唯一身份證號碼(ID號),用戶可以在單片機上電後讀取內部RAM單元F1H~F7H的數值,來獲取此單片機的唯一身份證號碼。使用MOV @Ri 指令來讀取。下面介紹C51 獲取方法:
char id[7]={0};
char i;
char idata *point;
for(i=0;i<7;i++)
{
id[i]=*point;
point++;
}

(此處只是對指針做一個小的介紹,達到訪問內部任何空間的方式,後述有對指針使用的詳細介紹)
2對SFR,RAM ,ROM的直接存取
C51提供了一組可以直接對其操作的擴展函數
若源程序中,用#include包含頭文件,io51.h 後,就可以在擴展函數中使用特殊功能寄存器的地址名,以增強程序的可讀性:

注 此方法對SFR,RAM,ROM的直接存取不建議使用.因為,淡io51.h這個頭文件在KEIL中無法打開,可用指針,或是採用absacc.h頭文件,

❷ keil c51 編譯C語言 怎麼單步執行 那個鍵子在哪啊

Debug--找到圖中所示按鈕即為單步運行

❸ 如何使用KeilC51創建一個工程文件

如何使用KeilC51創建一個工程文件

建立一個項目:

點擊工程菜單中選擇彈出的下拉式菜單中的新建 工程...,接著彈出一個標准Windows文件對話窗口,在"文件名"中輸入您的第一個程序項目名稱,這里我們用"test",這是筆者慣用的名稱,大家不必照搬就是了,只要符合Windows文件規則的文件名都行。"保存"後的文件擴展名為uv2,這是KEIL uVision2項目文件擴展名,以後我們可以直接點擊此文件以打開先前做的項目。

這時會彈出讓你選擇單片機型號的對話框,我們選擇ATMEL---AT89C51

然後點擊Target 1前面的「+」,出現Source Group 1,選中右鍵點選「增加文件到組 Source Group 1」

這時選擇文件類型為Asm 源文件,再選中001.asm文件,再按添加,在隨後出現的提示框中按「確定」

模擬器採用Mon51協議,在使用之前應必須對軟體項目進行如下設置:

1、單擊工程菜單,再在下拉菜單中單擊"目標target 1屬性" 在下圖中,單擊"Target"輸入模擬器的工作頻率(11.0592MHz)。

2、在調試菜單中點選"Keil Monitor-51 Driver",即選擇了STC89C516RD硬體模擬器。

3、單擊「R外圍設備」選Target Setup設置選項選擇您要使用串口(必須和實際相符合),波特率 38400。

如果被模擬的目標板使用12MHZ或者是11.0592MHZ晶振時波特率選擇38400,如果被模擬的目標板使用6MHZ晶振時波特率選擇18400。

4、如果需要生成HEX代碼給編程器燒寫晶元的話,需要選中「生成 HEX 文件」的選項,按鈕「選擇OBJ文件夾...」是用來選擇最終HEX文件的存放目錄的。

5、按F7快捷鍵可以進行編譯,編譯成功後如會出現上圖紅箭頭所指的文字,表示編譯成功!

然後可以進行硬體模擬了,將模擬器放入51單片機試驗開發板的40腳活動插座中,這時模擬器的電源由實驗開發板提供。

現在按Ctrl+F5可以進入模擬,這時再按F5全速運行狀態。

這時你會看到實驗板開發板P1的八個紅色LED,輪流點亮,表示運行成功,你可以查看相關的變數和參數,非常方便,這里我們完整演示一個匯編語言的模擬過程,其實KEIL C最擅長的還是C語言,建議有基礎的網友盡量採用C語言。

當首次使用一新的工程調試時可能出現下面的界面,說明KEIL軟體和模擬器之間通訊失敗,原因是你尚未

設定好串口及波特率。

請按選Settings然後按下圖設好串口(根據你的實際使用埠,以下假定為COM1)及波特率。

然後按F7,進行通訊連接,再按Ctrl+F5可以進入模擬,這時再按F5全速運行狀態。

❹ keil裡面編譯的c51問題

你注意以下幾個關鍵點:
uint ad_covert() //
{
uint temp1,temp2;

temp1=258;
return (temp1); //返回AD轉換數據 取八位結果
}

這些,都沒有問題,如果正常的話,函數永遠返回的是 常數258,.
但是,如果你的 result 定義成 uchar類型的,那麼,result的結果就永遠都是2.
因為uchar類型的數據,是8位數據,最大的數是 255,所以,對於大於 255的數字,就相當於對256取余數,因為你的函數永遠返回 258,大於 255,所以對256取余數的結果是 2。
這就是為什麼總是 2的原因,如果你的result定義成 uint類型,那麼,結果就永遠是 258.

❺ KEIL C51的編譯指令#pragma noiv什麼意思

這樣的問題直接查軟體的幫助就可以找到啊。

編譯指令NOIV
默認值:INTVECTOR(0)
描述:NOIV(NOINTVECTOR)編譯指令會抑制生成中斷向量。藉助這個編譯指令,用戶可以採用其它的編程工具產生中斷向量,從而與本軟體聯合使用。

❻ 關於Keil C51編譯的問題

COMMON.C(1): warning C500: LICENSE ERROR (R208: RENEW LICENSE ID CODE (LIC))
好像是說注冊錯誤,要裝破解版;
MAIN.C(9): error C202: 'TRO': undefined identifier第九行錯誤,應是TR0, O與0應區分

❼ keil C51程序編譯的問題

如果你的H頭文件包含在每個.C文件中,那就是說你的每個.C文件都定義了sbuf[20],KEIL就會提示你說你的sbuff[20]重復定義。我理解的應該是這個問題吧?

解決辦法,要麼用條件編譯區分sbuff的作用域,就是在哪些.c文件中使用。
要麼在一個.c文件中定義sbuff,在H文件中用外部聲明包含進去,比如:
extern unsigned char data char sbuf[20];這樣在其他的.C文件中,sbuff是引用而不是定義了。

一般都是採用第二種方式,H文件只存放外部聲明。

❽ Keil C51編譯的問題!

你主程序里沒有別的程序代碼了?
單片機在編譯時,首先是進行編譯預處理(頭文件包括指令,宏定義處理,條件編譯,各種偽指令等),然後再進入優化編譯階段,再進行匯編過程,接著是程序鏈接。

你在主程序中定義,unsigned char a[2]={1,2};數組,並分配兩個存儲單元。雖然在語法上是沒有錯,程序也能正確被編譯。但程序在真正進行實質鏈接時,由於你並沒有真正進行功能性的程序指定,編譯時它會生成很多冗餘的匯編代碼,按照你定義的單元。上面生成的匯編,你如果仔細看,很多的條件跳轉語句都是轉到不同的內存單元。如:
DJNZ R7,C:001F //R7寄存器相減為0則轉到001F,否則順序執行。
DJNZ R7,C:004B
DJNZ R7,C:003F
INC DPTR
F2 MOVX @R0,A
INC R0
DJNZ R7,C:004B
而實際,編寫程序,也沒有你以上的那種做法,不可能只分配內存單元,而不做任何其它事情。我想,你這樣做,無非就是想做個實驗罷了。

❾ KEIL C51多文件編譯

首先主函數只能存在於一個文件中,這個文件可以直接取名mian.c這樣比較方便管理。然後按功能分其它文件,分別編寫XX.h和XX.c文件,在XX.h中寫入函數的聲明和全局變數的定義,在XX.c中寫函數的具體內容,並且在XX.c中要include「XX.h」,在mian.c中include所有的.h文件。這樣就可以正常編譯和燒寫了。最終生成的還是一個hex文件

閱讀全文

與keilc51編譯鍵相關的資料

熱點內容
ubuntu壓縮zip 瀏覽:2
vigenere演算法的方法是什麼 瀏覽:666
pdf保護破解 瀏覽:341
仿微信聊天系統源碼廣州公司 瀏覽:106
怎麼查看我的世界伺服器日誌 瀏覽:430
怎麼從程序員走到成功 瀏覽:824
把軟體放入文件夾中如何移出 瀏覽:209
紅包源碼企業即時聊天軟體 瀏覽:581
xp安裝python 瀏覽:10
西門子參數編程讀取半徑值 瀏覽:403
洗首飾解壓小視頻 瀏覽:966
01背包問題的演算法解決 瀏覽:373
sd卡放哪個文件夾 瀏覽:301
解釋器模式java 瀏覽:104
android垂直自動滾動條 瀏覽:153
計算器java小程序 瀏覽:27
java的簡稱 瀏覽:68
雲伺服器公網ip地址 瀏覽:581
php對資料庫操作 瀏覽:237
java爬圖片 瀏覽:866