<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          KeilC51使用詳解 (二)

          作者: 時(shí)間:2016-11-18 來(lái)源:網(wǎng)絡(luò) 收藏
          第三章 Keil C51 vs 標(biāo)準(zhǔn)C

          深入理解并應(yīng)用C51對(duì)標(biāo)準(zhǔn)ANSIC的擴(kuò)展是學(xué)習(xí)C51的關(guān)鍵之一。因?yàn)榇蠖鄶?shù)擴(kuò)展功能都是直接針對(duì)8051系列CPU硬件的。大致有以下8類:l 8051存儲(chǔ)類型及存儲(chǔ)區(qū)域l 存儲(chǔ)模式l 存儲(chǔ)器類型聲明l 變量類型聲明l 位變量與位尋址l 特殊功能寄存器(SFR)l C51指針l 函數(shù)屬性具體說(shuō)明如下(8031為缺省CPU)。

          本文引用地址:http://www.ex-cimer.com/article/201611/315904.htm

          第一節(jié) Keil C51擴(kuò)展關(guān)鍵字

          C51 V4.0版本有以下擴(kuò)展關(guān)鍵字(共19個(gè)):_at_ idata sfr16 alien interrupt smallbdata large _task_ Code bit pdatausing reentrant xdata compact sbit data sfr

          第二節(jié) 內(nèi)存區(qū)域(Memory Areas):

          1. Pragram Area:

          由Code說(shuō)明可有多達(dá)64kBytes的程序存儲(chǔ)器

          2. Internal Data Memory:

          內(nèi)部數(shù)據(jù)存儲(chǔ)器可用以下關(guān)鍵字說(shuō)明:data:直接尋址區(qū),為內(nèi)部RAM的低128字節(jié) 00H~7FHidata:間接尋址區(qū),包括整個(gè)內(nèi)部RAM區(qū) 00H~FFHbdata:可位尋址區(qū), 20H~2FH

          3. External Data Memory

          外部RAM視使用情況可由以下關(guān)鍵字標(biāo)識(shí):xdata:可指定多達(dá)64KB的外部直接尋址區(qū),地址范圍0000H~0FFFFHpdata:能訪問(wèn)1頁(yè)(25bBytes)的外部RAM,主要用于緊湊模式(Compact Model)。

          4. Speciac Function Register Memory

          8051提供128Bytes的SFR尋址區(qū),這區(qū)域可位尋址、字節(jié)尋址或字尋址,用以控制定時(shí)器、計(jì)數(shù)器、串口、I/O及其它部件,可由以下幾種關(guān)鍵字說(shuō)明:sfr:字節(jié)尋址 比如 sfr P0=0x80;為PO口地址為80H,“=”后H~FFH之間的常數(shù)。sfr16:字尋址,如sfr16 T2=0xcc;指定Timer2口地址T2L=0xcc T2H=0xCDsbit:位尋址,如sbit EA=0xAF;指定第0xAF位為EA,即中斷允許還可以有如下定義方法:sbit 0V=PSW^2;(定義0V為PSW的第2位)sbit 0V=0XDO^2;(同上)或bit 0V-=0xD2(同上)。

          第三節(jié) 存儲(chǔ)模式

          存儲(chǔ)模式?jīng)Q定了沒(méi)有明確指定存儲(chǔ)類型的變量,函數(shù)參數(shù)等的缺省存儲(chǔ)區(qū)域,共三種:

          1. Small模式

          所有缺省變量參數(shù)均裝入內(nèi)部RAM,優(yōu)點(diǎn)是訪問(wèn)速度快,缺點(diǎn)是空間有限,只適用于小程序。

          2. Compact模式

          所有缺省變量均位于外部RAM區(qū)的一頁(yè)(256Bytes),具體哪一頁(yè)可由P2口指定,在STARTUP.A51文件中說(shuō)明,也可用pdata指定,優(yōu)點(diǎn)是空間較Small為寬裕速度較Small慢,較large要快,是一種中間狀態(tài)。

          3. large模式

          所有缺省變量可放在多達(dá)64KB的外部RAM區(qū),優(yōu)點(diǎn)是空間大,可存變量多,缺點(diǎn)是速度較慢。提示:存儲(chǔ)模式在C51編譯器選項(xiàng)中選擇。

          第四節(jié) 存儲(chǔ)類型聲明

          變量或參數(shù)的存儲(chǔ)類型可由存儲(chǔ)模式指定缺省類型,也可由關(guān)鍵字直接聲明指定。各類型分別用:code,data,idata,xdata,pdata說(shuō)明,例:data uar1char code array[ ]=“hello!”;unsigned char xdata arr[10][4][4];

          第五節(jié) 變量或數(shù)據(jù)類型

          C51提供以下幾種擴(kuò)展數(shù)據(jù)類型:bit 位變量值為0或1sbit 從字節(jié)中定義的位變量 0或1sfr sfr字節(jié)地址 0~255sfr16 sfr字地址 0~65535其余數(shù)據(jù)類型如:char,enum,short,int,long,float等與ANSI C相同。

          第六節(jié) 位變量與聲明

          1. bit型變量

          bit型變量可用變量類型,函數(shù)聲明、函數(shù)返回值等,存貯于內(nèi)部RAM20H~2FH。注意:(1) 用#pragma disable說(shuō)明函數(shù)和用“usign”指定的函數(shù),不能返回bit值。(2) 一個(gè)bit變量不能聲明為指針,如bit *ptr;是錯(cuò)誤的(3) 不能有bit數(shù)組如:bit arr[5];錯(cuò)誤。

          2. 可位尋址區(qū)說(shuō)明20H-2FH

          可作如下定義:int bdata i;char bdata arr[3],然后:sbit bito=in0;sbit bit15=I^15;sbit arr07=arr[0]^7;sbit arr15=arr[i]^7;

          第七節(jié) Keil C51指針

          C51支持一般指針(Generic Pointer)和存儲(chǔ)器指針(Memory_Specific Pointer).

          1. 一般指針

          一般指針的聲明和使用均與標(biāo)準(zhǔn)C相同,不過(guò)同時(shí)還可以說(shuō)明指針的存儲(chǔ)類型,例如:long * state;為一個(gè)指向long型整數(shù)的指針,而state本身則依存儲(chǔ)模式存放。char * xdata ptr;ptr為一個(gè)指向char數(shù)據(jù)的指針,而ptr本身放于外部RAM區(qū),以上的long,char等指針指向的數(shù)據(jù)可存放于任何存儲(chǔ)器中。一般指針本身用3個(gè)字節(jié)存放,分別為存儲(chǔ)器類型,高位偏移,低位偏移量。

          2. 存儲(chǔ)器指針

          基于存儲(chǔ)器的指針說(shuō)明時(shí)即指定了存貯類型,例如:char data * str;str指向data區(qū)中char型數(shù)據(jù)int xdata * pow; pow指向外部RAM的int型整數(shù)。這種指針存放時(shí),只需一個(gè)字節(jié)或2個(gè)字節(jié)就夠了,因?yàn)橹恍璐娣牌屏俊?/p>

          3. 指針轉(zhuǎn)換

          即指針在上兩種類型之間轉(zhuǎn)化:l 當(dāng)基于存儲(chǔ)器的指針作為一個(gè)實(shí)參傳遞給需要一般指針的函數(shù)時(shí),指針自動(dòng)轉(zhuǎn)化。l 如果不說(shuō)明外部函數(shù)原形,基于存儲(chǔ)器的指針自動(dòng)轉(zhuǎn)化為一般指針,導(dǎo)致錯(cuò)誤,因而請(qǐng)用“#include”說(shuō)明所有函數(shù)原形。l 可以強(qiáng)行改變指針類型。

          第八節(jié) Keil C51函數(shù)

          C51函數(shù)聲明對(duì)ANSI C作了擴(kuò)展,具體包括:

          1. 中斷函數(shù)聲明:

          中斷聲明方法如下:void serial_ISR () interrupt 4 [using 1]{/* ISR */}為提高代碼的容錯(cuò)能力,在沒(méi)用到的中斷入口處生成iret語(yǔ)句,定義沒(méi)用到的中斷。/* define not used interrupt, so generate "IRET" in their entrance */void extern0_ISR() interrupt 0{} /* not used */void timer0_ISR () interrupt 1{} /* not used */void extern1_ISR() interrupt 2{} /* not used */void timer1_ISR () interrupt 3{} /* not used */void serial_ISR () interrupt 4{} /* not used */

          2. 通用存儲(chǔ)工作區(qū)

          3. 選通用存儲(chǔ)工作區(qū)由using x聲明,見(jiàn)上例。

          4. 指定存儲(chǔ)模式

          由small compact 及l(fā)arge說(shuō)明,例如:void fun1(void) small { }提示:small說(shuō)明的函數(shù)內(nèi)部變量全部使用內(nèi)部RAM。關(guān)鍵的經(jīng)常性的耗時(shí)的地方可以這樣聲明,以提高運(yùn)行速度。

          5. #pragma disable

          在函數(shù)前聲明,只對(duì)一個(gè)函數(shù)有效。該函數(shù)調(diào)用過(guò)程中將不可被中斷。

          6. 遞歸或可重入函數(shù)指定

          在主程序和中斷中都可調(diào)用的函數(shù),容易產(chǎn)生問(wèn)題。因?yàn)?1和PC不同,PC使用堆棧傳遞參數(shù),且靜態(tài)變量以外的內(nèi)部變量都在堆棧中;而51一般使用寄存器傳遞參數(shù),內(nèi)部變量一般在RAM中,函數(shù)重入時(shí)會(huì)破壞上次調(diào)用的數(shù)據(jù)??梢杂靡韵聝煞N方法解決函數(shù)重入:a、在相應(yīng)的函數(shù)前使用前述“#pragma disable”聲明,即只允許主程序或中斷之一調(diào)用該函數(shù);b、將該函數(shù)說(shuō)明為可重入的。如下:void func(param...) reentrant;KeilC51編譯后將生成一個(gè)可重入變量堆棧,然后就可以模擬通過(guò)堆棧傳遞變量的方法。由于一般可重入函數(shù)由主程序和中斷調(diào)用,所以通常中斷使用與主程序不同的R寄存器組。另外,對(duì)可重入函數(shù),在相應(yīng)的函數(shù)前面加上開(kāi)關(guān)“#pragma noaregs”,以禁止編譯器使用絕對(duì)寄存器尋址,可生成不依賴于寄存器組的代碼。

          7. 指定PL/M-51函數(shù)

          由alien指定。

          第四章 Keil C51高級(jí)編程

          本章討論以下內(nèi)容:l 絕對(duì)地址訪問(wèn)l C與匯編的接口l C51軟件包中的通用文件l 段名轉(zhuǎn)換與程序優(yōu)化

          第一節(jié) 絕對(duì)地址訪問(wèn)

          C51提供了三種訪問(wèn)絕對(duì)地址的方法:

          1. 絕對(duì)宏:

          在程序中,用“#include”即可使用其中定義的宏來(lái)訪問(wèn)絕對(duì)地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD具體使用可看一看absacc.h便知例如:rval=CBYTE[0x0002];指向程序存貯器的0002h地址rval=XWORD [0x0002];指向外RAM的0004h地址

          2. _at_關(guān)鍵字

          直接在數(shù)據(jù)定義后加上_at_ const即可,但是注意:(1)絕對(duì)變量不能被初使化;(2)bit型函數(shù)及變量不能用_at_指定。例如:idata struct link list _at_ 0x40;指定list結(jié)構(gòu)從40h開(kāi)始。xdata char text[25b] _at_0xE000;指定text數(shù)組從0E000H開(kāi)始提示:如果外部絕對(duì)變量是I/O端口等可自行變化數(shù)據(jù),需要使用volatile關(guān)鍵字進(jìn)行描述,請(qǐng)參考absacc.h。

          3. 連接定位控制

          此法是利用連接控制指令code xdata pdata /data bdata對(duì)“段”地址進(jìn)行,如要指定某具體變量地址,則很有局限性,不作詳細(xì)討論。

          第二節(jié) Keil C51與匯編的接口

          1. 模塊內(nèi)接口

          方法是用#pragma語(yǔ)句具體結(jié)構(gòu)是:#pragma asm匯編行#pragma endasm這種方法實(shí)質(zhì)是通過(guò)asm與ndasm告訴C51編譯器中間行不用編譯為匯編行,因而在編譯控制指令中有SRC以控制將這些不用編譯的行存入其中。

          2. 模塊間接口

          C模塊與匯編模塊的接口較簡(jiǎn)單,分別用C51與A51對(duì)源文件進(jìn)行編譯,然后用L51將obj文件連接即可,關(guān)鍵問(wèn)題在于C函數(shù)與匯編函數(shù)之間的參數(shù)傳遞問(wèn)題,C51中有兩種參數(shù)傳遞方法。(1) 通過(guò)寄存器傳遞函數(shù)參數(shù)最多只能有3個(gè)參數(shù)通過(guò)寄存器傳遞,規(guī)律如下表:

          參數(shù)數(shù)目charintlong,float一般指針
          123R7R5R3R6 & R7R4 & R5R2 & R3R4~R7R4~R7R1~R3R1~R3R1~R3
          (2) 通過(guò)固定存儲(chǔ)區(qū)傳遞(fixed memory)這種方法將bit型參數(shù)傳給一個(gè)存儲(chǔ)段中: ?function_name?BIT將其它類型參數(shù)均傳給下面的段:?function_name?BYTE,且按照預(yù)選順序存放。至于這個(gè)固定存儲(chǔ)區(qū)本身在何處,則由存儲(chǔ)模式默認(rèn)。(3) 函數(shù)的返回值函數(shù)返回值一律放于寄存器中,有如下規(guī)律:
          return typeRegistev說(shuō)明
          bit標(biāo)志位由具體標(biāo)志位返回
          char/unsigned char 1_byte指針R7單字節(jié)由R7返回
          int/unsigned int 2_byte指針R6 & R7雙字節(jié)由R6和R7返回,MSB在R6
          long&unsigned longR4~R7MSB在R4, LSB在R7
          floatR4~R732Bit IEEE格式
          一般指針R1~R3存儲(chǔ)類型在R3 高位R2 低R1
          (4) SRC控制該控制指令將C文件編譯生成匯編文件(.SRC),該匯編文件可改名后,生成匯編.ASM文件,再用A51進(jìn)行編譯。

          第三節(jié) Keil C51軟件包中的通用文件

          在C51/LiB目錄下有幾個(gè)C源文件,這幾個(gè)C源文件有非常重要的作用,對(duì)它們稍事修改,就可以用在自己的專用系統(tǒng)中。

          1. 動(dòng)態(tài)內(nèi)存分配

          init_mem.C:此文件是初始化動(dòng)態(tài)內(nèi)存區(qū)的程序源代碼。它可以指定動(dòng)態(tài)內(nèi)存的位置及大小,只有使用了init_mem( )才可以調(diào)回其它函數(shù),諸如malloc calloc,realloc等。calloc.c:此文件是給數(shù)組分配內(nèi)存的源代碼,它可以指定單位數(shù)據(jù)類型及該單元數(shù)目。malloc.c:此文件是malloc的源代碼,分配一段固定大小的內(nèi)存。realloc.c:此文件是realloc.c源代碼,其功能是調(diào)整當(dāng)前分配動(dòng)態(tài)內(nèi)存的大小。

          2. C51啟動(dòng)文件STARTUP.A51

          啟動(dòng)文件STARTUP.A51中包含目標(biāo)板啟動(dòng)代碼,可在每個(gè)project中加入這個(gè)文件,只要復(fù)位,則該文件立即執(zhí)行,其功能包括:l 定義內(nèi)部RAM大小、外部RAM大小、可重入堆棧位置l 清除內(nèi)部、外部或者以此頁(yè)為單元的外部存儲(chǔ)器l 按存儲(chǔ)模式初使化重入堆棧及堆棧指針l 初始化8051硬件堆棧指針l 向main( )函數(shù)交權(quán)開(kāi)發(fā)人員可修改以下數(shù)據(jù)從而對(duì)系統(tǒng)初始化 常數(shù)名 意義IDATALEN 待清內(nèi)部RAM長(zhǎng)度XDATA START 指定待清外部RAM起始地址XDATALEN 待清外部RAM長(zhǎng)度IBPSTACK 是否小模式重入堆棧指針需初始化標(biāo)志,1為需要。缺省為0IBPSTACKTOP 指定小模式重入堆棧頂部地址XBPSTACK 是否大模式重入堆棧指針需初始化標(biāo)志,缺省為0XBPSTACKTOP 指定大模式重入堆棧頂部地址PBPSTACK 是否Compact重入堆棧指針,需初始化標(biāo)志,缺省為0PBPSTACKTOP 指定Compact模式重入堆棧頂部地址PPAGEENABLE P2初始化允許開(kāi)關(guān)PPAGE 指定P2值PDATASTART 待清外部RAM頁(yè)首址PDATALEN 待清外部RAM頁(yè)長(zhǎng)度提示:如果要初始化P2作為緊湊模式高端地址,必須:PPAGEENAGLE=1,PPAGE為P2值,例如指定某頁(yè)1000H-10FFH,則PPAGE=10H,而且連接時(shí)必須如下:L51 PDATA(1080H),其中1080H是1000H-10FFH中的任一個(gè)值。以下是STARTUP.A51代碼片斷,紅色是經(jīng)常可能需要修改的地方:;------------------------------------------------------------------------------; This file is part of the C51 Compiler package; Copyright KEIL ELEKTRONIK GmbH 1990;------------------------------------------------------------------------------; STARTUP.A51: This code is executed after processor reset.;; To translate this file use A51 with the following invocation:;; A51 STARTUP.A51;; To link the modified STARTUP.OBJ file to your application use the following; L51 invocation:;; L51 , STARTUP.OBJ ;;------------------------------------------------------------------------------;; User-defined Power-On Initialization of Memory;; With the following EQU statements the initialization of memory; at processor reset can be defined:;; ; the absolute start-address of IDATA memory is always 0IDATALEN EQU 80H ; the length of IDATA memory in bytes.;XDATASTART EQU 0H ; the absolute start-address of XDATA memoryXDATALEN EQU 0H ; the length of XDATA memory in bytes.;PDATASTART EQU 0H ; the absolute start-address of PDATA memoryPDATALEN EQU 0H ; the length of PDATA memory in bytes.;; Notes: The IDATA space overlaps physically the DATA and BIT areas of the; 8051 CPU. At minimum the memory space occupied from the C51 ; run-time routines must be set to zero.;------------------------------------------------------------------------------;; Reentrant Stack Initilization;; The following EQU statements define the stack pointer for reentrant; functions and initialized it:;; Stack Space for reentrant functions in the SMALL model.IBPSTACK EQU 0 ; set to 1 if small reentrant is used.IBPSTACKTOP EQU 0FFH+1 ; set top of stack to highest location+1.;; Stack Space for reentrant functions in the LARGE model. XBPSTACK EQU 0 ; set to 1 if large reentrant is used.XBPSTACKTOP EQU 0FFFFH+1; set top of stack to highest location+1.;; Stack Space for reentrant functions in the COMPACT model. PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.PBPSTACKTOP EQU 0FFFFH+1; set top of stack to highest location+1.;;------------------------------------------------------------------------------;; Page Definition for Using the Compact Model with 64 KByte xdata RAM;; The following EQU statements define the xdata page used for pdata; variables. The EQU PPAGE must conform with the PPAGE control used; in the linker invocation.;PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.PPAGE EQU 0 ; define PPAGE number.;;------------------------------------------------------------------------------

          3. 標(biāo)準(zhǔn)輸入輸出文件

          putchar.cputchar.c是一個(gè)低級(jí)字符輸出子程,開(kāi)發(fā)人員可修改后應(yīng)用到自己的硬件系統(tǒng)上,例如向CLD或LEN輸出字符。缺省:putchar.c是向串口輸出一個(gè)字符XON|XOFF是流控標(biāo)志,換行符“/*n”自動(dòng)轉(zhuǎn)化為回車/換行“/r/n”。getkey.cgetkey函數(shù)是一個(gè)低級(jí)字符輸入子程,該程序可用到自己硬件系統(tǒng),如矩陣鍵盤(pán)輸入中,缺省時(shí)通過(guò)串口輸入字符。

          4. 其它文件

          還包括對(duì)Watch-Dog有獨(dú)特功能的INIT.A51函數(shù)以及對(duì)8×C751適用的函數(shù),可參考源代碼。

          第四節(jié) 段名協(xié)定與程序優(yōu)化

          1. 段名協(xié)定(Segment Naming Conventions)

          C51編譯器生成的目標(biāo)文件存放于許多段中,這些段是代碼空間或數(shù)據(jù)空間的一些單元,一個(gè)段可以是可重定位的,也可以是絕對(duì)段,每一個(gè)可重定位的段都有一個(gè)類型和名字,C51段名有以下規(guī)定:每個(gè)段名包括前綴與模塊名兩部分,前綴表示存儲(chǔ)類型,模塊名則是被編譯的模塊的名字,例如:?CO?main1 :表示main1模塊中的代碼段中的常數(shù)部分?PR?function1?module 表module模塊中函數(shù)function1的可執(zhí)行段,具體規(guī)定參閱手冊(cè)。

          2. 程序優(yōu)化

          C51編譯器是一個(gè)具有優(yōu)化功能的編譯器,它共提供六級(jí)優(yōu)化功能。確保生成目標(biāo)代碼的最高效率(代碼最少,運(yùn)行速度最快)。具體六級(jí)優(yōu)化的內(nèi)容可參考幫助。在C51中提供以下編譯控制指令控制代碼優(yōu)化:OPTIMIZE(SJXE):盡量采用子程序,使程序代碼減少。NOAREGS:不使用絕對(duì)寄存器訪問(wèn),程序代碼與寄存器段獨(dú)立。NOREGPARMS:參數(shù)傳遞總是在局部數(shù)據(jù)段實(shí)現(xiàn),程序代碼與低版本C51兼容。OPTIMIZE(SIZE)AK OPTIMIZE(speed)提供6級(jí)優(yōu)化功能,缺省為: OPTIMIZE(6,SPEED)。



          關(guān)鍵詞: KeilC51使用詳

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();