STM32启动过程分析
- 格式:docx
- 大小:16.38 KB
- 文档页数:2
东软stm32期末考试题及答案一、单项选择题(每题2分,共20分)1. STM32系列微控制器属于以下哪种类型的微控制器?A. 8位微控制器B. 16位微控制器C. 32位微控制器D. 64位微控制器答案:C2. STM32的内部时钟系统不包括以下哪一项?A. 内部高速时钟(HSI)B. 外部高速时钟(HSE)C. 外部低速时钟(LSE)D. 外部中速时钟(MSE)答案:D3. 在STM32中,以下哪个寄存器用于控制GPIO的模式?A. GPIOx_MODERB. GPIOx_OTYPERC. GPIOx_OSPEEDRD. GPIOx_PUPDR答案:A4. STM32的中断优先级配置中,抢占优先级和响应优先级的范围是多少?A. 0-15B. 0-31C. 0-255D. 0-1023答案:B5. STM32的以下哪个外设不是用来实现通信的?A. USARTB. SPIC. I2CD. ADC答案:D6. STM32中,以下哪个选项不是ADC的触发方式?A. 软件触发B. 硬件触发C. 外部中断触发D. DMA触发答案:D7. STM32的以下哪个寄存器用于配置定时器的计数模式?A. TIMx_CR1B. TIMx_CR2C. TIMx_SMCRD. TIMx_DIER答案:C8. STM32中,以下哪个选项不是DMA的通道?A. DMA1_Channel1B. DMA2_Channel2C. DMA1_Channel7D. DMA3_Channel4答案:D9. STM32的以下哪个寄存器用于配置RCC时钟?A. RCC_CRB. RCC_CFGRC. RCC_CIRD. RCC_PLLCFGR答案:B10. STM32中,以下哪个选项不是电源控制寄存器PWR的控制位?A. PVDEB. DBPC. FPDSD. VOS答案:A二、填空题(每题2分,共20分)1. STM32的内部高速时钟(HSI)的频率是_________ MHz。
解析STM32启动过程
STM32启动过程是指当电源被接通时,STM32芯片进行自检并加载固
件的过程。
这个过程可以分为四个主要阶段:复位阶段、时钟初始化阶段、中断向量表重定位阶段和主函数执行阶段。
时钟初始化阶段是STM32启动的第二个阶段。
在复位阶段,系统时钟
会被配置为默认的内部RC振荡器,通常为8MHz。
在时钟初始化阶段,可
以通过程序代码来配置系统时钟,包括选择和配置时钟源、设置时钟分频等。
时钟的初始化是系统正常运行的前提条件,因为大多数外设的工作频
率都与系统时钟相关。
主函数执行阶段是STM32启动的最后一个阶段。
在中断向量表重定位
完成后,主函数会被调用执行。
主函数中通常会初始化系统的各种外设,
配置时钟、GPIO、中断等,并进入一个无限循环等待外设事件的发生。
一
旦外设事件发生,会触发中断,处理对应的中断服务程序。
总结来说,STM32启动过程包括复位阶段、时钟初始化阶段、中断向
量表重定位阶段和主函数执行阶段。
复位阶段进行系统自检和硬件初始化,时钟初始化阶段配置系统时钟,中断向量表重定位阶段将中断向量表重定
位到实际的起始地址,主函数执行阶段初始化外设并进入循环等待外设事
件的发生。
这个过程是STM32系统启动的基本过程,对于系统的正常运行
起着关键作用。
在ARM编程领域中,凡是打断程序顺序执行的事件,都被称为异常。
除了外部中断外,当有指令执行了“非法操作”,或者访问被禁的内存区间,因各种错误产生的fault,以及不可屏蔽中断发生时,都会打断程序的执行,这些情况统称为异常。
简单来说:异常包括外部中断和内核fault。
外部中断(IRQ):原本处于正常状态,突然有个外部因素干扰,然后马上处理干扰事项,解决好后又回到原来正常状态。
在中断产生后一般会去执行中断服务函数,实现特定任务。
无特殊说明,后面:异常就是中断,中断就是异常在编译时,每一个函数都有一个入口地址,该地址就是函数名。
尽管函数不是变量,但它在内存中仍有其物理地址,该地址能够赋给指针变量。
函数名相当于一个指向其函数入口指针常量。
函数名后面加圆括号,表示函数调用。
若要得到函数的地址,直接用函数名就可以了。
函数名就是一个地址,是存放该函数代码在存储器空间上的起始地址。
以一个子函数为例,编译器会分配一段内存空间用于存放改子函数代码内容,这段内存空间的起始地址是一个具体值,在程序里边就是函数名,当我们在程序其他位置调用该子函数时候,实际上就是让程序跳转到该函数名地址去运行子函数内容。
Cotrex-M4支持大量的中断,包括16‐5(保留功能)-1=10个系统异常,和最多240个外部中断。
当一个中断发生时候,并由CM4内核接受后,会执行对应的中断服务函数。
所以可以想象需要定义非常多的中断服务函数(而实际上并不需要很多,因为一般都只使能我们需要用到的中断)。
为方便CM4找到对应的中断函数入口,CM4使用了“向量表查表机制”这里使用一张向量表。
向量表其实是一个WORD(32位整数)数组,每个下标对应一种中断,该下标元素的值则是该中断服务函数的入口地址。
●#1~15(系统异常)在CortexM4中定义,IRQ#0~239(外部中断)中断由各个芯片商定义●向量表定义了中断的处理例程的入口地址。
缺省情况下,CM4认为向量表位于零地址处●响应中断时,CM4会根据中断号从表中找出对应的中断处理程序的入口地址●每个表项占用4字节●位置0x00000000处保存的是MSP的初始值异常类型表项地址偏移量异常向量00x00MSP的初始值10x04复位20x08NMI30x0C硬fault40x10MemManage fault50x14总线fault 60x18用法fault7‐100x1c‐0x28保留110x2c SVC120x30调试监视器130x34保留140x38PendSV 150x3c SysTick 160x40IRQ #0170x44IRQ #1中断向量表的跳转●支持10个Cortex-M4系统异常和82个可屏蔽外部中断●16个可编程优先级(使用了4位中断优先级)●包括内核异常在内的所有中断均通过NVIC进行管理。
解析STM32的启动过程STM32的启动过程可以分为硬件启动过程和软件启动过程两部分。
硬件启动过程主要是指芯片上电后的初始化阶段,而软件启动过程则是指固定在芯片内的启动程序的执行过程。
硬件启动过程1.上电复位:当STM32芯片上电后,会进行一次复位操作,将片内的所有寄存器初始化为默认值。
2.时钟初始化:芯片复位后,需要初始化芯片的各个时钟源和时钟分频系数。
例如,配置系统时钟、外设时钟和外设时钟的分频。
3.外设初始化:初始化芯片的各个外设,包括GPIO、USART、SPI、I2C等。
外设初始化主要是配置相应的寄存器使它们能够正常工作。
4.中断向量表:中断向量表是储存在芯片中的一系列函数指针,用于响应中断事件。
在硬件启动过程中,需要将中断向量表的地址设定为固定的位置,并将其中各个中断的函数指针初始化为默认的中断服务函数。
5.系统堆栈初始化:系统堆栈是用于存储函数调用时的临时变量和程序返回地址的存储区域。
在硬件启动过程中,需要初始化系统堆栈指针,为后续的函数调用和中断处理做准备。
6. 程序复位:在芯片复位后,可以选择从外部存储器(如Flash)中加载启动程序,或从内部存储器(如内置Bootloader)中加载启动程序。
启动程序一般是一个二进制文件,其中包含了一系列的初始化指令和应用程序的入口点。
软件启动过程1.初始化函数:启动程序首先执行初始化函数,用于初始化C库、变量和硬件资源等。
例如,初始化堆栈指针、启动C库和启用FPU等。
2.系统时钟初始化:启动程序需要初始化系统时钟,以使系统能够正常工作。
这包括设置主时钟源、配置主时钟分频系数和外设时钟分频系数等。
3.初始化其他硬件资源:启动程序会初始化其他的硬件资源,例如外设、存储器、中断控制器等。
4.跳转到主函数入口点:启动程序最后一步是跳转到主函数的入口点,开始执行用户代码。
总结STM32的启动过程可以分为硬件启动过程和软件启动过程。
硬件启动过程包括上电复位、时钟初始化、外设初始化、中断向量表配置和系统堆栈初始化等操作。
STM32 三种启动模式对应的存储介质是芯片内置的,它们分别是:1.用户闪存 =芯片内置的Flash2.SRAM=芯片内置的RAM区,就是内存了。
3.系统存储器=芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段bootloader,就是同时的ISP升级程序,这个区域的内容在芯片出现后没有人能够修改或拆除,即它是一个ROM。
在每个STM32 的芯片上都有两个管脚BOOT0和BOOT1,这两个管脚在芯片复位时电平状态决定了芯片复位后从哪个区域开始执行程序:BOOT1=X ,BOOT0=0 :从用户闪存(flash)启动,这是正常模式,较多情况下使用这种模式。
BOOT1=1, BOOT0=1 :从内置SRAM(内存)启动,这种模式可以用于调试。
BOOT1=0 ,BOOT0=1 :从系统存储器启动,这种可以用于调试。
使用注意:(1)一般情况下如果我们想用用串口下载代码,则必须配置BOOT0为 1, BOOT1为 0,而如果想让 STM32 一按复位键就开始跑代码,则需要配置 BOOT0为0,BOOT1随便设。
(2)一般不使用内置SRAM启动(BOOT1=1 BOOT0=1),因为SRAM 掉电后数据就丢失。
多数情况下SRAM只是在调试时使用,也可以做其他一些用途。
如做故障的局部诊断,写一段小程序加载到SRAM中诊断板上的其他电路,或用此方法读写板上的Flash或EEPROM等。
还可以通过这种方法解除内部Flash的读写保护,当然解除读写保护的同时Flash的内容也被自动清除,以防止恶意的软件拷贝。
STM32引脚状态决定了用哪种方式启动。
Main Flash memory (flash启动) :是STM32内置的flash,一般我们使用JTAG或者SWD模式下载时,就是下载到这里面,启动后也直接从这启动程序。
System memory 从系统存储启动:这种模式启动的程序功能是有厂家设,一般很少使用,一般来说STM32在出厂是内置了一段bootloader,也就是我们常说的ISP程序,这是一块ROM,出厂后我发修改,这种启动模式,是为了从串口下载程序,因为厂家提供BootLoader中,可以通过bootloader将程序下载到系统Flash中。
STM32 之启动文件详解在嵌入式应用程序开发过程里,由于使用C 语言编程,基本很少涉及到机器底层寄存器的执行过程,一般都会直接在main 函数里开始写代码,似乎main 成为了理所当然的起点,尽管从C 程序的角度来看程序都是直接从main 函数开始执行。
然而,MCU 上电后,是如何寻找到并执行main 函数这一问题却很自然的被忽略了!事实上微控制器是无法从硬件上去定位main 函数的入口地址,因为使用C 语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,因此main 函数的入口地址在编译后便不一定是一个绝对地址。
MCU 上电后又是如何寻找到这个入口地址呢?以前接触无论是PIC、AVR、MSP430 或是51 过程中都没涉及到启动文件的配置,仅仅只有熔丝位或配置字是需要根据实际使用配置来设置,其实并非没有,而是由于大部分的开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main 函数开始进行应用程序的设计即可。
然而,但接触到嵌入内核比如Linux 系统移植过程bootloader 却是很重要也是必不可少的一个环节。
事实上,每一种微控制器,无论性能高下,结构简繁,价格贵贱都是必须有启动文件才能正常工作的,它的作用同bootloader 类似。
启动文件完成了微控制器从复位到开始执行main 函数中间这段时间的必要启动配置。
在STM32 中,如果是在MDK 下创建一个工程,一般都有提示是否加入Star up Code 文件,这个就是启动文件,这里有个误区,一般对于初学者来看,很容易误以为STM32F10x.s 这个启动文件是STM32 所有类型芯片的通用启动文件,因此也自然不会去理会它的作用,事实上,这个启动文件只是。
本文通过对STM32的官方固件库STM32F10x_StdPeriph_Lib_V3.5.0里的MDK启动文件分析,简化部分不需要的代码,并从繁杂的固件库里,精炼出一个类似于“hello world”的入门实战小程序——点亮一个LED。
该工程仅仅包含一个启动文件和一个有main函数的C文件。
本文初衷:不用固件库建立自己的工程!实验软件:Keil uVision4实验硬件:神舟IV号开发板芯片型号:STM32F107VCSTM32启动代码分析、简化、实战汇编基础:1.伪指令:EQU语法格式:名称EQU表达式{,类型}EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言的#define。
其中EQU可以用“*”代替。
名称为EQU伪指令定义的字符名称,当表达式为32位的常量时,可以指定表达式的数据类型,可以有一下三种类型:CODE16、CODE32和DA TA2.伪指令:AREA语法格式:AREA段名{,属性1}{,属性2}……AREA命令指示汇编程序汇编一个新的代码段或数据段。
段是独立的、指定的、不可见的代码或数据块,它们由链接程序处理。
段名:可以为段选择任何段名。
但是,以一个数字开始的名称必须包含在竖杠号内,否则会产生一个缺失段名错误。
例如,|1_DataArea|。
有些名称是习惯性的名称。
例如:|.text|用于表示由C编译程序产生的代码段,或用于以某种方式与C库关联的代码段。
属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。
常用的属性如下:——CODE属性:用于定义代码段,默认为READONLY。
——DA TA属性:用于定义数据段,默认为READWRITE。
——READONLY属性:指定本段为只读,代码段默认为READONLY。
——READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。
——ALIGN属性:使用方式为ALIGN表达式。
一文了解STM32启动过程1 概述说明每一款(芯片)的启动文件都值得去研究,因为它可是你的程序跑的最初一段路,不可以不知道。
通过了解启动文件,我们可以体会到处理器的架构、指令集、中断向量安排等内容,是非常值得玩味的。
(STM32)作为一款高端Cortex-M3系列(单片机),有必要了解它的启动文件。
打好基础,为以后优化程序,写出高质量的代码最准备。
本文以一个实际测试代码--START_(TE)ST为例进行阐述。
整体过程STM32整个启动过程是指从上电开始,一直到运行到main 函数之间的这段过程,步骤为(以使用微库为例):①上电后(硬件)设置SP、PC②设置系统(时钟)③软件设置SP④加载.data、.bss,并初始化栈区⑤跳转到C文件的main函数代码启动过程涉及的文件不仅包含startup_stm32f10x_hd.s,还涉及到了MDK自带的连接库文件entry.o、entry2.o、entry5.o、entry7.o 等(从生成的map文件可以看出来)。
2 程序在Flash上的存储结构在真正讲解启动过程之前,先要讲解程序下载到Flash上的结构和程序运行时(执行到main函数)时的S(RAM)数据结构。
程序在用户Flash上的结构如下图所示。
下图是通过阅读hex文件和在MDK下调试综合提炼出来的。
上图中:MSP初始值由编译器生成,是主堆栈的初始值。
初始化数据段是.data未初始化数据段是.bss.data和.bss是在__main里进行初始化的,对于(ARM)Com (pi)ler,__main主要执行以下函数:其中__scatterlo(ad)会对.data和.bss进行初始化。
加载数据段和初始化栈的参数加载数据段和初始化栈的参数分别有4个,这里只讲解加载数据段的参数,至于初始化栈的参数类似。
0x0800033c Flash上的数据段(初始化数据段和未初始化数据段)起始地址0x20000000加载到SRAM上的目的地址0x0000000c数据段的总大小0x080002f4调用函数_scatterload_copy需要说明的是初始化栈的函数-- 0x08000304与加载数据段的函数不一样,为_scatterload_zeroinit,它的目的就是将栈空间清零。
《嵌入式系统设计(基于STM32F429)》第4章课后题参考答案1.尝试分析一下STM32F4系列微控制器从复位到main()启动过程。
答:复位后。
(1)从存储空间0x00000000处去除栈顶指针到MSP。
(2)从存储空间0x00000004出读取复位终端服务程序入口地址到PC。
(3)执行SystemInit函数,初始化系统时钟和外部存储器接口。
(4)执行__main函数,完成堆栈区域初始化。
(5)点转到main()函数,执行应用程序(C代码)2.请写出复位异常向量、SVC异常向量和SysTick向量地址。
答:复位异常向量地址:0x00000004SVC异常向量地址:0x0000002CSysTick向量地址:0x0000003C3.请写出启动文件中定义的SysTick、外部中断0和USART1中断的中断服务函数名。
答:SysTick中断服务函数名:SysTick_Handler外部中断0中断服务函数名:EXTI0_IRQHandlerUSART1中断的中断服务函数名:USART1_IRQHandler4.请编写中断EXTI0_IRQHandler的中断服务程序,使用C程序实现,只需要空函数。
答:void EXTI0_IRQHandler (void){}5.尝试说明在发生EXTI0_IRQHandler中断时,内核响应的过程。
答:(1)处理器在当前堆栈上把程序状态寄存器、程序计数寄存器、链接寄存器、R12、R3~R0八个寄存器自动依次入栈。
(2)读取向量表中的EXTI0服务程序入口地址(EXTI0_IRQHandler)。
(3)根据向量表更新程序计数寄存器的值(EXTI0服务程序入口地址->PC)。
(4)加载新程序计数寄存器处的指令(步骤(2)~步骤(4)与步骤(1)同时进行)。
(开始执行中断服务程序)(5)更新链接寄存器为EXC_RETURN(EXC_RETURN表示退出异常后返回的模式及使用的堆栈)。
STM32的启动1、启动⽂件简介 启动⽂件由汇编编写,是系统上电复位后第⼀个执⾏的程序。
主要做了以下⼯作: (1)初始化堆栈指针 MSP=_initial_sp (2)初始化 PC 指针=Reset_Handler (3)初始化中断向量表 (4)配置系统时钟 (5)调⽤ C 库函数_main 初始化⽤户堆栈,从⽽最终调⽤ main 函数去到 C 的世界2、STM32的启动流程 下⾯这段话引⽤⾃《CM3 权威指南 CnR2》—复位序列, CM4 的复位序列跟 CM3 ⼀样。
在离开复位状态后, CM3 做的第⼀件事就是读取下列两个 32 位整数的值: (1)从地址 0x0000,0000(FLASH 的地址 0x08000000,因为STM32设计的Flash起始地址是在0x0800 0000开始的)处取出 MSP 的初始值。
(2)从地址 0x0000,0004(FLASH 的地址 0x08000004,因为STM32设计的Flash起始地址是在0x0800 0000开始的)处取出 PC 的初始值——这个值是复位向量, LSB 必须是1,然后从这个值所对应的地址处取值。
请注意,这与传统的 ARM 架构不同——其实也和绝⼤多数的其它单⽚机不同。
传统的 ARM 架构总是从 0 地址开始执⾏第⼀条指令。
它们的 0 地址处总是⼀条跳转指令。
在CM3 中,在 0 地址处提供 MSP 的初始值,然后紧跟着就是向量表。
向量表中的数值是 32位的地址,⽽不是跳转指令。
向量表的第⼀个条⽬指向复位后应执⾏的第⼀条指令,就是我们刚刚分析的 Reset_Handler 这个函数。
初始化 MSP 和 PC 的⼀个范例 因为 CM3 使⽤的是向下⽣长的满栈,所以 MSP 的初始值必须是堆栈内存的末地址加1。
举例来说,如果我们的堆栈区域在 0x20007C00-0x20007FFF 之间,那么 MSP 的初始值就必须是 0x20008000。
stm32试题及答案一、单项选择题(每题2分,共20分)1. STM32系列微控制器属于以下哪种类型的微控制器?A. 8位B. 16位C. 32位D. 64位答案:C2. STM32的时钟系统主要由哪两个部分组成?A. HSI和HSEB. HSE和PLLC. LSI和LSED. PLL和HSE答案:B3. STM32的GPIO端口可以配置为以下哪些模式?A. 输入模式B. 输出模式C. 模拟模式D. 所有以上答案:D4. STM32中,下列哪个寄存器用于配置NVIC中断控制器?A. NVIC_ISERB. NVIC_ICERC. NVIC_IPRD. 所有以上答案:D5. STM32的ADC(模数转换器)可以支持的最大采样速率是多少?A. 1MHzB. 2MHzC. 3.5MHzD. 5MHz答案:C二、多项选择题(每题3分,共15分)1. STM32系列微控制器支持以下哪些通信接口?A. USARTB. SPIC. I2CD. CAN答案:ABCD2. 下列哪些功能是STM32的外设模块所提供的?A. 定时器B. 模数转换C. 数模转换D. 通信接口答案:ABCD3. STM32的内存可以包括以下哪些类型?A. 内部SRAMB. 外部SRAMC. 内部FlashD. 外部Flash答案:ABCD三、判断题(每题2分,共10分)1. STM32微控制器的内部Flash存储器可以作为程序存储器使用。
(对)2. STM32的GPIO端口只能配置为数字输入或数字输出模式。
(错)3. STM32的ADC模块可以同时支持多个通道的采样。
(对)4. STM32的时钟系统不能通过软件进行配置。
(错)5. STM32的NVIC中断控制器可以配置中断的优先级。
(对)四、简答题(每题5分,共20分)1. 简述STM32的启动过程。
答案:STM32的启动过程通常从内部Flash存储器的地址0x0开始,执行复位初始化代码,然后跳转到用户程序的入口点。
1/6/afeibfp/archive/2013/01/08/2850408.html <2013年1月>日一二三四五六303112345678910111213141516171819202122232425262728293031123456789昵称:afeibfp 园龄:2年5个月粉丝:0关注:0+加关注搜索找找看 谷歌搜索常用链接我的随笔我的评论我的参与最新评论我的标签更多链接我的标签51单片机(2)多字节除法(2)汇编(2)随笔分类(2)转发(2)随笔档案(16)2013年1月 (14)2011年9月 (2)最新评论1. Re:014:针对mdk 中STM32程序无法使用printf ,产生停留BEAB BKPT 0xAB 处问题的解决(转)不点那个MiclroLIB 就行了--blakeliu阅读排行榜1. 001:无符号双字节除以单字节(51单片机,汇编源码)(418)2. 004:STM32启动文件详解及SystemInit 函数分析(转)(389)3. 014:针对mdk 中STM32程序无法使用printf ,产生停留BE AB BKPT 0xAB 处问题的解决(转)(312)4. 010:请教STM32用JLINK V8 SWD 输出调试信息到ITM V iewer 的问题(转)(208)5. 009:semihost/ITM 机制浅析以及使用JLINK 通过ITM 调试stm32单片机(转)(190)评论排行榜1. 014:针对mdk 中STM32程序无法使用printf ,产生停留BE AB BKPT 0xAB 处问题的解决(转)(1)2. 013:ADS semihosting 与硬件重定向(转)(0)3. 012:Keil 调试技术(转)(0)4. 011:Nuvoton(新唐) Cort ex M0 使用semihost 输入输出办法(转)(0)5. 010:请教STM32用JLINK V8 SWD 输出调试信息到ITM V iewer 的问题(转)(0)推荐排行榜博客园首页新随笔联系管理订阅 随笔- 16 文章- 0 评论- 1afeibfp004:STM32启动文件详解及SystemInit 函数分析(转)1 ;先在R A M 中分配系统使用的栈,R A M 的起始地址为0x 2000_00002 ;然后在R A M 中分配变量使用的堆3 ;然后在C O D E 区(f l a s h )分配中断向量表,f l a s h 的起始地址为0x 0800_0000,该中断向量表就从这个起始地址开始分配4 ;分配完成后,再定义和实现相应的中断函数,5 ;所有的中断函数全部带有[w e a k ]特性,即弱定义,如果编译器发现在别处文件中定义了同名函数,在链接时用别处的地址进行链接。
STM32启动过程STM32是STMicroelectronics公司推出的32位微控制器,广泛应用于工业、通信、汽车等领域。
在使用STM32微控制器前,了解其启动过程是非常重要的。
下面将详细介绍STM32的启动过程,包括复位、时钟初始化、系统初始化等。
首先,当STM32芯片上电时,会执行复位操作。
复位可以分为两种形式:硬件复位和软件复位。
硬件复位是通过将复位引脚(NRST)拉低来实现的,而软件复位是通过向系统控制寄存器(SYSCTRL)写入特定值来实现的。
在复位过程中,所有寄存器会被清零,程序从复位向量开始执行。
在复位后,需要进行时钟初始化。
STM32支持多种时钟源,如内部RC 振荡器、外部晶振等。
时钟源的选择要根据具体应用来确定。
时钟初始化包括使能时钟源、配置时钟分频因子等操作。
时钟源的选择和配置对于芯片的性能和功耗有很大影响,需要根据具体需求进行优化。
时钟初始化完成后,接下来进行系统初始化。
系统初始化包括设置堆栈指针、使能中断、配置外设等操作。
堆栈指针的设置是为了正确管理程序的子程序调用和返回,中断的使能是为了响应外部事件和实时任务,外设的配置是为了实现具体应用的功能。
系统初始化的目的是为了让芯片进入正常工作状态,为后续的应用程序运行做好准备。
在系统初始化完成后,就可以执行应用程序了。
应用程序一般由中断服务程序和主程序组成。
中断服务程序用于响应外部事件的发生,如定时器中断、串口中断等。
主程序是应用程序的主要逻辑,通过循环执行主程序,完成具体的功能。
在应用程序执行过程中,可以通过外设和寄存器操作来实现对外部设备的控制和通信。
总结来说,STM32的启动过程包括复位、时钟初始化和系统初始化。
复位操作清除了所有寄存器的内容,进入初始状态;时钟初始化设置了芯片的时钟源和分频因子;系统初始化配置了堆栈指针、使能中断和外设。
了解STM32的启动过程对于正确使用和配置芯片非常重要,能够确保芯片能够正常工作并满足应用需求。
一.Duanxx的STM32学习:启动模式,BOOT0和BOOT1详解Reference from:/daunxx/article/details/40148945在画STM32的电路图的时候,关于STM32的启动方式纠结了一下,现有的参考设计都是在STM32的启动选择引脚BOOT0和BOOT1上使用了跳帽,用以人工选择STM32的启动方式,但是在实际应用中这种设计就显得冗余,所以这里顺带研究了一下STM32的启动方式。
STM32一共有三种启动模式,在ST官网上下载的RM0008中,我找到了启动相关的配置说明:对应的中文翻译如下:所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK 的第4个上升沿,BOOT引脚的值将被锁存。
用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
∙Main Flash memory是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。
∙System memory从系统存储器启动,这种模式启动的程序功能是由厂家设置的。
一般来说,这种启动方式用的比较少。
系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,这是一块ROM,出厂后无法修改。
一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。
但是这个下载方式需要以下步骤:Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoaderStep2:最后在BootLoader的帮助下,通过串口下载程序到Flash中Step3:程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动可以看到,利用串口下载程序还是比较的麻烦,需要跳帽跳来跳去的,非常的不注重用户体验。
STM32RCC分析与使用由于STM32系列微控制器系统比较复杂,时钟系统也相对于普通MCU更多样化,这加大了我们设计程序和学习的难度。
比如普通的MCU延时程序,我们直接可以使用“for循环”或者“while”来轻易实现;而在Cortex核的STM32系列微控制器上则不行:因为无法判断当时的时钟频率,做不到精确的延时。
如果详细地了解其时钟系统后,我们知道可以使用SYSCLK来实现精确延时。
RCC的学习可以说没有实验,但所有的模块都会用到时钟,我们进行I/O口的初始化,配置函数中第一行代码一般都是对时钟的初始化,足可见其重要性。
一般而言,要是真正理解了STM32中所有的时钟,学习其他外设都是易如反掌了.实验要求以SystemInit()函数为突破口的情况下,深入了解STM32时钟的初始化流程。
实验目的学习STM32系列的时钟设置.硬件分析时钟树在STM32系统中,共有五个时钟源,分别为HSE、HSI、LSE、LSI、PLL。
由图可以看出,HSI和LSI为片内RC振荡器,HSI为8MHz而LSI为32KHz;HSE和LSE为外部时钟源;PLL则需要HSE和HSI来提供时钟。
(1)HSE:高速外部时钟信号可以通过外部直接提供时钟,从OSC_IN输入,或使用外部陶瓷/晶体谐振器。
外部直接提供的时钟可以达到25MHz,用户可以通过设置时钟信号控制寄存器RCC_CR中的HSEBYP和HSEON位来选择该模式。
此时OSC_OUT引脚为高阻状态。
(2)HSI:高速内部时钟信号该时钟通过8MHz的内部RC振荡器产生,并且可被直接用做系统时钟,或者经过2分频后作为PLL的输入。
它比HSE有更快的启动时间,但频率精确度没有外部晶体振荡器高。
而且根据制造工艺的不同,不同芯片之间的RC振荡器频率也是不同。
出厂时,每个设备频率已被校准至1%(25摄氏度)。
出厂校验值被装载到时钟控制寄存器RCC_CR 的HSICAL[7:0]位。
STM32启动过程解析1、通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;2、通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;3、通过boot引脚设置可以将中断向量表定位于内置Bootloader区,本文不对这种情况做论述;而Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。
对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。
有了上述准备后,下面以STM32的2.02固件库提供的启动文件“stm32f10x_vector.s”为模板,对STM32的启动过程做一个简要而全面的解析。
程序清单一:;文件“stm32f10x_vector.s”,其中注释为行号DATA_IN_ExtSRAM EQU 0 ;1Stack_Size EQU 0x00000400 ;2AREA STACK, NOINIT, READWRITE, ALIGN = 3 ;3Stack_Mem SPACE Stack_Size ;4__initial_sp ;5Heap_Size EQU 0x00000400 ;6AREA HEAP, NOINIT, READWRITE, ALIGN = 3 ;7__heap_base ;8Heap_Mem SPACE Heap_Size ;9__heap_limit ;10THUMB ;11PRESERVE8 ;12IMPORT NMIException ;13IMPORT HardFaultException ;14IMPORT MemManageException ;15IMPORT BusFaultException ;16IMPORT UsageFaultException ;17IMPORT SVCHandler ;18IMPORT DebugMonitor ;19IMPORT PendSVC ;20IMPORT SysTickHandler ;21IMPORT WWDG_IRQHandler ;22IMPORT PVD_IRQHandler ;23IMPORT TAMPER_IRQHandler ;24IMPORT RTC_IRQHandler ;25IMPORT FLASH_IRQHandler ;26IMPORT EXTI0_IRQHandler ;28IMPORT EXTI1_IRQHandler ;29IMPORT EXTI2_IRQHandler ;30IMPORT EXTI3_IRQHandler ;31IMPORT EXTI4_IRQHandler ;32IMPORT DMA1_Channel1_IRQHandler ;33 IMPORT DMA1_Channel2_IRQHandler ;34 IMPORT DMA1_Channel3_IRQHandler ;35 IMPORT DMA1_Channel4_IRQHandler ;36 IMPORT DMA1_Channel5_IRQHandler ;37 IMPORT DMA1_Channel6_IRQHandler ;38 IMPORT DMA1_Channel7_IRQHandler ;39 IMPORT ADC1_2_IRQHandler ;40IMPORT USB_HP_CAN_TX_IRQHandler ;41 IMPORT USB_LP_CAN_RX0_IRQHandler ;42 IMPORT CAN_RX1_IRQHandler ;43 IMPORT CAN_SCE_IRQHandler ;44 IMPORT EXTI9_5_IRQHandler ;45IMPORT TIM1_BRK_IRQHandler ;46 IMPORT TIM1_UP_IRQHandler ;47 IMPORT TIM1_TRG_COM_IRQHandler ;48 IMPORT TIM1_CC_IRQHandler ;49 IMPORT TIM2_IRQHandler ;50IMPORT TIM3_IRQHandler ;51IMPORT TIM4_IRQHandler ;52IMPORT I2C1_EV_IRQHandler ;53IMPORT I2C1_ER_IRQHandler ;54IMPORT I2C2_EV_IRQHandler ;55IMPORT I2C2_ER_IRQHandler ;56IMPORT SPI1_IRQHandler ;57IMPORT SPI2_IRQHandler ;58IMPORT USART1_IRQHandler ;59IMPORT USART2_IRQHandler ;60IMPORT USART3_IRQHandler ;61IMPORT EXTI15_10_IRQHandler ;62 IMPORT RTCAlarm_IRQHandler ;63 IMPORT USBWakeUp_IRQHandler ;64 IMPORT TIM8_BRK_IRQHandler ;65 IMPORT TIM8_UP_IRQHandler ;66 IMPORT TIM8_TRG_COM_IRQHandler ;67 IMPORT TIM8_CC_IRQHandler ;68 IMPORT ADC3_IRQHandler ;69IMPORT FSMC_IRQHandler ;70IMPORT TIM5_IRQHandler ;72IMPORT SPI3_IRQHandler ;73IMPORT UART4_IRQHandler ;74IMPORT UART5_IRQHandler ;75IMPORT TIM6_IRQHandler ;76IMPORT TIM7_IRQHandler ;77IMPORT DMA2_Channel1_IRQHandler ;78 IMPORT DMA2_Channel2_IRQHandler ;79 IMPORT DMA2_Channel3_IRQHandler ;80 IMPORT DMA2_Channel4_5_IRQHandler ;81 AREA RESET, DATA, READONLY ;82 EXPORT __Vectors ;83__Vectors ;84DCD __initial_sp ;85DCD Reset_Handler ;86DCD NMIException ;87DCD HardFaultException ;88DCD MemManageException ;89DCD BusFaultException ;90DCD UsageFaultException ;91DCD 0 ;92DCD 0 ;93DCD 0 ;94DCD 0 ;95DCD SVCHandler ;96DCD DebugMonitor ;97DCD 0 ;98DCD PendSVC ;99DCD SysTickHandler ;100DCD WWDG_IRQHandler ;101DCD PVD_IRQHandler ;102DCD TAMPER_IRQHandler ;103DCD RTC_IRQHandler ;104DCD FLASH_IRQHandler ;105DCD RCC_IRQHandler ;106DCD EXTI0_IRQHandler ;107DCD EXTI1_IRQHandler ;108DCD EXTI2_IRQHandler ;109DCD EXTI3_IRQHandler ;110DCD EXTI4_IRQHandler ;111DCD DMA1_Channel1_IRQHandler ;112 DCD DMA1_Channel2_IRQHandler ;113 DCD DMA1_Channel3_IRQHandler ;114DCD DMA1_Channel5_IRQHandler ;116 DCD DMA1_Channel6_IRQHandler ;117 DCD DMA1_Channel7_IRQHandler ;118 DCD ADC1_2_IRQHandler ;119DCD USB_HP_CAN_TX_IRQHandler ;120 DCD USB_LP_CAN_RX0_IRQHandler ;121 DCD CAN_RX1_IRQHandler ;122DCD CAN_SCE_IRQHandler ;123DCD EXTI9_5_IRQHandler ;124DCD TIM1_BRK_IRQHandler ;125DCD TIM1_UP_IRQHandler ;126DCD TIM1_TRG_COM_IRQHandler ;127 DCD TIM1_CC_IRQHandler ;128DCD TIM2_IRQHandler ;129DCD TIM3_IRQHandler ;130DCD TIM4_IRQHandler ;131DCD I2C1_EV_IRQHandler ;132DCD I2C1_ER_IRQHandler ;133DCD I2C2_EV_IRQHandler ;134DCD I2C2_ER_IRQHandler ;135DCD SPI1_IRQHandler ;136DCD SPI2_IRQHandler ;137DCD USART1_IRQHandler ;138DCD USART2_IRQHandler ;139DCD USART3_IRQHandler ;140DCD EXTI15_10_IRQHandler ;141DCD RTCAlarm_IRQHandler ;142DCD USBWakeUp_IRQHandler ;143DCD TIM8_BRK_IRQHandler ;144DCD TIM8_UP_IRQHandler ;145DCD TIM8_TRG_COM_IRQHandler ;146 DCD TIM8_CC_IRQHandler ;147DCD ADC3_IRQHandler ;148DCD FSMC_IRQHandler ;149DCD SDIO_IRQHandler ;150DCD TIM5_IRQHandler ;151DCD SPI3_IRQHandler ;152DCD UART4_IRQHandler ;153DCD UART5_IRQHandler ;154DCD TIM6_IRQHandler ;155DCD TIM7_IRQHandler ;156DCD DMA2_Channel1_IRQHandler ;157 DCD DMA2_Channel2_IRQHandler ;158DCD DMA2_Channel4_5_IRQHandler ;160 AREA |.text|, CODE, READONLY ;161 Reset_Handler PROC ;162EXPORT Reset_Handler ;163IF DATA_IN_ExtSRAM == 1 ;164LDR R0,= 0x00000114 ;165LDR R1,= 0x40021014 ;166STR R0,[R1] ;167LDR R0,= 0x000001E0 ;168LDR R1,= 0x40021018 ;169STR R0,[R1] ;170LDR R0,= 0x44BB44BB ;171LDR R1,= 0x40011400 ;172STR R0,[R1] ;173LDR R0,= 0xBBBBBBBB ;174LDR R1,= 0x40011404 ;175STR R0,[R1] ;176LDR R0,= 0xB44444BB ;177LDR R1,= 0x40011800 ;178STR R0,[R1] ;179LDR R0,= 0xBBBBBBBB ;180LDR R1,= 0x40011804 ;181STR R0,[R1] ;182LDR R0,= 0x44BBBBBB ;183LDR R1,= 0x40011C00 ;184STR R0,[R1] ;185LDR R0,= 0xBBBB4444 ;186LDR R1,= 0x40011C04 ;187STR R0,[R1] ;188LDR R0,= 0x44BBBBBB ;189LDR R1,= 0x40012000 ;190STR R0,[R1] ;191LDR R0,= 0x44444B44 ;192LDR R1,= 0x40012004 ;193STR R0,[R1] ;194LDR R0,= 0x00001011 ;195LDR R1,= 0xA0000010 ;196STR R0,[R1] ;197LDR R0,= 0x00000200 ;198LDR R1,= 0xA0000014 ;199STR R0,[R1] ;200ENDIF ;201IMPORT __main ;202LDR R0, =__main ;203BX R0 ;204ENDP ;205ALIGN ;206IF :DEF:__MICROLIB ;207EXPORT __initial_sp ;208EXPORT __heap_base ;209EXPORT __heap_limit ;210ELSE ;211IMPORT __use_two_region_memory ;212EXPORT __user_initial_stackheap ;213__user_initial_stackheap ;214LDR R0, = Heap_Mem ;215LDR R1, = (Stack_Mem + Stack_Size) ;216LDR R2, = (Heap_Mem + Heap_Size) ;217LDR R3, = Stack_Mem ;218BX LR ;219ALIGN ;220ENDIF ;221END ;222ENDIF ;223END ;224-----------------------------------------------------------------------------------------------------------------------------------------------------------------如程序清单一,STM32的启动代码一共224行,使用了汇编语言编写,这其中的主要原因下文将会给出交代。
STM32启动
ARM7和ARM9启动时从绝对地址0X00000000开始执行复位中断程序,即固定了复位后的起始地址,但中断向量表的位置是可变的。
而STM32则不同,M3内核规定起始地址必须存放栈顶地址,第二个地址必须是复位中断向量的入口地址,这样CPU复位后会自动从下一个32位地址取出复位中断向量的入口地址,PC就跳转到中断服务程序,所以M3是固定了中断向量表的位置而地址是可变的。
M3的中断向量表有三个位置,通过BOOT引脚进行启动设置。
BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。
中断向量表定位于FLASH区,复位后PC=0x80000000.
OOT1=0 BOOT0=1 从系统存储器启动(相当于厂家在存储器中固化了BOOTLOADER),这种模式启动的程序功能由厂家设置。
BOOT1=1 BOOT0=1 从内置SRAM启动,这种模式可以用于调试。
这种模式下,中断向量表位于SRAM区,起始地址为0x20000000.复位为PC=0x20000000.
startup_stm32f10x_XX.s
这个文件里面首先定义了复位中断(复位入口矢量被硬件固定在地址
0x0000_0004)的处理函数:Reset_Handler,它的作用就是将保存于flash中的初始化数据复制到sram中,调用上面说到的SystemInit来初始化时钟,接着跳转到main执行。
接着定义了Default_Handler,这个是作为其他所有中断的默认处理函数,作用就是死循环,所以你假如开启了某个中断,请按照这里面的中断函数名给它写中断处理函数,例如串口中断处理函数名是USART1_IRQHandler,你开了串口中断,如果不重写USART1_IRQHandler,就默认执行Default_Handler,死循环了。
而如果你有重写,那么中断向量表中的处理函数的地址就会更新为你自己写的那个函数的地址了。
为什么会这样呢?因为此文件的末尾用了类似这样的语句:.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
它给中断处理函数提供了弱(weak)别名(Default_Handler),如果不重写,中断了默认执行Default_Handler,如果重写了,因为是弱别名,所以会被你写的同名函数覆盖。
在中断向量表中第一个存放的是复位中断向量,STM32MDK环境中
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
首先用跳转指令是程序跳转到SystemInit,在"startup_stm32f10x_xx.s"文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有flash的设定),这个函数会在系统复位之后首先被执行。
文件中默认的一些设置:允许HSE(外部时钟),FLASH(允许预取缓冲区,设置2个等待周期),PLL系数为9,开启PLL并选择PLL输出作为时钟源(SYSCLK),后续设置SYSCLK = HCLK = APB2 = 72MHz,APB1 = HCLK/2 = 36MHz,HCLK即AHB的时钟。