STM32那点事(1) 您所在的位置:网站首页 define意思中文 STM32那点事(1)

STM32那点事(1)

2023-03-13 10:21| 来源: 网络整理| 查看: 265

STM32 官方为广大开发者提供一套统一开发固件,主要是屏蔽寄存器封装,提供初始化等功能,较少开发者负担。只需要调用相关模块封装,对相关结构提初始化即可,较少开发调试时间。本次主要以官方STM32F4xx_DSP_StdPeriph_Lib_V1.8.0固件版本为主,主要讲解各个模块主要作用以及使用方法,固件主要结构将在后面做介绍 本次主要讲解开发过程中大家都会忽略的STM32 启动文件流程,STM43 启动文件名为startup_stm32f40_41xxx.s,其目录在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm,也可以按照整个文件名搜索整个固件,会发现有很多相同文件分布在不同目录,主要是因为官方固件提供很多开发样例,每个样例都需要进行启动文件,官方提供用例在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Examples\中。启动文件时以.s开头,都是用ARM汇编指令集来完成的。具体ARM汇编可以参考《Arm 体系结构与编程》

启动文件工作 1:初始化堆栈空间 2:PC指针 Rest_Handler 3: 初始化中断向量表 4:系统时钟 5:堆栈初始化完成之后,进入main函数

初始化栈空间 初始化文件开头代码 首先是初始化栈空间代码如下: 在这里插入图片描述 上述代码的意思是开辟空间为0x00000400(1KB)的栈空间, 主要用于局部遍历,函数调用,参数形参等开销,不能超过芯片内部SRAM。可以根据需要进行调整,防止程序溢出 EQU:为ARM汇编伪指令,相当于C中define,意思为定义Stack_Size 代表0x00000400 AREA: 汇编伪指令,意思是定义伪一个代码端或者数据段,其格式为 AREA sectionname {,attr} {,attr} sectionname为定义的代码或者数据段名字, attr为该字段属性 AREA STACK, NOINIT, READWRITE, ALIGN=3 意思为 定义该数据段名字为STACK,NOINIT指定本数据段仅仅保留了内存单元,而没有将各初始值写入内存单元。 READWRITE为该数据段即可写又可读, ALIGN为字节对齐,为2的3次方等于8,8字节对齐。 SPACE:用于一块内存单元,并用0初始化。申请Stack_Size大小内存。 __initial_sp 紧随SPACE后面,表示申请内存的结束地址,即栈顶位置,栈是由高向低生长,故需要指向栈顶位置

初始化堆空间 紧接着为堆空间地址申请,代码如下 在这里插入图片描述 堆空间大小为Heap_Size即0x00000200(512Byte),EQU AREA和SPACE指令上面已经讲到 不再解释。__heap_base在SPACE之前,因为堆空间是向上增长的,__heap_base指向为堆的地址,__heap_limit为堆的结束地址。 PRESERVE8:当前代码中数据段是8字节对齐,因为汇编指令中LDRD和STRD指令要求内存单元地址是8字节对齐的,在程序中使用这些指令在数据栈中传送数据时,要求该数据段是8字节对齐。 THUMB:兼容THUMB指令集。THumb指令集是堆ARM指令集的一个子集进行重新编码得到得,其指令长度为16位。THUMN-2为32位。

中断向量表初始化 接下来将会进入中断向量表: 在这里插入图片描述 定义RESET数据段为可读,中断向量表本质上为一张中断函数指针,每个地址记录中断服务程序入口地址,发生中断后,STM32将会进入到相应的中断服务程序,每个地址代表不同的中断,由厂商写死,不可更改,《STM32F4xx中文参考手册》中可知,每个地址代表的中断: 在这里插入图片描述 篇幅有限并没有详细列出来,可以查看手册 EXPORT:声明一个标号可被外部的文件使用,使标号具有全局属性,上述代表中分别定义__Vectors为中断向量首地址,__Vectors_End为中断向量表末尾地址,__Vectors_Size为中断向量大小,实际代码中断向量表如下:

在这里插入图片描述 DCD:分配一个或者多个以字为单位的内存,以4字节对齐,并要求初始化这些内存。 __initial_sp为0x0000 0000地址,为初始化栈地址,Reset_Handler为复位中断程序,该处理采用汇编进行编写 __Vectors_Size为计算中断向量表大小为(__Vectors_End - __Vectors)。 在这里插入图片描述

Reset Handler reset为程序上电进入,设置时钟,进入main函数处理 在这里插入图片描述 首先声明Reset_Handler, SystemInit和__main函数,SystemInit为外部C语言编写文件主要是对时钟初始化,__main为main函数入口,可以被该汇编文件进行调用。 LDR:从存储器中加载到寄存器中。 BL:程序跳转指令,程序PC指针跳转到由寄存器/标号给出的地址,并把跳转前的下一条指令地址保存到LR中 BLX: 与BL不同之处,根据寄存器的LSE确定处理器的状态,并把跳转前的下一条指令保存到LR。 上述程序,首先把SystemInit()函数地址加载在R0中,并跳转到SystemInit()函数,执行SystemInit,执行完毕后 加载__main函数,程序跳转到main函数中。 SystemInit()函数功能意义在后续中继续解释。

中断服务程序 中断服务程序默认没有编写,默认的中断程序如下: 在这里插入图片描述 上述每个中断程序默认为无限循环,当进入到中断,而开发者有没有实现中断服务程序将会进入死循环。 注意:中断服务程序需要开发者实现相应中断,一般是在stm32f4xx_it.c文件中。

堆初始化 堆的初始化调用是在一下程序中: 在这里插入图片描述

IF:相当于C中if ,上述代码意思是判定__MICROLIB宏是否定义 如果定义,将会跳转到__initial_sp,使用上述代码中默认堆栈大小初始化,如果没有定义将会使用__use_two_region_memory,用户自定义。 __MICROLIB宏的定义是在keil5工具中进行勾选,如下所示: 在这里插入图片描述 参考文档 《 零死角玩转STM32》 《STM32F4XX中文参考手册》 《arm体系结构与编程》



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有