×
单片机 > 单片机程序设计 > 详情

再造STM32---第三部分:什么是寄存器?

发布时间:2020-06-10 发布时间:
|

      本系列是基于STM32F429野火库进行学习。


3.1什么是寄存器?

      我们经常说寄存器,那么什么是寄存器?这是我们本章需要讲解的内容,在学习的过程中,大家带着这个疑问好好思考下,到最后看看大家能否用一句话给寄存器下一个定义。


3.2 STM32 长啥样?

      我们开发板中使用的芯片是 176pin 的 STM32F429IGT6,具体见图 3-1。这个就是我们接下来要学习的 STM32,它讲带领我们进入嵌入式的殿堂。芯片正面是丝印, ARM 应该是表示该芯片使用的是 ARM 的内核, STM32F429IGT6是芯片型号,后面的字应该是跟生产批次相关,最下面的是 ST 的 LOGO。芯片四周是引脚,左下角的小圆点表示 1 脚,然后从 1 脚起按照逆时针的顺序排列(所有芯片的引脚顺序都是逆时针排列的)。开发板中把芯片的引脚引出来,连接到各种传感器上,然后在 STM32 上编程(实际就是通过程序控制这些引脚输出高电平或者低电平)来控制各种传感器工作,通过做实验的方式来学习 STM32 芯片的各个资源。开发板是一种评估板,板载资源非常丰富,引脚复用比较多,力求在一个板子上验证芯片的全部功能。

图 3-1 STM32F429IGT6 实物图

图 3-2 STM32F429IGT6 正面引脚图


3.3 芯片里面有什么?

      我们看到的 STM32 芯片已经是已经封装好的成品,主要由内核和片上外设组成。若与电脑类比,内核与外设就如同电脑上的 CPU 与主板、内存、显卡、硬盘的关系。

      STM32F429 采用的是 Cortex-M4 内核,内核即 CPU,由 ARM 公司设计。 ARM 公司并不生产芯片,而是出售其芯片技术授权。芯片生产厂商(SOC)如 ST、 TI、 Freescale,负责在内核之外设计部件并生产整个芯片,这些内核之外的部件被称为核外外设或片上外设。如 GPIO、 USART(串口)、 I2C、 SPI 等都叫做片上外设。具体见图 3-3。

图 5-3 STM32 芯片架构简图

      芯片和外设之间通过各种总线连接,其中主控总线有 8 条,被控总线有 7 条,具体见图 3-4。主控总线通过一个总线矩阵来连接被控总线, 总线矩阵用于主控总线之间的访问仲裁管理,仲裁采用循环调度算法。总线之间交叉的时候如果有个圆圈则表示可以通信,没有圆圈则表示不可以通信。比如 S0: I 总线只有跟 M0、 M2 和 M6 这三根被控总线交叉的时候才有圆圈,就表示 S0 只能跟这三根被控总线通信。从功能上来理解, I 总线是指令总线,用来取指,指令指的是编译好的程序指令。我们知道 STM32 有三种启动方式, 从 FLASH 启动(包含系统存储器),从内部 SRAM 启动,从外部 RAM 启动, 这三种存储器刚好对应的就是 M0、 M2 和M6 这三条总线。

图 3-4 STM32F42xxx 和 STM32F43xxx 器件的总线接口


3.4 存储器映射

在图 3-4 中, 连接被控总线的是 FLASH, RAM 和片上外设,这些功能部件共同排列在一个 4GB 的地址空间内。我们在编程的时候,操作的也正是这些功能部件。


3.4.1 存储器映射

存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射,具体见图 3-5。 如果给存储器再分配一个地址就叫存储器重映射。

图 3-5 存储器映射

1. 存储器区域功能划分

      在这 4GB 的地址空间中, ARM 已经粗线条的平均分成了 8 个块,每块 512MB,每个块也都规定了用途,具体分类见表格 3-1。每个块的大小都有 512MB,显然这是非常大的,芯片厂商在每个块的范围内设计各具特色的外设时并不一定都用得完,都是只用了其中的一部分而已。

表格 3-1 存储器功能分类

      在这 8 个 Block 里面,有 3 个块非常重要,也是我们最关心的三个块。 Boock0 用来设计成内部 FLASH, Block1 用来设计成内部 RAM, Block2 用来设计成片上的外设,下面我们简单的介绍下这三个 Block 里面的具体区域的功能划分。

存储器 Block0 内部区域功能划分:

      Block0 主要用于设计片内的 FLASH, F429 系列片内部 FLASH 最大是 2MB,我们使用的 STM32F429IGT6 的 FLASH 是 1MB。要在芯片内部集成更大的 FLASH 或者 SRAM都意味着芯片成本的增加,往往片内集成的 FLASH 都不会太大, ST 能在追求性价比的同时做到 1MB 以上,实乃良心之举。 Block 内部区域的功能划分具体见表格 3-2。

