新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > keil提供的啟動代碼解析(STARTUP.A51)

keil提供的啟動代碼解析(STARTUP.A51)

作者: 時間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
1. 由Keil C生成的啟動代碼

程序清單1.1 AT89C51啟動代碼

本文引用地址:http://m.butianyuan.cn/article/201611/318640.htm

$NOMOD51 //不使用51默認(rèn)的特殊功能寄存器

;

; This file is part of the C51 Compiler package

; Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.

;

; STARTUP.A51: This code is executed after processor reset.

; 說的很清楚,該代碼會在處理器上電復(fù)位后首先執(zhí)行

;

; 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

; BL51 invocation:

;

; BL51 , STARTUP.OBJ

; BL51是Keil使用的鏈接器(Linker),這是命令行的使用格式

;

;

; User-defined Power-On Initialization of Memory

; 下面將定義一些與存儲器初始化相關(guān)的符號常量,與ICCAVR相比,Keil把符號常量顯式聲明出來更容易理解。

; With the following EQU statements the initialization of memory

; at processor reset can be defined:

;

; ; the absolute start-address of IDATA memory is always 0

IDATALEN EQU 80H ; the length of IDATA memory in bytes.

;IDDATALEN指片內(nèi)128字節(jié)RAM,I指internal

XDATASTART EQU 0H ; the absolute start-address of XDATA memory

XDATALEN EQU 0H ; the length of XDATA memory in bytes.

; XDATA指片外SRAM空間,X指external

PDATASTART EQU 0H ; the absolute start-address of PDATA memory

PDATALEN EQU 0H ; the length of PDATA memory in bytes.

; PDATA指程序存儲器,p指program

; 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.

; 注意:8051 CPU的寄存器空間和存儲器空間并不是統(tǒng)一編址的,而是通過指令來區(qū)分,所以不同的存儲區(qū)的地址可能重疊(overlap)

;

;

; Reentrant Stack Initilization

;

; The following EQU statements define the stack pointer for reentrant

; functions and initialized it:

; Keil C默認(rèn)情況不是用堆棧來傳遞參數(shù)的,所以造成函數(shù)不可重入(可重入概念參看線程安全和可重入函數(shù)一節(jié))。Keil要求用戶顯示聲明函數(shù)是否具有可重入屬性,以便為C函數(shù)調(diào)用初始化棧。

; 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.

;不同內(nèi)存模式下的堆棧。Keil 編譯器中有三種模式設(shè)置:

Small:所有的變量都放在內(nèi)部RAM區(qū)

Compact:所有變量在默認(rèn)情況下都會放在外部RAM的低256字節(jié)中(可由R0尋址)

Large:所有變量都放在外部RAM中(DPTR尋址)

這是由51處理器繁多的尋址模式導(dǎo)致的,不同的尋址模式有不同的效率

;

;

; 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.

;

PPAGE_SFR DATA 0A0H ; SFR that supplies uppermost address byte

; (most 8051 variants use P2 as uppermost address byte)

;

;

; Standard SFR Symbols

ACC DATA 0E0H

B DATA 0F0H

SP DATA 81H

DPL DATA 82H

DPH DATA 83H

NAME ?C_STARTUP

?C_C51STARTUP SEGMENT CODE

?STACK SEGMENT IDATA

RSEG ?STACK

DS 1

EXTRN CODE (?C_START)

PUBLIC ?C_STARTUP

CSEG AT 0 //代碼段的起始點(diǎn)

?C_STARTUP: LJMP STARTUP1 //轉(zhuǎn)跳到STARTUP1程序區(qū)中去。

RSEG ?C_C51STARTUP

STARTUP1:

//IF ENDIF是條件編譯命令,只有當(dāng)條件為真時,才編譯代碼

IF IDATALEN <> 0 //如果有IDATA,則把IDATA區(qū)的數(shù)據(jù)清零,類似于清BSS區(qū)

MOV R0,#IDATALEN - 1

CLR A

IDATALOOP: MOV @R0,A

DJNZ R0,IDATALOOP

ENDIF

//如果有外部數(shù)據(jù)區(qū),則把外部數(shù)據(jù)區(qū)中從XDATASTART到XDATASTART+ XDATALEN的區(qū)域清零

//由于51的儲存區(qū)類型和編譯模型比較多,下面的代碼就是根據(jù)不同的配置把相應(yīng)的區(qū)域清零

IF XDATALEN <> 0

MOV DPTR,#XDATASTART

MOV R7,#LOW (XDATALEN)

IF (LOW (XDATALEN)) <> 0

MOV R6,#(HIGH (XDATALEN)) +1

ELSE

MOV R6,#HIGH (XDATALEN)

ENDIF

CLR A

XDATALOOP: MOVX @DPTR,A

INC DPTR

DJNZ R7,XDATALOOP

DJNZ R6,XDATALOOP

ENDIF

IF PPAGEENABLE <> 0

MOV PPAGE_SFR,#PPAGE

ENDIF

IF PDATALEN <> 0

MOV R0,#LOW (PDATASTART)

MOV R7,#LOW (PDATALEN)

CLR A

PDATALOOP: MOVX @R0,A

INC R0

DJNZ R7,PDATALOOP

ENDIF

IF IBPSTACK <> 0

EXTRN DATA (?C_IBP)

MOV ?C_IBP,#LOW IBPSTACKTOP

ENDIF

IF XBPSTACK <> 0

EXTRN DATA (?C_XBP)

MOV ?C_XBP,#HIGH XBPSTACKTOP

MOV ?C_XBP+1,#LOW XBPSTACKTOP

ENDIF

IF PBPSTACK <> 0

EXTRN DATA (?C_PBP)

MOV ?C_PBP,#LOW PBPSTACKTOP

ENDIF

//該處是初始化堆棧指針

MOV SP,#?STACK-1

; This code is required if you use L51_BANK.A51 with Banking Mode 4

; EXTRN CODE (?B_SWITCH0)

; CALL ?B_SWITCH0 ; init bank mechanism to code bank 0

LJMP ?C_START

END

從上面一段代碼,我們已經(jīng)發(fā)現(xiàn)了一些與ATmega8初始化代碼相同的操作:初始化堆棧和bss區(qū)。由于AT89C51的存儲空間和尋址模式比ATmega8復(fù)雜,所以初始代碼中增加了許多根據(jù)不同配置而進(jìn)行初始化的代碼



關(guān)鍵詞: keil啟動代

評論


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

關(guān)閉