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 分钟前
无人机系统耗电,低功耗管理问题解决方法(chatgpt)
单片机·嵌入式硬件·无人机
时空自由民.29 分钟前
无人机系统耗电,低功耗管理问题解决方法(腾讯元宝)
单片机·嵌入式硬件·无人机
清风6666662 小时前
基于单片机的双档输出数字直流电压源设计
单片机·mongodb·毕业设计·nosql·课程设计
牛马大师兄2 小时前
STM32独立看门狗IWDG与窗口看门狗WWDG知识梳理笔记
笔记·stm32·单片机·嵌入式硬件·嵌入式·看门狗
夜月yeyue2 小时前
STM32 Flash 访问加速器详解(ART Accelerator)
linux·单片机·嵌入式硬件·uboot·bootloard
A9better2 小时前
嵌入式开发学习日志37——stm32之USART
stm32·嵌入式硬件·学习
国科安芯6 小时前
ASP4644芯片低功耗设计思路解析
网络·单片机·嵌入式硬件·安全
充哥单片机设计6 小时前
【STM32项目开源】基于STM32的智能厨房火灾燃气监控
stm32·单片机·嵌入式硬件
CiLerLinux13 小时前
第四十九章 ESP32S3 WiFi 路由实验
网络·人工智能·单片机·嵌入式硬件
时光の尘13 小时前
【PCB电路设计】常见元器件简介(电阻、电容、电感、二极管、三极管以及场效应管)
单片机·嵌入式硬件·pcb·二极管·电感·三极管·场效应管