C51 启动流程总结

前言

简单介绍下 C51 内存框架及启动流程吧

相关参考资料:
C51.pdf
《单片机原理与应用及 C51 编程技术》
《基于单片机 8051 的嵌入式开发指南》

硬件框架

存储框架

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

由上面知道了 C51 硬件复位后,会执行到 0000H 地址处,那这里会放些什么呢?

软件流程

在这里插入图片描述

;//
; 此文件为 Keil C51 工程的启动文件 STARTUP.A51
; 会在链接过程中链接到最终程序中
; 
; STARTUP.A51 整体流程如下:
; 
;      Start 
;        |
;        V 
;     触发中断? ---------------------------------------------------|
;        |                                                          |
;        V                                                          |
;     设置 STACK 的 size                                            |
;        |                                                          |
;        V                                                          |
;     初始化时钟频率                                                |
;        |                                                          |
;        V                                                          |
;     清零 IDATA 区                                                 |
;        |                                                          |
;        V                                                          |
;     清零 XDATA 区                                     执行相应的中断跟服务函数
;        |                                                          |
;        V                                                          |
;     清零 PDATA 区                                                 |
;        |                                                          |
;        V                                                          |
;     初始化 reentrant 函数使用的堆栈指针                           |
;     (small/compact/large)                                         |
;        |                                                          |
;        V                                                          |
;    初始化 STACK 的指针                                            |
;        |                                                          |
;        V                                                          |
;    调用 main() 函数                                               |
;        | ---------------------------------------------------------|                                                         |
;        V 
;       END 
;
;//

$NOMOD51         ;Ax51宏汇编器控制命令:禁止预定义的8051
;------------------------------------------------------------------------------
;  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.
;  STARTUP.A51: STARTUP.A51文件所生成的代码将在单片机复位后被执行!
;
;  To translate this file use A51 with the following invocation:
;  将按照下面的命令行语句调用A51编译器进行编译产生目标文件
;
;     A51 STARTUP.A51
;
;  To link the modified STARTUP.OBJ file to your application use the following
;  BL51 invocation:
; 将按照下面的命令行语句调用BL51连接器把STARTUP.OBJ定位连接到您的程序代码中
;
;     BL51 <your object file list>, STARTUP.OBJ <controls>
;
;------------------------------------------------------------------------------
;
;  User-defined Power-On Initialization of Memory
; ; 自定义上电后需要初始化的储存区域
;
;  With the following EQU statements the initialization of memory
;  at processor reset can be defined:
;  使用下列EQU伪指令定义初始化的存储区域 在单片机复位后定义生效
;
;		; the absolute start-address of IDATA memory is always 0
; IDATA (间接寻址区)其起始地址固定为0;IDATALEN用于指定需要初始化的IDATA区长度(以字节为单位)*
IDATALEN	EQU	80H	; the length of IDATA memory in bytes.  
;
XDATASTART	EQU	0H	; the absolute start-address of XDATA memory
XDATALEN	EQU	0H	; the length of XDATA memory in bytes.
;XDATA (外部直接寻址区) XDATASTART用于指定需要初始化的XDATA区起始地址
;XDATALEN 用于指定需要初始化的XDATA区长度(以字节为单位)*
;
PDATASTART	EQU	0H	; the absolute start-address of PDATA memory
PDATALEN	EQU	0H	; the length of PDATA memory in bytes.
;PDATA(页寻址区) PDATASTART用于指定需要初始化的PDATA区起始地址
;PDATALEN用于指定需要初始化的;PDATA区长度(以字节为单位)*
;
;  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中 IDATA 区物理上已经包括了DATA区(直接寻址区)以及 BIT区 (位寻址
;             区)。C51(库)占用了 最小化内存空间,运行时程序需要把它设为0
;------------------------------------------------------------------------------
;
;  Reentrant Stack Initilization
; 重入堆栈初始化
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
; 下面的EQU语句定义重入函数的堆栈指针并初始化它
;
;  Stack Space for reentrant functions in the SMALL model.          ; SMALL 模式下的重入函数的堆栈空间
IBPSTACK	EQU	0	; set to 1 if small reentrant is used.          ; 如果再 SMALL 模式下使用重入则设为 1 
IBPSTACKTOP	EQU	0FFH+1	; set top of stack to highest location+1.   ; 设置堆栈顶最高位置 +1
;
;  Stack Space for reentrant functions in the LARGE model.	        ; LARGE模式下的重入函数的堆栈空间
XBPSTACK	EQU	0	; set to 1 if large reentrant is used.          ; 如果再LARGE模式下使用重入则设为 1
XBPSTACKTOP	EQU	0FFFFH+1; set top of stack to highest location+1.   ; 设置堆栈顶最高位置 +1
;
;  Stack Space for reentrant functions in the COMPACT model.	    ; COMPACT 模式下的重入函数的堆栈空间
PBPSTACK	EQU	0	; set to 1 if compact reentrant is used.        ; 如果再 COMPACT 模式下使用重入则设为 1
PBPSTACKTOP	EQU	0FFFFH+1; set top of stack to highest location+1.   ; 设置堆栈顶最高位置 +1
;
;------------------------------------------------------------------------------
;
;  Page Definition for Using the Compact Model with 64 KByte xdata RAM      ; 使用COMPACT模式时为64KB的XDATA RAM定义页
;
;  The following EQU statements define the xdata page used for pdata        ; 下面的EQU语句定义PDATA变量的使用了XDATA页
;  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.            ;如果使用PDATA页则设为1
PPAGE		EQU	0	; define PPAGE number.                          ;定义页号
;
;------------------------------------------------------------------------------

