STM32开发核心要点
一.时钟
CPU的运行必然依靠时钟节拍,STM32时钟源有内部高速、低速,外部高速(RC)、低俗时钟源(晶振),RC不稳定、晶振很稳定。时钟源经过PLL锁相环选择后成为系统时钟SYSCLK,SYSCLK经过AHB预分频器后得到高性能总线时钟HCLK(也是CPU使用的时钟),然后滴答定时器通过CPU的HCLK分频得到时钟(等于HCLK或者HCLK/8),滴答定时器用于裸机死等延时或开启中断作为系统节拍。此后HCLK经过分频器来到APB1(PLCK1)低速总线和APB2(PLCK2)高速总线,各外设挂载在APB1和APB2上。外设的时钟是关闭的,需要时才打开。
二.中断
中断:中断就是 MCU 对突发事件的快速响应机制。
MCU的中断控制分为两个层次,第一层为NVIC,NVIC是CPU内部的中断总开关,第二层是外设自身的中断控制寄存器,如果想让外设的中断能够起作用就必须同时配置NVIC和外设自身的中断使能。外设激活中断的逻辑为:触发中断条件,然后相应的中断标志位被硬件置1(大部分需要中断处理完毕由软件置0),经由NVIC进行优先级的比较决定是否进入对应的中断处理函数,然后由于大部分外设只有一个中断公共处理函数,而具有多种中断,所以需要在中断处理函数中进行辨别再处理。EXTI外部IO中断则是将GPIO的某个引脚开启中断并进行配置,当该GPIO输入相应的电平信号后会将中断信号传入NVIC,再由NVIC决定是否进入中断处理函数。
三.外设控制
MCU的一切都可以看作是对寄存器进行配置来完成的控制。外设也不例外,外设的寄存器可以分为控制寄存器,数据寄存器和状态寄存器,控制寄存器派生出了中断使能寄存器和配置/参数寄存器,数据寄存器派生出来CNT/CCR寄存器,状态寄存器派生出了原始状态/中断标志寄存器和中断清除寄存器。
四.主循环特性
一般在主循环开始前会配置好各项系统参数包括时钟、HAL库初始化、以及各种外设的初始化函数,然后在主循环中的一般逻辑是顺序运行,以过程为中心。
五.MCU的上电过程
阶段一:硬件硬编码初始化(无需程序干预)
当你按下复位键或通电的那一瞬间,芯片内部的硬件电路会强制进行一轮硬件级别的寄存器复位:
-
所有的控制寄存器、状态寄存器、总线时钟寄存器全部被刷成默认值(比如大部分控制位变 0,所有外设断电)。
-
核心动作:CPU 内部的 PC(程序计数器)寄存器会被强制写入一个固定的死地址(例如 STM32 中默认是
0x0000 0000或0x0800 0000)。CPU 别无选择,上电第一步只能去这个寄存器指向的内存地址读代码。
阶段二:启动文件(Startup_xxx.s)配置阶段
CPU 顺着 PC 寄存器指引的地址,读到了用汇编语言写的启动文件。这个阶段主要配置两类跟“内存空间”相关的寄存器:
-
SP(堆栈指针寄存器):写入栈顶地址,给 C 语言运行划定内存底线。
-
中断向量表寄存器(VTOR):把一整排中断服务函数的入口地址,塞进内核的中断向量寄存器里(包括你前面提到的定时器中断、EXTI中断、SysTick中断的函数指针)。
3. 阶段三:SystemInit() 时钟树配置阶段 —— 【激活灵魂】
启动文件的最后,会跳去执行一个 C 语言函数叫 SystemInit()。在这个函数里,发生的就是我们前面讨论的时钟树寄存器大爆发:
-
配置 Flash 访问寄存器:因为 CPU 马上要飙到 72MHz/168MHz 了,但 Flash 闪存硬件跟不上这么快,必须先配置 Flash 控制寄存器(
FLASH->ACR),让它开启等待周期(Latency)。 -
配置 RCC 寄存器:打开 HSE 外部晶振,等待状态寄存器(
RCC->CR)的HSERDY位置 1;然后配置RCC->CFGR设定 PLL 的倍频系数,开启 PLL;最后等 PLL 稳定了,切换多路开关,把系统时钟(SYSCLK)切到 PLL。 -
至此,总闸通电,芯片彻底活了。
4. 阶段四:main() 函数中的外设配置阶段 —— 【走向业务】
终于进入了你写的 main() 函数。在这个阶段,你调用各种 HAL_TIM_Init()、HAL_GPIO_Init(),它们翻译成底层,全都是在摆弄寄存器:
-
外设控制:写
TIMx_CR、USART_CR来规定工作模式。 -
中断使能:写外设的
DIER/IMR寄存器打开局部中断,写内核的NVIC寄存器打开内核大门。 -
数据传输:如果是普通传输,就是 CPU 读写
DR/RDR/TDR数据寄存器;如果是高速传输,你就去配置 DMA 控制寄存器(告诉它源地址、目的地址、传输长度),然后写个EN位,DMA 寄存器就会接管总线自己去传数据。
更多推荐


所有评论(0)