51单片机keil提供的启动代码解析(STARTUP.A51)
参考文档:http://hi.baidu.com/yc_dy/item/4ff959be36ccff72254b0959
1. 由Keil C生成的启动代码
程序清单1.1 AT89C51启动代码
$NOMOD51 //不使用51默认的特殊功能寄存器
;------------------------------------------------------------------------------
; 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.
; 说的很清楚,该代码会在处理器上电复位后首先执行
;
; 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),这是命令行的使用格式
;------------------------------------------------------------------------------
;
; User-defined Power-On Initialization of Memory
; 下面将定义一些与存储器初始化相关的符号常量,与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指片内128字节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的寄存器空间和存储器空间并不是统一编址的,而是通过指令来区分,所以不同的存储区的地址可能重叠(overlap)
;------------------------------------------------------------------------------
;
; Reentrant Stack Initilization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
; Keil C默认情况不是用堆栈来传递参数的,所以造成函数不可重入(可重入概念参看线程安全和可重入函数一节)。Keil要求用户显示声明函数是否具有可重入属性,以便为C函数调用初始化栈。
; 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.
;不同内存模式下的堆栈。Keil 编译器中有三种模式设置:
Small:所有的变量都放在内部RAM区
Compact:所有变量在默认情况下都会放在外部RAM的低256字节中(可由R0寻址)
Large:所有变量都放在外部RAM中(DPTR寻址)
这是由51处理器繁多的寻址模式导致的,不同的寻址模式有不同的效率
;------------------------------------------------------------------------------
;
; 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 //代码段的起始点
?C_STARTUP: LJMP STARTUP1 //转跳到STARTUP1程序区中去。
RSEG ?C_C51STARTUP
STARTUP1:
//IF ENDIF是条件编译命令,只有当条件为真时,才编译代码
IF IDATALEN <> 0 //如果有IDATA,则把IDATA区的数据清零,类似于清BSS区
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
//如果有外部数据区,则把外部数据区中从XDATASTART到XDATASTART+ XDATALEN的区域清零
//由于51的储存区类型和编译模型比较多,下面的代码就是根据不同的配置把相应的区域清零
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
从上面一段代码,我们已经发现了一些与ATmega8初始化代码相同的操作:初始化堆栈和bss区。由于AT89C51的存储空间和寻址模式比ATmega8复杂,所以初始代码中增加了许多根据不同配置而进行初始化的代码
51单片机keil提供的启动代码解析(STARTUP.A51)相关推荐
- [51单片机] HC-SR04超声波测距仪 基础代码
>_<:超声波测距仪模块: >_<:51单片机,11.0592MHz晶振,将采集数据发送到串口的基础例子: >_<:代码: 1 /***************** ...
- 51单片机c语言定时器程序,51单片机定时器设置入门与程序解析
89C51单片机有两个计数器T0和T1,每个计数器都是由两个8位的RAM 单元组成的,即每个计数器都是16 位的计数器,最大的计数容量是216=65536,记住是从0-65535. 其次.提供给定时器 ...
- 51单片机风扇转动c语言代码,基于51单片机的智能风扇控制系统设计.doc
完美.WORD格式.整理 范文.范例.指导 基于51单片机智能风扇控制系统的设计与实现 摘要:随着气温的逐渐上升,风扇的需求量也逐渐扩大.传统风扇不能根据外界温度的变化对风扇转速快慢进行调整,也不能对 ...
- 写一段51单片机的避障小车代码
以下是一段使用51单片机编写的避障小车代码: #include <reg51.h>sbit LeftSensor = P3^0; sbit RightSensor = P3^1; sbit ...
- 51单片机~串口通信(讲解+代码)
51单片机~串口通信 (一)计算机串行通信原理: 综上:所以在设置的时候,经常将SCON设置为0X50==0101 0000 ,使用方式1. (二)工作: 中断控制 led灯,每发送一条指令灯亮或灭( ...
- 51单片机风扇转动c语言代码,基于51单片机的c语言程序 电机转速测量与PWM控制...
[实例简介] 部分源程序如下: //=================测速计数处理=================================== void timer1()interrupt ...
- 51单片机-1602液晶显示的时钟代码
单片机小白,初学单片机,利用51单片机简单的编写了基于1602显示的时钟程序,技术不好,可能会有许多不好的地方,希望大神指正 基本功能:时钟显示,利用按键调时,分 #include<reg52. ...
- 用keil语言定义c51,51单片机Keil C51的使用(C语言)
实验目的: 初步掌握Keil(C51语言)和SUN ES59PA实验仪的操作和使用,能够输入和运行简单的程序.实验设备: SUN ES59PA实验仪一套.具有一个RS232串行口并安装Keil C51 ...
- 51单片机----Keil uVision程序编译软件与Proteus 8 Professional电路仿真软件之间调到统一频率(12MHz)
1.调节Keil uVision程序点击 再次点击1-2-点击OK. 2.Proteus 8 Professional调节频率,双击单片机,把这里修改为12MHz. 注意:这里12 MHz千万不要删掉 ...
最新文章
- Android 设置透明的方法
- OD使用教程 调试篇
- 树莓派 Ubuntu mate 18.04 修改为清华源
- pytorch拼接函数:torch.stack()和torch.cat()--详解及例子
- Problem I: 函数---判断某年某月某日是这一年中的第几天
- live555学习笔记3-消息循环
- 万人攻防大战:淘宝优惠活动,沦为黑产盛宴
- SQLServer如何取得随机获取的数据库记录
- h5调微信支付 unkonw url_h5移动端调用支付宝、微信支付的实现
- python线程池如何调度,python线程池控制
- 将 .qrc文件转换成 .py文件的解决方法
- 走遍美国之大雾山国家公园
- linux vm使用物理磁盘,vmware使用整个物理硬盘做虚拟机的注意事项
- c语言志愿者信息管理系统,基于C/S架构的青年志愿者管理系统
- 无效的m3u8怎么办_你还在为m3u8文件如何转换而发愁?看了我就有答案了
- 浪潮财务软件 系统表预检查: 对象 ID X。无法使用闩锁类型 SH 读取并闩锁页 。由于不可修复的错误,CHECK 语句已终止。
- 动画(重点)~~~~~
- 这三款小巧好用的APP,请务必收下
- 经常写大材料的请惠存(转载)
- android的ui模板,11免费好看的手机APP UI模板