; Standard SFR Symbols required in XBANKING.A51                     ; 标准SFR符号
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                    ; 在 code 段的 0 地址处放以下代码(使用AT指令进行绝对地址的定位)

		RSEG	?C_C51STARTUP

STARTUP1:

IF IDATALEN <> 0                                ; 如果长度大于 1 则初始化 IDATA
		MOV	R0,#IDATALEN - 1
		CLR	A
IDATALOOP:	MOV	@R0,A
		DJNZ	R0,IDATALOOP
ENDIF

IF XDATALEN <> 0                                ; 预置初始化时的外循环次数到 R6
		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                             ; 如果长度大于 1 则初始化 PDATA
		MOV	P2,#PPAGE
ENDIF

IF PDATALEN <> 0                                ; SMALL 模式下使用重入函数时要设置的堆栈
		MOV	R0,#PDATASTART
		MOV	R7,#LOW (PDATALEN)
		CLR	A
PDATALOOP:	MOVX	@R0,A
		INC	R0
		DJNZ	R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0                                ; COMPACT 模式下使用重入函数时要设置的堆栈
EXTRN DATA (?C_IBP)

		MOV	?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0                                ; LARGE 模式下使用重入函数时要设置的堆栈
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 ; 如果你的程序使用了Mode 4 程序分组技术(BANKING)请启用下面的程序代码
EXTRN CODE (?B_SWITCH0)
                CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
		LJMP	?C_START            ;main()

		END

在这里插入图片描述
在这里插入图片描述

可重入函数

在这里插入图片描述

C51单片机中断是单片机应用中的重要部分,可以提高程序的响应速度和实时性。下面是C51单片机中断实验的总结: 1. 中断的概念和作用 中断是指在程序执行过程中,由硬件或软件发起的一种特殊事件。中断可以打断程序的正常执行,转而执行中断服务程序(ISR),处理该事件后返回到原来的程序执行位置。中断可以提高程序的实时性和响应速度。 2. 中断的分类 C51单片机中断可以分为外部中断和定时器中断两种。外部中断是由外部设备(如按键、传感器等)产生的中断信号,而定时器中断则是由定时器模块产生的中断信号。 3. 中断的使用方法 在C51单片机中,中断的使用需要注册中断服务程序,并设置中断优先级和中断向量。具体步骤如下: (1)编写中断服务程序,命名为“中断向量号+中断服务程序名”,例如“INT0_ISR”。 (2)在主程序中设置中断优先级和中断向量,如下所示: ```c EA = 1; // 允许中断 EX0 = 1; // 允许外部中断0 IT0 = 1; // 设置外部中断0为下降沿触发 ``` (3)在中断服务程序中处理相应的中断事件,如下所示: ```c void INT0_ISR(void) interrupt 0 { // 处理外部中断0事件 } ``` 4. 中断实验的设计 中断实验可选用外部中断或定时器中断。例如,设计一个按键控制LED的实验,当按下按键时,LED亮起;松开按键时,LED熄灭。实验过程如下: (1)连接电路,将按键和LED分别连接到P3.2和P1.0口。 (2)编写中断服务程序,处理外部中断0事件: ```c void INT0_ISR(void) interrupt 0 { if (P3_2 == 0) // 检测按键是否按下 { P1_0 = 1; // 点亮LED } else { P1_0 = 0; // 熄灭LED } } ``` (3)在主程序中设置中断优先级和中断向量,如下所示: ```c EA = 1; // 允许中断 EX0 = 1; // 允许外部中断0 IT0 = 1; // 设置外部中断0为下降沿触发 ``` (4)启动程序,按下按键时,LED亮起;松开按键时,LED熄灭。 5. 中断实验的注意事项 (1)中断服务程序中应尽量避免使用延时函数和循环语句,以免影响程序的实时性。 (2)在编写中断服务程序时,应注意保存现场和恢复现场,以保证程序的正确执行。 (3)在使用多个中断时,应注意设置中断优先级,以保证高优先级中断能够及时响应。 6. 总结 C51单片机中断是提高程序实时性和响应速度的重要手段,掌握中断的使用方法和注意事项对于单片机应用开发具有重要意义。在实际应用中,应根据具体情况选择合适的中断类型并合理设置中断优先级,以确保程序的正确执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值