历史上的今天
今天是:2024年11月19日(星期二)
2018年11月19日 | 单片机startup.a51文件内容的详解
2018-11-19 来源:eefocus
1.标号
IDATALEN EQU 80H ; the length of IDATA memory in bytes.
这里IDATALEN只是一个标号而已,和idata不是一回事!你要是愿意,这段程序里的IDATALEN你完全可以改成dog呀,pig呀,playboy呀这些标号(其实我的理想是过猪一样的生活,不愁吃喝,无忧无虑,可惜做不到),上面的这一句是说程序里面凡是用到IDATALEN的地方其实就是可以看成是80H这个数,你用80H去代替IDATALEN是完全对的。
之所以取IDATALEN这么个名字,只是为了好记,表明和idata有一点点关系,不至于你的程序长了,假使你本来是用了playboy作为标号的,写到后来你就会忘了playboy到底是什么含义了。idata的范围是0~FFH。如果你想改成FFH,完全可以。
2。清零
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
关于这一段,很明显是在清零,如果上面idatalen=80H,那么是对0~7FH清零;如果
你的程序是改写成:
IDATALEN EQU 0100H ;
就是对0~FFH清零。
还要注意的是那条IF语句,下面再谈。
二、如何按你意愿加载这段程序
一般考虑到这个往往是你的设计中要区分上电复位和程序复位。有时候当程序复位时你不希望一些内存单元被清零了,那么你不对startup.a51作点修改,就不行了。
默认是自动加载这段startup.a51的。
所以你要这样做:
把lib目录下的原始startup.a51文件拷到你的项目所在目录下,再把你项目目录下的这个startup.a51加入到你的项目中(在keil的集成环境中,希望你对这个是知道如何做的),然后对这个startup.a51加以修改。
比如改成:
IDATALEN EQU 00H ; the length of IDATA memory in bytes.
然后编译链接。这样你的程序中就不会包含对idata清零的内码了。
为什么?上面提到的IF语句的作用呀!当定义IDATALEN=0时,清零代码被跳过!
////////////////////////////////////////////
Startup.a51的中文说明
;------------------------------------------------------------------------------
; STARTUP.A51: 用户上电初始化程序
;------------------------------------------------------------------------------
;
; 用户定义需上电初始化的内存空间
;
; 使用以下EQU命令可定义在CPU复位时需用0进行初始化的内存空间
;
;; ; IDATA 存储器的空间的绝对起始地址总是0.;
IDATALEN EQU 80H ; 需用0进行初始化的IDATA存储器空间的字节数
;
XDATASTART EQU 0H ; XDATA存储器空间的绝对起始地址
XDATALEN EQU 0H ; 需用0进行初始化的XDATA存储器的空间字节数.
;
PDATASTART EQU 0H ; PDATA存储器的空间的绝对起始地址
PDATALEN EQU 0H ; 需用0进行初始化的PDATA存储器的空间字节数.
;
; 注意: IDATA 存储器的空间在物理上包括了8051单片机的DATA和BIT存储器空间.
; 听 说 至少要保证与C51编译器运行库有关的存储器的空间进行0初始化 不知是否
;------------------------------------------------------------------------------
;
; 再入函数模拟初始化
;
; 以下用EQU指令定义了再入函数模拟堆栈指针的初始化
;
; 使用SMALL存储器模式时再入函数的堆栈空间 .
IBPSTACK EQU 0 ; 使用SMALL存储器模式再入函数时将其设置成1.
IBPSTACKTOP EQU 0FFH+1 ; 将堆栈顶设置为最高地址+1.
;
; 使用LARGE存储器模式时再入函数的堆栈空间.; 使用LARGE存储器模式时再入函数的堆栈空间.
XBPSTACK EQU 0 ; 使用LARGE存储器模式再入函数时将其设置成1.
XBPSTACKTOP EQU 0FFFFH+1; 将堆栈顶设置为最高地址+1.
;
; 使用COMPACT存储器模式时再入函数的堆栈空间.; 使用COMPACT存储器模式时再入函数的堆栈空间.
PBPSTACK EQU 0 ; 使用COMPACT存储器模式再入函数时将其设置成1.
PBPSTACKTOP EQU 0FFFFH+1; 将堆栈顶设置为最高地址+1.
;
;------------------------------------------------------------------------------
;
; 使用COMPACT存储器模式时64K字节XDATA存储器空间的分页定义
;
; 以下用EQU指令定义PDATA类型变量在XDATA存储器空间的页地址
; 使用EQU指令定义PFAGE时必须与L51连接定位器PDATA指令的控制参数一致
;
PPAGEENABLE EQU 0 ; 使用PDATA类型变量时将其设置成1.
PPAGE EQU 0 ; 定义页号.
;
;------------------------------------------------------------------------------
NAME ?C_STARTUP; 模块名为 ?C_STAUTUP
?C_C51STARTUP SEGMENT CODE ; 代码
?STACK SEGMENT IDATA ; 堆栈
RSEG ?STACK ; 堆栈
DS 1
EXTRNEXTRN CODE ((?C_START)) ; 程序开始地址
PUBLIC ?C_STARTUP
CSEG AT 0x8000 ; 定义用户程序的起始地址,用MON51仿真器时可能有用
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1::
;
; 初始化串口
MOV SCON,#40H
MOV TMOD,#20H
MOV TH1,#0fdH
SETB TR1
CLR TI
; 单片机上电IDATA内存清零 如果不需要上电清零IDATA 可以注销IF到IFEDN之间的话句
; 或者修改IDTALEN的长度 为了具有掉电保护功能 不知IDTALEN多长为好
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
;
; 单片机上电XDATA内存清零 如果不需要上电清零XDATA 可以注销IF到IFEDN之间的话句
; 或者修改XDATALEN的长度
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
;
; 送PDATA存储器页面高位地址
IF PAGEENABLE <> 0
MOV P2,#PPAGE
ENDIF
;
; 单片机上电PDATA内存清零 如果不需要上电清零XDATA 可以注销IF到IFEDN之间的话句
; 或者修改PDATALEN的长度
IF PDATALEN <> 0
MOV R0,#PDATASTART
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
;
; 设置使用SMALL存储器模式时再入函数的堆栈空间.
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV ?C_IBP,#LOW IBPSTACKTOP
ENDIF
;
; 设置使用LARGE存储器模式时再入函数的堆栈空间.
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
;
; 设置使用COMPACT存储器模式时再入函数的堆栈空间.
IF PBPSTACK <> 0
EXTRN DATA (C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF
;
; 设置堆栈的起始地址
MOV SP,#?STACK-1 ; 例如 MOV SP,#4FH;
; This code is required if you use L51_BANK.A51 with Banking Mode 4
; 如果你的程序使用了Mode 4 程序分组技术 请启动下面的程序,不会吧你的程序超过64K 利害
; EXTRN CODE (?B_SWITCH0)
; CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
;; 程序从第一组bank 0 块开始执行
; 跳转到用户程序MAIN函数
LJMP ?C_START
END
;lINSHENGFENG
上一篇:单片机有源蜂鸣器驱动之效率编程
下一篇:教你给51单片机扩展片外RAM
史海拾趣
|
电阻种类及特点简介 电阻,英文名resistance,通常缩写为R,它是导体的一种基本性质,与导体的尺寸、材料、温度有关。欧姆定律说,I=U/R,那么R=U/I,电阻的基本单位是欧姆,用希腊字母“Ω”表示,有这样的定义:导体上加上一伏特电压时,产生一 ...… 查看全部问答> |
|
我刚刚开始接触FPGA,资料也才看了一点,Verilog HDL也只是大致了解. 我在想要不要买块开发板,一边看资料一边在开发板上试试 以前学C的时候上课也觉得很枯燥,但是会经常自己编些小算术题之类的~呵呵 望有经验的兄弟姐妹给些建议 不慎感谢… 查看全部问答> |
|
想实现 运行状态 掉电保持,以便重新上电时恢复, 需要保持的数据大约 20字节, 该状态每秒更新一次。 请问有什么比较好的方法?掉电检测如何实现? //目前使用的方法是:Dallas SDRAM, 当作RAM一部分。 掉电检测没有,上电时检查状 ...… 查看全部问答> |
|
做应用的需要一片固定的内存,我在Config.bib中划好,在驱动里增加了MmIOMapSpace和MmIOUnMapSpace以及对应的IOCTL,在驱动内部测试,这片内存可以正常访问,map以及unmap。 我用IOCTL为应用返回这片内存的物理及虚拟地址,为什么在应用中使用该虚 ...… 查看全部问答> |
|
[求助]DPF播放一個半小時的幻燈圖片後就不再播放了。爲什麽? 在板子上做测试,从服务器上读图片,在板子上以幻灯片的形式播放,几乎每次一个半小时后就停止播放。系统是winCE的,网上查了好久,知道是订阅时间的问题,但不知道该改哪部分的代码,请达人们指教,小弟刚接触嵌入式开发。… 查看全部问答> |
|
偶刚入此行,有些问题过于菜鸟,请大虾多多指教。 本人使用at91sam9261 开发板,用 sam-ba 2.4 往dataflash里面写,用ads1.2便宜的bin文件,通过sam-ba 里面的“send boot file”可以将 bin文件写进去,reset后也可以被执行。但当偶有vxwork下的t ...… 查看全部问答> |
|
@8000 30 40 04 80 FF 3F 31 40 00 06 3C 40 0C 02 3E 40 F8 00 B0 12 EE A7 3C 40 00 02 3E 40 0C A8 30 12 0B 00 B0 12 00 A8 21 53 B0 12 44 A0 B0 12 12 A4 0A 12 0B 12 08 12 09 12 06 12 07 12 04 12 05 12 D2 93 E5 02 C5 20 C2 43 E5 ...… 查看全部问答> |
|
以前从没接触过430,我看到那个工作电流就傻眼了,口水啊……。视频教程也不能下载,最近没有时间看(只有上班时间才能上网,很少见吧!)。手上电路图也没有,幸好板子上所有连接都标注好了。看了看寄存器,感觉挺简单,无非就是PXSEL选择功能,PX ...… 查看全部问答> |




