IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32的启动过程分析 -> 正文阅读

[嵌入式]STM32的启动过程分析

本文分析STM32单片机从上电到运行的过程,目的在于了解STM32单片机从启动到运行的整个过程。

一般我们在使用STM32单片机的时候,都是使用官方提供的驱动文件,移植到自己即将要使用的工程中,移植完成之后再编写自己的逻辑代码,放到main( )函数中,就可以完美的运行起来了。相信很多的人都没有去关注过STM32从启动到运行这个过程都发生了什么,现在就简单分析一些这个过程。

本文以STM32F103为例进行分析。在官方给我们提供的启动文件中,将整个单片机的启动过程要做的事情都已经帮我们做好了,以至于我们在使用这款单片机的时候,几乎可以不会吹灰之力就可以运行起来。STM32F103的启动文件形如:
在这里插入图片描述
根据不同的芯片容量,都有相对应的启动文件可供选择,实际使用根据芯片容量选择合适的启动文件即可。

启动文件的主要作用有:

1)设置栈

2)初始化 SP 指针

3)设置堆

4)复位中断服务函数

5)调用 SystemInit()函数来完成初始化工作

6)调用__main,该函数内部会调用 main()函数

1、设置栈
从启动文件中可以看到:
在这里插入图片描述
上述代码中:
1)35行,将栈的大小设为0x00000400(即1024 = 1KB)。
2)37行,栈名称为STACK,不初始化,可读可写,8(2^3)字节对齐。
3)38行,分配一片连续的存储区域并初始化为 0,大小为0x400个字节。
4)39行,__initial_sp表示栈的结束地址,即栈顶地址,STM32中栈是由高地址向低地址生长。

2、设置堆
在这里插入图片描述上述代码中:
1)45行,将堆的大小设为0x00000200(即512B = 0.5KB)。
2)47行,栈名为HEAP,不初始化,可读可写,8(2^3)字节对齐。
3)48行,堆空间起始地址。
4)49行,堆空间:0x200个字节。
5)50行,堆空间结束地址。

3、对堆栈属性进行设置
在这里插入图片描述
1)PRESERVE8 指令指定当前文件保持堆栈八字节对齐。
2)告诉汇编器下面是32位的Thumb指令,如果需要汇编器将插入位以保证对齐。

4、设置中断向量表
在这里插入图片描述
1)57行,定义一块数据段,只可读,段名字是RESET。
2)58行,EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用。
3)59行,在程序中声明一个全局的标号__Vectors_End。
4)60行,在程序中声明一个全局的标号__Vectors_Size。

之后的是中断的定义,可以分为两部分:
一部分是系统内部中断:
在这里插入图片描述
另一部分是外部中断:
在这里插入图片描述
在之后是中断向量表的其他设置:
在这里插入图片描述
1)142行,得到向量表的大小。

2)144行,定义一个代码段,可读,段名字是.text。

5、中断功能的定义

复位中断:

在这里插入图片描述
1)149行,IMPORT:伪指令用于通知编译器要使用的标号在其他的源文件中定义。
2)150行,系统初始化。
3)151行,R0的值为SystemInit的地址。
4)152行,切换指令集,跳到SystemInit。
5)153行,R0的值为__main的地址。__main是库提供的函数。用于完成堆栈,堆的初始化等工作,还会调用__user_initial_stackheap。
6)154行,切换指令集,跳到__main,并且最终会跳转到main(),进入C语言运行环境。

6、用户栈和堆初始化
在这里插入图片描述
1)333行,如果勾选了micro lib,使用微库。
2)339行,没有勾选微库。
在这里插入图片描述
1)344,用户堆栈初始化程序入口。
2)346,保存堆起始地址。
3)347行,保存栈结束地址。
4)348行,保存堆结束地址。
5)349行,保存栈起始地址。

7、中断跳转
中断发生之后,是怎么实现跳转到相应的中断服务函数里面的呢?
1)首先,前面定义好了中断的响应函数,即中断向量表,标号__Vectors,表示中断向量表的入口地址。
2)我们假设STM32从FLASH启动,则中断向量表起始地址为0x8000000,STM32上电后根据boot引脚来决定PC位置,即启动后PC跳到0x08000000。
3)然后CPU会先取2个地址,第一个是栈顶地址,第二个是复位异常地址(Reset_Handler),Reset_Handler最终会进入到C语言的运行环境,这个时候会先配置NVIC,使用NVIC_SetVectorTable()可以配置中断向量表的起始地址和偏移,告诉CPU该向量表是位于Flash还是Ram,偏移是多少。
4)在发生中断后,CPU找到中断向量表地址,然后根据偏移(对号入座)再找到中断地址,这样就完成了跳转了。

嵌入式学习,请关注微信公众号“嵌入式之入坑笔记”,全网同名!
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:13:51  更:2022-01-16 13:15:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:33:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码