谷动谷力

 找回密码
 立即注册
查看: 537|回复: 0
打印 上一主题 下一主题
收起左侧

单片机启动代码分析

[复制链接]
跳转到指定楼层
楼主
发表于 2023-7-31 19:37:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sunsili 于 2023-8-1 13:07 编辑

单片机启动代码分析

51单片机启动文件在哪

当我们使用C语言开发51系列内核的单片机时都需要添加一个启动文件到项目中,比如keil工程下的STARTUP.A51文件。当然不管你是使用Keil,IAR或是其他开发工具都会需要类似的文件,只是工具平台中对其中内容描述不一样而已,也有一些开发工具不需要添加,只是其编译器内部已经做了一些处理,不需要我们操心了。


启动文件对开发很重要

其实不仅仅是51单片机开发需要启动文件,所有单片机(说更广一点应该是需要程序控制的芯片吧),只要你是用C语言开发(或是说除汇编以外的其他语言)就都需要启动文件。为什么呢?因为启动文件实质就是一个汇编文件,如果你是用汇编代码做开发,那肯定就用不上它们了。这篇文章我们先介绍51单片机的启动文件,明天如果时间充足可再把STM32的启动文件对比分析一下,帮助大家深入理解。

如果是使用keil开发,那在我们新建工程的过程的最后一步一般都会弹出一个对话框让你选择是否将XXX文件添加到工程中,如下图所示:


弹出的对话框

选择是这里就是编译器自动就将文件添加到工程目录下了(如果是古老的版本可能不会有对话框出现,需自己手动复制添加),可参考下图:



工程目录结构内容

一般教材或教程中都不会对这个文件做过多说明,再加上很多开发工具都给我们自动添加进去了,所以很多初学者都不会去了解这个文件,更不会去关注这个文件的作用。并且大多数时候我们都是直接使用它,又加上它内部完全是汇编代码,所以基本上大家都不会去关心它,只会在建工程的时候告诉你要将xxx文件添加进去。

启动文件,顾名思义,通俗来说就是程序启动的时的准备文件,芯片上电或复位时会按照其中代码来进行一些必要的初始化操作,随后引导程序跳转到我们的代码中去,就这么个过程,说简单把里面也没啥东西,说复杂的话它决定了我们的代码能否运行,怎么运行这些的大事。

对于51或其他一些资源没那么丰富的单片机来说启动文件的关键代码可能只需要十来行就差不多了。因为我们平时都几乎用不着去管它,所以初学的时候去讲解其中内容不是自讨苦吃吗,傻瓜才会干吧?但如果是复杂的芯片就不一样了,一些我们想对程序进行的特殊控制就可以在启动文件中进行设置了,所以想要了解某些芯片的启动过程,或了解它们内核原理还是可以看看编译器公司或芯片厂家官网给的启动文件。如果他们没提供这些启动文件,那我们用户就得自己手动编写这些程序了!所以三四十年前研究单片机的肯定都是大牛,当然老外对这些东西有一定的先天优势,所以有的东西教不好,学不好不一定是我们的错,哈哈哈……


51单片机启动文件内容

你打开你的51工程直接找到对应的文件就可以查看该文件内容了,确确实实是汇编代码吧。

STARTUP.A51文件截图

不过,好在大部分内容都是注释,现在我们一起来了解一下这些汇编代码的意义。

$NOMOD51 ; 禁止定义文件修改

; 定义IDATA、XDATA、PDATA存储区域的起始地址和长度

IDATALEN EQU 80H ; IDATA长度为80H
XDATASTART EQU 0 ; XDATA起始地址
XDATALEN EQU 0 ; XDATA长度为0

PDATASTART EQU 0 ; PDATA起始地址
PDATALEN EQU 0 ; PDATA长度为0

; 定义中断服务例程堆栈空间

IBPSTACK EQU 0 ; SMALL模型堆栈禁用
IBPSTACKTOP EQU 0xFF+1 ; SMALL堆栈顶地址

XBPSTACK EQU 0 ; LARGE模型堆栈禁用
XBPSTACKTOP EQU 0xFFFF+1 ; LARGE堆栈顶地址

PBPSTACK EQU 0 ; COMPACT模型堆栈禁用
PBPSTACKTOP EQU 0xFF+1 ; COMPACT堆栈顶地址

; PAGE配置

PPAGEENABLE EQU 0 ; 禁用PDATA分页
PPAGE EQU 0 ; PPAGE页码
PPAGE_SFR DATA 0A0H ; PPAGE的SFR地址

; 标准特殊功能寄存器符号定义

ACC DATA 0E0H
B DATA 0F0H
SP DATA 81H

; 初始化数据存储区

IDATALOOP: MOV @R0,A ; 初始化IDATA
XDATALOOP: MOVX @DPTR,A ; 初始化XDATA
PDATALOOP: MOVX @R0,A ; 初始化PDATA

; 初始化堆栈指针

MOV SP,#?STACK-1

; 跳转调用主程序

LJMP ?C_START

现在应该可以知道启动文件做了什么工作了吧?

1. 定义内存区域

使用EQU语句定义了chip内部的IDATA、XDATA、PDATA的起始地址和长度。

2. 定义中断堆栈区

为中断服务例程定义了独立的堆栈区域,分别对应SMALL、LARGE、COMPACT模型。

3. PAGE配置

对于采用页模式的PDATA存储区域,进行相关的页配置。

4. SFR定义

定义了程序会用到的一些特殊功能寄存器的地址,如ACC、B、SP等。

5. 数据区初始化

通过循环初始化指令,清零IDATA、XDATA、PDATA的数据存储区域。

6. 堆栈指针

初始化堆栈指针SP,指向顶部地址为主程序提供堆栈空间。

7. 跳转调用,进入用户程序

通过LJMP指令无条件跳转并调用主程序入口。

总的来说,启动文件完成了存储器初始化,中断堆栈配置,以及进入主程序等准备工作。这为51单片机工程的执行奠定了基础,如果你了解了这些底层工作再去理解单片机的开发应该可以让你更能像芯片一样思考程序吧。希望这篇文章可以在你学习或未来的职业生涯中帮到你哟!看懂的不妨点个赞加分享,没懂的不妨打印出来,可以睡前多看几遍。


题外话,如果现在要修改单片机复位后程序的启动位置在这个文件中能否实现,那应该怎么修改呢?


当然只是提个想法,这些参数在开发工具中就可以设置,实际使用基本不会对51做这些处理,所以不要被这些内容吓到了。


当然如果上面这个问题理解了,以后接触bootloader或boot应该理解起来就没啥大问题了。



+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-4-29 17:41 , Processed in 0.077585 second(s), 40 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表