STM32文件详解

STM32文件详解

启动文件

启动文件的方式

1、初始化堆栈指针 SP = _initial_sp

2、初始化程序计数器指针 PC = Reset_Handler

3、设置堆和栈的大小

4、初始化中断向量表

5、配置外部 SRAM 作为数据存储器(可选)

6、配置系统时钟,通过调用 SystemInit 函数(可选)

7、调用 C 库中的 _main 函数初始化用户堆栈,最终调用 main 函数

打开MDK

MDK->Help->uVision Help,

栈空间开辟

堆空间开辟

PRESERVE8:指示编译器按照 8 字节对齐。

THUMB:指示编译器之后的指令为 THUMB 指令

中断向量表


__Vectors 为向量表起始地址, __Vectors_End 为向量表结束地址,__Vectors_Size 为向量表大小,>__Vectors_Size = __Vectors_End - __Vectors。

复位程序

接下来是定义只读代码段

复位子程序代码

利用 PROC、ENDP 这一对伪指令把程序段分为若干个过程,使程序的结构加清晰。

对于 weak 的理解

weak 顾名思义是"弱"的意思,在汇编中,在函数名称后面加[WEAK]来表示,而在 C 语言中,在函数名称前面加上__weak 修饰符来表示,这样的函数我们称为"弱函数"。

被[WEAK]或__weak 声明的函数,我们可以在自己的文件中重新定义一个同名函数, 最终编译器编译的时候,会选择我们定义的函数,如果我们没有重新定义这个函数,那么编译器就会执行[WEAK]或__weak 声明的函数,并且编译器不会报错

对于_main 函数的分析

_main 代码是编译器自动创建的,因此无法找到_main 代码。

程序经过汇编启动代码,执行到__main()后,负责初始化堆栈,完成库函数的初始化,最后自动跳转向 main()函数。

中断程序

堆栈初始化

ALIGN指指令或数据的存放地址进行对齐,一般需要跟一个立即数

勾选了 Use MicroLIB 就代表定义了__MICROLIB 这个宏。

接下来进行堆栈空间初始化,堆是从低到高生长,栈是从高到低生长,是两个互相独立 的数据段,并且不能交叉使用。

Use MicroLIB

MicroLIB 是 MDK 自带的微库,是缺省 C 库的备选库,MicroLIB 进行了高度优化使得其代码变得很小,功能比缺省 C 库少。MicroLIB 是没有源码的,只有库。

系统启动流程

时钟树

一个简化的 STM32F1 时钟系统。图中已经把我们主要关注几处标注出来。

A 部分表示其它电路需要的输入源时钟信号;

B 为一个特殊的振荡电路"PLL",由几个部分构成;

C 为我们重点需要关注的 MCU 内的主时钟"SYSCLK";AHB 预分频器将 SYSCLK 分频或不分 频后分发给其它外设进行处理,包括到 F 部分的 Cortex-M 内核系统的时钟。

D、E 部分别为定时器等外设的时钟源 APB1/APB2。

G 是 STM32 的时钟输出功能,其它部分等我们学习到再详细探讨。

时钟源

对于 STM32F1,输入时钟源(Input Clock)主要包括 HSI,HSE,LSI,LSE。其中,从时钟频率来分可以分为高速时钟源和低速时钟源,其中 HSI、HSE 高速时钟,LSI 和 LSE 是低速时钟。

从来源可分为外部时钟源和内部时钟源,外部时钟源就是从 外部通过接晶振的方式获取时钟源,其中 HSE 和 LSE 是外部时钟源;其他是内部时钟源,芯片上电即可产生,不需要借助外部电路。

时钟配置函数

SYSCLK(系统时钟) =72MHz

AHB 总线时钟(HCLK=SYSCLK) =72MHz

APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz

APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz

PLL 主时钟 =72MHz

时钟初始化配置函数

c 复制代码
void SystemInit (void)
{
  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
  RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
  RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   
  
  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  RCC->CFGR &= (uint32_t)0xFF80FFFF;

#ifdef STM32F10X_CL
  /* Reset PLL2ON and PLL3ON bits */
  RCC->CR &= (uint32_t)0xEBFFFFFF;

  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x00FF0000;

  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;

  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;      
#else
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
    
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
  #ifdef DATA_IN_ExtSRAM
    SystemInit_ExtMemCtl(); 
  #endif /* DATA_IN_ExtSRAM */
#endif 

  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  /* Configure the Flash Latency cycles and enable prefetch buffer */
  SetSysClock();

#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}

SystemInit 函数开始通过条件编译,先复位 RCC 寄存器,同时通过设置 CR 寄存器的 HSI 时钟使能位来打开 HSI 时钟。

  1. 时钟控制寄存器(RCC_CR)
  2. 时钟配置寄存器(RCC_CFGR)
  3. 时钟中断寄存器(RCC_CIR)
  4. APB2 外设复位寄存器(RCC_APB2RSTR)和APB1 外设复位寄存器

默认情况下如果 CR 寄存器复位, 是选择 HSI 作为系统时钟,这点大家可以查看 RCC->CR 寄存器相关位描述可以得知,当低两位配置为 00 的时候(复位之后),会选择 HSI 振荡器为系统时钟。

在 system_stm32f10x.c 文件的开头就有对此宏定义,系统默认的宏定义是72MHz

c 复制代码
#define SYSCLK_FREQ_72MHz 72000000

如果你要设置为 36MHz,只需要注释掉上面代码

c 复制代码
#define SYSCLK_FREQ_36MHz 36000000 
相关推荐
小菜鸟学代码··24 分钟前
STM32中断详解
stm32·单片机·嵌入式硬件
芒果de香蕉皮44 分钟前
mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
stm32·单片机·嵌入式硬件·算法·无人机
Yyq130208696821 小时前
MS41908M网络摄像机·监控摄像机用镜头驱动芯片(内置光圈控制
嵌入式硬件
DS小龙哥2 小时前
基于STM32单片机矿井矿工作业安全监测设计
stm32
musir12 小时前
stm32四联七段数码管,LED8*8点阵
stm32·单片机·嵌入式硬件
m0_748250033 小时前
【STM32】F103ZET6开发板----笔记01
笔记·stm32·嵌入式硬件
1101 11013 小时前
STM32-笔记16-定时器中断点灯
笔记·stm32·单片机
weixin_438150993 小时前
广州大彩串口屏安卓/linux触摸屏四路CVBS输入实现同时显示!
android·单片机
搬砖的小码农_Sky3 小时前
硬件设计:RS485电平标准
单片机·嵌入式硬件·fpga开发
ElePower95274 小时前
STM32学习(一)
stm32·嵌入式硬件