本帖最后由 JackTang1994 于 2022-2-8 10:43 编辑
#申请原创# #技术资源#
软件环境:MPLAB X IDE v5.5,XC8编译器
硬件环境:ATmega4809 Curiosity Nano开发板
参考资料
AVR指令集文档:https://www.microchip.com/DS40002198
ATmega4809 Curiosity Nano开发板:https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega4809_Curiosity_Nano_Schematics.pdf
AVR编译器用户手册:http://ww1.microchip.com/downloads/en/DeviceDoc/50002750D.pdf
示例代码工程:
存储器介绍
存储器类型介绍RAM:随机存储器,速度快。可以按字节访问,掉电后数据丢失。
常用类型:SRAM、SDRAM、DDR等。
ROM:只读存储器,速度相对于RAM来说更慢。一般不能按照字节访问,基本访问单位一般为page(页)而且需要先擦除后才能写,掉电后数据依然保持,不会丢失。
常用类型:Flash、EEPROM、NandFlash、NorFlash等
总结:根据存储器特性,程序代码会被设计存储到ROM中,在MCU中ROM一般叫做Flash;而变量数据则会被设计存储在RAM中。
编译与链接是什么?
编译就是将源代码(C代码或者汇编代码)翻译成机器码(只包含01的二进制数)。根据不同的架构位数的MCU相应的编译器生成后的机器码长度也不一样。一般有16位、32位的机器码。
链接就是将生成的机器码进行组装,将其他源代码中的数据、代码放置在不同的内存区域。然后下载器再根据工程中设置下载地址,将生成的机器码镜像下载到相应的存储地址处。
MCU源代码编译链接及操作流程
说明:编译器和链接器以及代码下载软件工具都集成在了开发工具MPLAB X IDE中了
什么是启动代码?
启动代码就是芯片复位后最开始运行的代码。功能如下:- 设置栈(给C语言代码运行用的,用于程序的调用及局部变量)
- 设置堆(需要使用动态内存时设置)
- 中断向量表设计
- 调试器相关配置(有些调试器需要MCU处于相应调试状态时才能进行调试,比如:Trace,在进行trace时需要设置MCU中控制trace的相关寄存器)
- 对存储器的操作(代码搬运、RAM清零、以及将非0全局变量从ROM中搬移到RAM中)等操作。
启动代码的基本功能:设置栈、设置中断向量表
为什么MCU开发中,我们没有写过启动代码
因为这些启动代码,一般芯片公司已经写好了,已经放置在了下载的MCU pack包中了,我们创建工程后会自动复制到我们工程中。或者有些启动代码是自动生成的,不需要我们再写了。
编译选项设置
默认情况下,MPLAB中会使用默认的启动代码(MicroChip写好的)。如果想要在工程中使用我们编写的启动代码,则需要设置下编译选项:
查看预定义的section
目的:查看我们代码应该放置在哪个预定的区,因为我们没有修改默认的链接脚本。
查看MPLAB安装目录下的MPLAB_XC8_C_Compiler_User_Guide_for_AVR.pdf文档,从4.9章节可以知道,MPLAB链接脚本中已经预定义了10个在main调用之前运行代码的section(.init0-.init9)、10个在main调用之后运行代码的section(.fini0-.fini9)。
注:默认链接脚本路径:XXX\Microchip\xc8\v2.31\avr\avr\lib\ldscripts
MCU中断函数处理
在没有跳转语句时,代码是从头开始一条一条运行的。当发生中断时程序会自动跳转到相应的中断入口地址处而中断入口地址是连续的地址,一般我们把这连续的中断入口地址也叫做中断向量表。因为中断入口地址对应的内存空间只有16bit(2字节),这个空间根本无法保存我们的中断服务函数代码。所以我们会在中断入口地址处放置一条跳转语句,跳转到我们中断服务函数入口地址,从而来执行我们的中断服务函数。
启动代码编写——汇编版
|