寄存器映射及地址计算(STM32F407)

上篇文章介绍了存储器映射(存储器映射(STM32F407)-CSDN博客),本文介绍寄存器映射的基本概念。

1、寄存器映射简介

寄存器是一类特殊的存储器,它的每个位都有特定的功能,可以实现对外设/功能的控制,给寄存器的地址命名的过程就叫寄存器映射。

举个简单的例子,大家家里面的纸张就好比通用存储器,用来记录数据是没问题的,但是不会有具体的动作,只能做记录,而你家里面的电灯开关,就好比寄存器。假设你家有8个灯, 就有8个开关(相当于一个8位寄存器),这些开关可以记录状态,同时还能让电灯点亮/关闭, 是会产生具体动作的。为了方便区分和使用,我们会给每个开关命名,比如厨房开关、大厅开关、卧室开关等,这个命名过程,就是映射。我们给STM32的寄存器命名,就是寄存器映射。

2、寄存器描述解读

寄存器描述是指对计算机中寄存器的功能、特性、使用方式等进行详细说明的文档或信息。寄存器描述可以在对应单片机的参考手册中查找。

以GPIO的ODR寄存器为例,其参考手册的描述如下图所示:

寄存器名字

每个寄存器都有一个对应的名字,以简单表达其作用,并方便记忆,这里GPIOx_ODR表示寄存器英文名。例如,若x可以从A~E,说明有5个这样的寄存器,上图中,x=A~I,说明有9个这样的寄存器。

寄存器偏移量及复位值

地址偏移量表示该寄存器的地址相对其外设基地址的偏移,比如GPIOB,由存储器映射图可知其外设基地址是:0x4002 0400。那么GPIOB_ODR寄存器的地址就是:0x4002 0414。知道了外设基地址和地址偏移量,我们就可以知道任何一个寄存器的实际地址。

复位值表示该寄存器在系统复位后的默认值,可以用于分析外设的默认状态。

寄存器位表

描述寄存器每一个位的作用(共32bit),这里表示ODR寄存器的第15位(bit),位名字为 ODR15,rw表示该寄存器可读写(r,可读取;w,可写入)。

位功能描述

描述寄存器每个位的功能,这里表示位0~15,对应ODR0~ODR15,每个位控制一个IO口的 输出状态。

其他寄存器描述,参照以上方法解读。

3、寄存器映射举例

从前文叙述,我们知道 GPIOB_ODR 寄存器的地址为:0x4002 0414,假设我们要控制 GPIOB 的 16 个 IO 口都输出 1,则可以写成:

*(unsigned int *)(0x40020414) = 0XFFFF;

这里我们先要将 0x4002 0414 强制转换成 unsigned int 类型指针,然后用 “ * ” 对这个指针的值进行设置,从而完成对 GPIOB_ODR 寄存器的写入。

这样写代码功能是没问题,但是可读性和可维护性都很差,使用起来极其不便,因此我们 将代码改为:

#define  GPIOB_ODR      *(unsigned int *)    (0x40020414)

GPIOB_ODR = 0XFFFF;

这样,我们就定义了一个 GPIOB_ODR 的宏,来替代数值操作,很明显,GPIOB_ODR 的可读性和可维护性,比直接使用数值操作来的直观和方便。这个宏定义过程就可以称之为寄存器的映射。

实际上大量寄存器的映射,使用结构体是最方便的方式,stm32f407xx.h 里面使用结构体方式对 STM32F407 的寄存器做了详细映射。

4、寄存器地址计算

STM32F407大部分外设寄存器地址都是在存储块2上面的,见存储器映射图(存储器映射(STM32F407)-CSDN博客)。具体某个寄存器地址,由三个参数决定:

1、总线基地址(BUS_BASE_ADDR);

2,外设基于总线基地址的偏移量(PERIPH_OFFSET);

3,寄存器相对外设基地址的偏移量(REG_OFFSET)。

可以表示为:

寄存器地址 = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET

①总线基地址(BUS_BASE_ADDR),顾名思义,就是STM32F407内部的总线地址,如下图所示:

上表中APB1的基地址,就是外设基地址,也就是总线基地址(BUS_BASE_ADDR),表中的偏移量就是相对于外设基地址的偏移量,也就是相对于APB1的基地址的偏移量。(根据上图所示,也很好理解,例如AHB1的基地址是0x4002 0000,而外设基地址是0x4000 0000,二者差了0x2 0000,因此,AHB1的偏移量就是0x2 0000)

②外设基于总线基地址的偏移量(PERIPH_OFFSET),顾名思义,就是挂载在该总线上的外设基于该总线基地址的偏移量。以GPIO为例,如下图所示,

GPIOB的基地址为0x4002 0400,它挂载在AHB1总线上,而AHB1总线的地址为0x4002 0000,因此,不难看出,GPIOB基于AHB1的地址的偏移量为0x400。也就是说,对于GPIOB这个外设,它的 PERIPH_OFFSET = x400。

若外设挂载在AHB1总线上,则它的 PERIPH_OFFSET 是基于AHB1总线地址(0x4002 0000)的偏移量。但是,如果外设挂载在其他总线上,如AHB2总线,则它的 PERIPH_OFFSET 是基于AHB2总线地址(0x5000 0000)的偏移量。

③寄存器相对外设基地址的偏移量(REG_OFFSET),顾名思义,指的是某个外设的寄存器相对于外设基地址的偏移量。以GPIOB的相关寄存器为例,如下图所示,

上图中的偏移量,就是GPIOB的寄存器相对外设基地址的偏移量(REG_OFFSET)。

因此,根据前面的公式,很容易可以计算出GPIOB_ODR的地址:

GPIOB_ODR地址 = AHB1总线基地址 + GPIOB外设偏移量 + 寄存器偏移量

待入可得:

GPIOB_ODR地址 = 0x4002 0000 + 0x400 + 0x14 = 0x4002 0414

因此,在参考手册里找到具体某个寄存器相对外设基地址的偏移量就可以知道该寄存器的实际地址了。

STM32F407所有寄存器映射都在stm32f407xx.h里面完成,包括各种基地址定义、结构体定义、外设寄存器映射、寄存器位定义(占了绝大部分)等。

5、总结

寄存器是一类特殊的存储器,它的每个位都有特定的功能,可以实现对外设/功能的控制,给寄存器的地址命名的过程就叫寄存器映射。

寄存器描述是指对计算机中寄存器的功能、特性、使用方式等进行详细说明的文档或信息。寄存器描述可以在对应单片机的参考手册中查找。

寄存器地址 = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET,通过该公式和参考手册,我们可以计算出寄存器的实际地址,主要用于直接对寄存器进行的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值