联系方式

    深圳市英瑞尔芯科技有限公司

    电话:

    186 6591 0262

    E-mail:

    sally@szinter.com.cn

    地址:

    深圳市福田区振华路现代之窗A座7B

STM32F0单片机快速入门三: MCU启动过程

发布时间:2022-08-20 03:07:00

来源:http://www.szinter.com.cn/news856207.html

1.MCU 如何启动代码?

首先,我们必须回应一个问题。 Startup Code,什么是 Bootloader?因为我们总是看到学生混合使用这两个定义。

Bootloader 可以翻译成正确的引导程序流程。初始单片机没有 Bootloader 这种定义。如大伙儿所知 MCS51,开始集成ic内部不能存储代码,必须插件软件EPROM,是下面这种带小窗户的存储器。 EPROM 中间的代码必须用紫外线照射几分钟。

之后发生了 Flash 这种可电可读存储器集成在单片机内。但是单片机的程序流程存储区在出厂时仍然是空白的,没有代码。客户编译程序后,可以在线下载到单片机。货物发送给客户后,如果看到了,Bug怎么办呢?用开发板再次在线下载新代码。这着实是有点不便,尤其是假如顾客间距很远得话。因此,一些聪明的程序员想出了一种方法,在程序过程中写一小段独特的代码。这个代码可以按照一定的方法打开,比如用功能键进入操作,可以根据串口通信(早期 PC 串口通信是标准配置)接受新代码并输入Flash,代码升级也可以在没有硬件配置开发板的情况下进行。

程序员也是当代历史时代前进的关键驱动力!

之后,有集成ic制造商在生产过程中将此类代码集成ic代码在线下载和程序流程升级非常方便。STM32F030内部干固Bootloader。我们把一个管脚 BOOT0 同时,再次集成ic通电或复位将打开Boootloader进到运作。此时,您可以根据单片机的串口通信将新程序流程发送给单片机,推送后再发送 BOOT0 再复位单片机,新程序流程就会运行起来。

Startup Code 它可以翻译成操作代码。单片机通电或复位后的初始代码。一般来说,关键是设置堆栈指针,获得和输入复位空间向量,然后复位自变量,最后自动跳转到客户代码。在详细查看操作代码之前,请先查看 STM32F030 内存映射。

2.STM32F030内存映射(Memory Map)

下边是 STM32F030 内存映射,其他集成ic会由于 Flash,SRAM 室内空间尺寸不同,略有不同。

因为是32位机,从 0x0000_0000 到 0xFFFF_FFFF 的一共 4G 室内空间。

这也是选择32位机器的好处。详细地址足够室内空间。与8或16位机器不同,详细地址的室内空间很容易不足,必须始终使用 Page 间接寻址。

从低详细地址到高地址,逐段查看:

0x0000 0000 Virtual memory

这个详细地址的室内空间会因为不同而有所不同 BOOT 方式而投射到不一样的物理内存。

当集成ic复位,或从 Standby 低功耗法唤起:

假如管脚 BOOT0 它被降低并投射到 Flash memory。这也是最常见的代码运行模式;

假如管脚 BOOT0 它被拉起,而且nBOOT1为 1 ,将投射到 System memory。进入bootloader方式;

假如管脚 BOOT0 它被拉起,而且nBOOT1为 0 ,将投射到 SRAM。

注:nBOOT1 为Flash客户为什么要设置一个存储器?

0x0800 0000 Flash memory

存储客户代码

0x1FFF EC00 System memory

储放 bootloader, 电影中集成温度传感器的校准数据信息和电影中集成工作电压的校准数据信息

该代码和数字在加工厂干固。

0x2000 0000 SRAM

储存客户自变量,堆放(Heap)和栈(Stack)。您还可以输入代码 SRAM 运作。

0x4000 0000 Pheriperals

集成ic集成的外部设备,如 USART, SPI, GPIO等待寄存器地址在这里。

0xE000 0000 Cortex-M0 internal pheriperals

M0核心外部设备投射到该地区。 systick (System Tick),NVIC,Debug Registers。该存储器集成ic指南找不到,必须到达 ARM 搜索指南。