表格 3-2 存储器 Block0 内部区域功能划分



储存器 Block1 内部区域功能划分:

      Block1 用于设计片内的 SRAM。 F429 内部 SRAM 的大小为 256KB,其中 64KB 的CCM RAM 位于 Block0,剩下的 192KB 位于 Block1,分 SRAM1 112KB, SRAM2 16KB,SRAM3 64KB, Block 内部区域的功能划分具体见表格 3-3。

表格 3-3 存储器 Block1 内部区域功能划分

储存器 Block2 内部区域功能划分:

      Block2 用于设计片内的外设,根据外设的总线速度不同, Block 被分成了 APB 和 AHB两部分,其中 APB 又被分为 APB1 和 APB2, AHB 分为 AHB1 和 AHB2,具体见表格 3-4。还有一个 AHB3 包含了 Block3/4/5/6,这四个 Block 用于扩展外部存储器,如 SDRAM,NORFLASH 和 NANDFLASH 等。

表格 3-4 存储器 Block2 内部区域功能划分

下面内容非常重要,务必注意!

3.5 寄存器映射:

      我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射,那什么叫寄存器映射?寄存器到底是什么?在存储器 Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。


      比如,我们找到 GPIOH 端口的输出数据寄存器 ODR 的地址是 0x40021C14(至于这个地址如何找到可以先跳过,后面我们会有详细的讲解), ODR 寄存器是 32bit,低16bit有效,对应着 16 个外部 IO,写 0/1 对应的的 IO 则输出低/高电平。现在我们通过 C 语言指针的操作方式,让 GPIOH的 16 个 IO 都输出高电平,具体见代码 3-1。

代码 3-1 通过绝对地址访问内存单元

      0x4002 1C14 在我们看来是 GPIOH 端口 ODR 的地址,但是在编译器看来,这只是一个普通的变量,是一个立即数,要想让编译器也认为是指针,我们得进行强制类型转换,把它转换成指针,即(unsigned int * )0x4002 1C14,然后再对这个指针进行 * 操作。unsigned int是32位的。

      刚刚我们说了,通过绝对地址访问内存单元不好记忆且容易出错,我们可以通过寄存器的方式来操作,具体见代码 3-2。

代码 3-2 通过寄存器别名方式访问内存单元

      为了方便操作,我们干脆把指针操作“*”也定义到寄存器别名里面,具体见代码 3-3。

代码 3-3 通过寄存器别名访问内存单元


3.5.1 STM32 的外设地址映射:

      片上外设区分为四条总线,根据外设速度的不同,不同总线挂载着不同的外设, APB挂载低速外设, AHB 挂载高速外设。相应总线的最低地址我们称为该总线的基地址,总线基地址也是挂载在该总线上的首个外设的地址。其中 APB1 总线的地址最低,片上外设从这里开始,也叫外设基地址。

1. 总线基地址

表格 3-5 总线基地址:

      表格 5-5 的“相对外设基地址偏移”即该总线地址与“片上外设”基地址 0x4000 0000的差值。关于地址的偏移我们后面还会讲到。

2. 外设基地址

      总线上挂载着各种外设,这些外设也有自己的地址范围,特定外设的首个地址称为“XX 外设基地址”,也叫 XX 外设的边界地址。具体有关 STM32F4xx 外设的边界地址请参考《STM32F4xx 参考手册》的 2.3 小节的存储器映射的表 2: STM32F4xx 寄存器边界地址。或者参考《STM32F4xx 参考手册》的存储器映射章节,这两个手册都有详细的讲解。

      这里面我们以 GPIO 这个外设来讲解外设的基地址,具体见表格 3-6。

表格 3-6 外设 GPIO 基地址

      从表格 3-6 看到, GPIOA 的基址相对于 AHB1 总线的地址偏移为 0,我们应该就可以猜到, AHB1 总线的第一个外设就是 GPIOA。

3. 外设寄存器

在 XX 外设的地址范围内,分布着的就是该外设的寄存器。以 GPIO 外设为例, GPIO是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,基本功能是控制引脚输出高电平或者低电平。最简单的应用就是把 GPIO 的引脚连接到 LED 灯的阴极, LED 灯的阳极接电源,然后通过 STM32 控制该引脚的电平,从而实现控制 LED 灯的亮灭。GPIO 有很多个寄存器,每一个都有特定的功能。每个寄存器为 32bit,占四个字节,在该外设的基地址上按照顺序排列,寄存器的位置都以相对该


关键字:STM32  寄存器

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何升级STM32单片机的代码