创建C51工程文件疑问点---startup.A51
標題黨為了方面后續(xù)自己翻的時候看的到
?以前是直接點的否,深受吳老板的棍棒教育,不用不改就是否。hhh~
2022注解:
-
- 總結(jié)起來 就是初始化寄存器,然后把IDATA、XDATA的數(shù)據(jù)都清0,然后跳轉(zhuǎn)到main函數(shù)
下面是看到的一段比較全的解釋,感覺懵懵懂懂是看懂了。
STARTUP.A51?這個文件有什么用,有必要添加到工程嗎?
如果不添加"startup.a51"文件,編譯器就會自動加入一段初始化內(nèi)存以及堆棧等的代碼,這時的內(nèi)存初始化部分你就無法去控制了,當然這在大部分情況下沒什么關(guān)系。但是如果你想你的程序在復位后,內(nèi)存里面的信息依然還保存著(所說的“熱復位”),那么你就需要添加該啟動文件,并且去里面修改內(nèi)存初始化部分,不要初始化你需要保留的部分內(nèi)存。
啟動文件.?清理RAM.設置堆棧等.即執(zhí)行完start.a51后跳轉(zhuǎn)到.c文件的main函數(shù)。這些初始化完畢后,還會設置SP指針。對非變量區(qū)域,如堆棧區(qū),將不會有賦值或清零動作。
有人喜歡改startup.a51,為了滿足自己一些想當然的愛好,這是不必要的,有可能錯誤的。比如掉電保護的時候想保存一些變量,但改startup.a51來實現(xiàn)是很笨的方法,實際只要利用非變量區(qū)域的特性,定義一個指針變量指向堆棧低部:0xff處就可實現(xiàn)。為什么還要去改? 可以這么說:任何時候都可以不需要改startup.a51,如果你明白它的特性。?
Startup code:啟動代碼。
在Keil中,啟動代碼在復位目標系統(tǒng)后立即被執(zhí)行。啟動代碼主要實現(xiàn)以下功能:
(1)???????清除內(nèi)部數(shù)據(jù)存儲器
(2)???????清除外部數(shù)據(jù)存儲器
(3)???????清除外部頁存儲器
(4)???????初始化small模式下的可重入棧和指針
(5)???????初始化large模式下的可重入棧和指針
(6)???????初始化compact模式下的可重入棧和指針
(7)???????初始化8051硬件棧指針
(8)???????傳遞初始化全局變量的控制命令或者在沒有初始化全局變量時給main函數(shù)傳遞命令。
在每一個啟動文件中,提供了可供用戶自己修改有來控制程序執(zhí)行的匯編常量。見表1
| Name | Description |
| IDATALEN | Specifies the number of bytes of idata to clear to 0. The default is 80h because most 8051 derivatives contain at least 128 bytes of internal data memory. Use a value of 100h for the 8052 and other derivatives that have 256 bytes of internal data memory. |
| XDATASTART | Specifies the initial xdata address to clear to 0. |
| XDATALEN | Indicates the number of bytes of xdata to clear to 0. The default is 0. |
| PDATASTART | Specifies the initial pdata address to clear to 0. |
| PDATALEN | Specifies the number of bytes of pdata to clear to 0. The default is 0. |
| IBPSTACK | Specifies whether or not the small model reentrant stack pointer (?C_IBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0. |
| IBPSTACKTOP | Specifies the top of the small model reentrant stack. The default is 0xFF in idata memory. |
| XBPSTACK | Specifies whether or not the large model reentrant stack pointer (?C_XBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0. |
| XBPSTACKTOP | Specifies the top of the large model reentrant stack. The default is 0xFFFF in xdata memory. |
| PBPSTACK | Specifies whether the compact model reentrant stack pointer (?C_PBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0. |
| PBPSTACKTOP | Specifies the top of the compact model reentrant stack. The default is 0xFF in pdata memory. |
| PPAGEENABLE | Enables (a value of 1) or disables (a value of 0) Port 2 initialization for pdata memory access. The default is 0. pdata addressing uses Port 2 for the upper address (or page) byte. |
| PPAGE | Specifies the value to write to Port 2 of the 8051 for pdata memory access. This value represents the xdata memory page to use for pdata. This is the upper 8 bits of the absolute address range to use for pdata. For example, if the pdata area begins at address 1000h (page 10h) in xdata memory,?PPAGEENABLE?should be set to 1, and?PPAGEshould be set to 10h. You must specify the starting pdata address to use to the BL51 Linker using the PDATA directive. For example: BL51 input modules PDATA (1050H)Neither the BL51 Linker nor the Cx51 Compiler checks to see if the?PDATA?directive and the?PPAGE?startup constant are correctly specified. You must ensure that these parameters contain suitable values. |
上面這些只是標號,如果愿意,自己可以換成其他的名字。這樣寫意義更直觀。
$NOMOD51 ; Ax51宏匯編器控制命令,禁止預定義的8051。使編譯器不使能預定義的8051符號,避免產(chǎn)生重復定義的錯誤。 ;------------------------------------------------------------------------------ ; This file is part of the C51 Compiler package ; Copyright (c) 1988-2001 Keil Elektronik GmbH and Keil Software, Inc. ;------------------------------------------------------------------------------ ; 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 ; BL51 invocation: ; ; BL51 <your object file list>, STARTUP.OBJ <controls> ; --- BL51是Keil使用的鏈接器(Linker),這是命令行的使用格式,一般不用,使用IDE環(huán)境,用project管理,有相應的按鈕可以實現(xiàn)該功能. ; ;-------------------------------------------------------------------------------------------------------------------- ; ; User-defined Power-On Initialization of Memory --- 初始化RAM單元 ; ; With the following EQU statements the initialization of memory --- 用下面的EQU聲明初始化ram單元 ; 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. ; --- 根據(jù)你選用的芯片可以適當?shù)男薷倪@些值 。IDATALEN 只是一個標號,EQU只是做宏一樣的替換,類似于C語言中的 ; --- #define uint (unsigned int) ,以上的代碼使得程序以后在碰到IDATALEN時替換成80H ; XDATASTART EQU 0H ; the absolute start-address of XDATA memory --以下兩項根據(jù)目標系統(tǒng)的外設配置和連接自己修改 XDATALEN EQU 0H ; the length of XDATA memory in bytes. ; PDATASTART EQU 0H ; the absolute start-address of PDATA memory PDATALEN 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 ;-- 再入堆棧初始化 ; --- 注意:再入堆棧的方向區(qū)別于芯片自帶的堆棧的生長方式,自頂向下生長的!而SP是是自底向上的。 ; --- 且再入堆棧是由編譯器自己管理的,一般不必去關(guān)心,只是在有再入函數(shù)的時候,根據(jù)函數(shù)的存儲器模式使用相應的RAM空間做為再入堆棧。 ; ; The following EQU statements define the stack pointer for reentrant ; functions and initialized it: ; --- Keil C默認情況不是用堆棧來傳遞參數(shù)的,所以造成函數(shù)不可重入,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 編譯器中有三種模式設置: ; --- Small:所有的變量都放在內(nèi)部RAM區(qū) ; --- Compact:所有變量在默認情況下都會放在外部RAM的低256字節(jié)中(可由R0尋址) ; --- Large:所有變量都放在外部RAM中(DPTR尋址) ; --- 這是由51處理器繁多的尋址模式導致的,不同的尋址模式有不同的效率 ; ;------------------------------------------------------------------------------------------------------------------------------ ; ; Page Definition for Using the Compact Model with 64 KByte xdata RAM ; --- 使用COMPACT存儲器模式時64K字節(jié)XDATA存儲器空間的分頁定義 ; ; 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. ;--- 以下用EQU指令定義PDATA類型變量在XDATA存儲器空間的頁地址 ;--- 使用EQU指令定義PFAGE時必須與L51連接定位器PDATA指令的控制參數(shù)一致 ; 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) 很多的外部頁面尋址以P2口為高位地址的數(shù)值,有使用外部頁面RAM的情況 ; --- 對PPAGEENABLE 設置為1 ,根據(jù)硬件連接修改PPAGE的值。 ; ;------------------------------------------------------------------------------; Standard SFR Symbols required in XBANKING.A51 ;--- 標準的SFR符號 ACC DATA 0E0H ;--- 關(guān)鍵字DATA A51偽指令定義單片機內(nèi)部數(shù)據(jù)存儲器字節(jié)地址的符號 B DATA 0F0H SP DATA 81H DPL DATA 82H DPH DATA 83HNAME ?C_STARTUP ;--- 定義當前程序模塊的目標模塊名?C_C51STARTUP SEGMENT CODE ;-- 定義一個可再定位的段符號名和段所在的存儲空間,匯編器產(chǎn)生的這個段符號名在BL51/L51連接定位時用 ?STACK SEGMENT IDATA ;-- 定義一個IDATA段,段名?STACK ,符合C51編譯器的命名規(guī)則 (SEGMENT 用于定義一個段)RSEG ?STACK ;-- 聲明當前段是IDATA段,段中保留空間。RSEG偽指令用于選擇一個事先用SEGMENT偽指令聲明的普通段DS 1 ; DS是預留空間定義指令EXTRN CODE (?C_START) ;聲明本模塊引用的外部全局符號,用于和C相連接在.src文件中可以看到這個符號PUBLIC ?C_STARTUP ;聲明可被其他模塊使用的全局符號,由.src文件中可以看出這個符號的作用。CSEG AT 0 ;結(jié)束當前的IDATA段,產(chǎn)生一個位于CODE中新段,起始地址是0000H。代碼段的起始點 ?C_STARTUP: LJMP STARTUP1 ;C編譯器編譯源程序后,芯片復位之后的復位代碼第一個就是執(zhí)行這條語句。RSEG ?C_C51STARTUP ;選擇段名為?C_C51STARTUP的CODE段為當前段,存儲程序代碼。STARTUP1: ;--- 單片機上電IDATA內(nèi)存清零。如果不需要上電清零IDATA, ;--- 可以注銷IF到IFEDN之間的話句或者修改IDTALEN的長度 IF IDATALEN <> 0 ;如果IDATALEN不等于0 條件匯編指令,有IDATA區(qū)的話,清IDATA區(qū)。MOV R0,#IDATALEN - 1 ;區(qū)域為0——IDATALEN-1CLR A IDATALOOP: MOV @R0,ADJNZ R0,IDATALOOP ENDIF;(一)如果上面idatalen=80H,那么是對0~7FH清零;如果你的程序是改寫成:IDATALEN EQU 0100H ;就是對0~FFH清零。 ;(二)如何按你意愿加載這段程序 ;一般考慮到這個往往是你的設計中要區(qū)分上電復位和程序復位。有時候當程序復位時你不希望一些內(nèi)存單元被清零了, ;那么你不對startup.a51作點修改,就不行了。 ;默認是自動加載這段startup.a51的。 ;所以你要這樣做:把lib目錄下的原始startup.a51文件拷到你的項目所在目錄下,再把你項目目錄下的這個startup.a51加入到你的項目中 ;比如改成:IDATALEN EQU 00H ; the length of IDATA memory in bytes. ;然后編譯鏈接。這樣你的程序中就不會包含對idata清零的內(nèi)碼了。 ;為什么?上面提到的IF語句的作用呀!當定義IDATALEN=0時,清零代碼被跳過!;--- 單片機上電XDATA內(nèi)存清零。如果不需要上電清零XDATA, ;--- 可以注銷IF到IFEDN之間的話句或者修改XDATALEN的長度 IF XDATALEN <> 0 ;如果有外部數(shù)據(jù)區(qū),則把外部數(shù)據(jù)區(qū)中從XDATASTART到XDATASTART+ XDATALEN的區(qū)域清零MOV DPTR,#XDATASTARTMOV R7,#LOW (XDATALEN)IF (LOW (XDATALEN)) <> 0MOV R6,#(HIGH (XDATALEN)) +1 ;如果低地址是零,一個高地址就代表256字節(jié)ELSEMOV R6,#HIGH (XDATALEN)ENDIFCLR A XDATALOOP: MOVX @DPTR,AINC DPTRDJNZ R7,XDATALOOPDJNZ R6,XDATALOOP ENDIFIF PPAGEENABLE <> 0 ;清外部頁RAM區(qū)域MOV P2,#PPAGE ;給P2口賦相應的值,根據(jù)用戶自己的目標系統(tǒng)。 ENDIF;--- 單片機上電XDATA內(nèi)存清零。如果不需要上電清零XDATA, ;--- 可以注銷IF到IFEDN之間的話句或者修改XDATALEN的長度 IF PDATALEN <> 0 ;清外部頁RAM區(qū)域MOV R0,#PDATASTARTMOV R7,#LOW (PDATALEN)CLR A PDATALOOP: MOVX @R0,AINC R0DJNZ R7,PDATALOOP ENDIF;--- 設置使用SMALL存儲器模式時再入函數(shù)的堆棧空間 IF IBPSTACK <> 0 ; 使用再入堆棧的情況,用戶自己在程序中定義函數(shù)的存儲模式。; C51定義了三個全局變量,?C_IBP,?C_XBP,?C_PBP來存儲再入堆棧的棧頂?shù)刂?EXTRN DATA (?C_IBP) ; 聲明本模塊使用的外部全局符號,符號的段類型限制了符號的使用范圍,; 而符號本身則代表的是一個RAM單元的地址址MOV ?C_IBP,#LOW IBPSTACKTOP ENDIF;--- 設置使用LARGE存儲器模式時再入函數(shù)的堆??臻g IF XBPSTACK <> 0 ;函數(shù)是Large存儲模式的時候,存儲再入堆棧的區(qū)域。 EXTRN DATA (?C_XBP)MOV ?C_XBP,#HIGH XBPSTACKTOPMOV ?C_XBP+1,#LOW XBPSTACKTOP ENDIF ;--- 設置使用COMPACT存儲器模式時再入函數(shù)的堆??臻g IF PBPSTACK <> 0 ;函數(shù)是Compact模式的時候,存儲再入堆棧棧頂?shù)刂返拇鎯卧蜅5睦每臻g EXTRN DATA (?C_PBP)MOV ?C_PBP,#LOW PBPSTACKTOP ENDIF ;--- 設置堆棧的起始地址MOV SP,#?STACK-1 ;定義的硬件棧的常數(shù)。區(qū)別再入堆棧和硬件棧。定義的段符號代表該段的首地址 ; 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 ; 程序從第一組bank 0 塊開始執(zhí)行,跳轉(zhuǎn)到用戶程序MAIN函數(shù)LJMP ?C_START ; 把執(zhí)行的權(quán)力交給C主函數(shù)。也就是說指定函數(shù)的入口點。改句話結(jié)束以后將跳入C的main函數(shù)開始執(zhí)行。END總結(jié)
以上是生活随笔為你收集整理的创建C51工程文件疑问点---startup.A51的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [css] 使用rem布局时怎样合理设
- 下一篇: tomcat下面的starup.bat的