3.运行代码(Startup Code)

下面这个很简单。GPIO以旋转代码为例:

STM32Cube_FW_F0_V1.11.0ProjectsSTM32F030R8-Nucleo

ExamplesGPIOGPIO_IOToggleMDK-ARMProject.uvprojx

将本项目在线下载到单片机后,用程序调试观察以下两个详细地址:

大家会发觉0x0000_逐渐地区, 和0x0800_逐渐地区,内容完全一致。这表明, Flash 区内容投射 0x0000_0000起止的详细地址区。

留意STM32F030应用于小端模式(Litlle Edian)。

有别于 MCS51 在 0x0000 复位空间向量放置,STM32F030 也有其他 ARM 集成ic原堆栈指针的详细地址存储在零详细地址中。

0x0000 0000: (0x2000 0428) 原堆栈指针

0x0000 0004: (0x0800 00C9) 复位空间向量,通电或复位后开始加载PC

注:单片机通电或复位后,堆栈指针复位 PC 默认值的载入从详细地址开始 0x0000_0000,0x0000_0004获得。在上面这类客户方式下,具体是以 Flash 区的 0x0800_0000,0x0800_0004 获得的。

我们可以根据程序进行调试和观察ic复位后 M0 核心存储器:

这时,细心的学生很可能会发现一个问题。

堆栈指针 SP 前面存储器中的具体内容和内容是正确的。 PC 内容好像不一样?PC 里的值是 0x0800_00C我也在储存器里 0x0800_00C9 啊!

这里涉及 ARM 管理系统中的两种运行状态 ARM 和 Thumb。ARM 实行32位命令,Thumb实行16位命令。那么如何在彼此之间转换呢?一种方法是自动跳转详细地址的最小位置(Bit0), 当 Bit0 设为 1 时进到 Thumb 情况,当 Bit0 设为 0 时进到 ARM 情况。

对于单片机来说,16位 Thumb 有足够的命令,16个命令比32个命令可以节省内部空间。 M0 核心只适用 Thumb 命令。

在这里,你可以理解为什么复位空间的向量 0x0800_00C9 了。

看来复位空间的向量 0x0800_00C8 偏见的第一条命令:

单片机即将实施的第一项命令 0x4804,是什么意思?

先说结果:这是单片机复位后鼠标光标偏向的命令:

LDR R0, =SystemInit

这里详细解释一下 0x4804 这条命令:

它匹配的序列号是 0 ** 0000000100

Bit15 to Bit11 (01001)为LDR(literal)命令,既从PC将数据信息发送到存储器Rt。

Bit10 to Bit8 (000)表示当地存储器Rt为 R0

Bit7 to Bit0 表示相对性 PC 的偏移为 0b10000,既0x10。

留意PC值是今天的详细地址 4。

那麽从 0x080000C8 0x4 0x10 = 0x080000DC 取下数据信息 0x0800092D 送至存储器 R0.这个详细地址是 SystemInit( )函数公式的详细地址。下一句话 BLX R0 读取系统软件复位函数公式。

SystemInit( ) 这一变量在 system_stm32f0xx.c 这一文档里,关键进行系统软件钟表的复位。可以点进来看一下实际的内容。

函数公式 SystemInit( ) 实施后,程序流程会自动跳回家,得到 __ ** in( ) 自动跳转到函数公式的详细地址 __ ** in() 函数公式公式。必须注意的是,这个函数公式不是每个客户代码中的 ** in( ) 函数公式。

__ ** in() 函数是 Keil 库给的,大家看不到代码,重点是自变量复位。这里不用太担心。如果你想进一步研究,你可以看看 ARM Compiler User Guide 的 Reset and initialization 这一节。

__ ** in() 函数公式实施后,工作基本完成,自动跳转到客户代码 ** in( ) 函数公式。

参考文献:

STM32F030 Datasheet

STM32F030 Reference Manual

ARM Compiler User Guide

ARM?v6-M Architecture Reference Manual

微信公众平台热烈欢迎大家了解:TopSemic

相关标签: