什么是寄存器以及什么是寄存器映射
在存储器 Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共 32bit, 每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到 每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通 过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的 不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个 给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
地址
下图为总线基地址
?“相对外设基地址偏移”即该总线地址与“片上外设”基地址 0x4000 0000 的差值。
下图为外设GPIO基地址
?下图为GPIOB端口的寄存器地址列表
“相对外设基地址偏移”即该总线地址与“片上外设”基地址 0x4000 0000 的差值。
GPIO 端口置位/复位寄存器说明
①名称 寄存器说明中首先列出了该寄存器中的名称,“(GPIOx_BSRR)(x=A…E)”这段的意 思是该寄存器名为“GPIOx_BSRR”其中的“x”可以为 A-E,也就是说这个寄存器说明适 用于 GPIOA、GPIOB 至 GPIOE,这些 GPIO 端口都有这样的一个寄存器。
?②偏移地址 偏移地址是指本寄存器相对于这个外设的基地址的偏移。本寄存器的偏移地址是 0x18, 从参考手册中我们可以查到 GPIOA 外设的基地址为 0x4001 0800 ,我们就可以算出 GPIOA 的这个 GPIOA_BSRR 寄存器的地址为:0x4001 0800+0x18 ;同理,由于 GPIOB 的外设基 地址为 0x4001 0C00,可算出 GPIOB_BSRR 寄存器的地址为:0x4001 0C00+0x18 。其他 GPIO 端口以此类推即可。?
③寄存器位表 紧接着的是本寄存器的位表,表中列出它的 0-31 位的名称及权限。表上方的数字为位 编号,中间为位名称,最下方为读写权限,其中w表示只写,r表示只读,rw表示可读写。 本寄存器中的位权限都是 w,所以只能写,如果读本寄存器,是无法保证读取到它真正内 容的。而有的寄存器位只读,一般是用于表示 STM32 外设的某种工作状态的,由 STM32 硬件自动更改,程序通过读取那些寄存器位来判断外设的工作状态。
④位功能说明 位功能是寄存器说明中最重要的部分,它详细介绍了寄存器每一个位的功能。例如本 寄存器中有两种寄存器位,分别为 BRy 及 BSy,其中的 y 数值可以是 0-15,这里的 0-15 表 示端口的引脚号,如 BR0、BS0 用于控制 GPIOx 的第 0 个引脚,若 x 表示 GPIOA,那就是 控制 GPIOA 的第 0 引脚,而 BR1、BS1 就是控制 GPIOA 第 1 个引脚。
其中 BRy 引脚的说明是“0:不会对相应的 ODRx 位执行任何操作;1:对相应 ODRx 位进行复位”。这里的“复位”是将该位设置为 0 的意思,而“置位”表示将该位设置为 1;说明中的 ODRx 是另一个寄存器的寄存器位,我们只需要知道 ODRx 位为 1 的时候,对 应的引脚 x 输出高电平,为 0 的时候对应的引脚输出低电平即可(感兴趣的读者可以查询该 寄存器 GPIOx_ODR 的说明了解)。所以,如果对 BR0 写入“1”的话,那么 GPIOx 的第 0 个引脚就会输出“低电平”,但是对 BR0 写入“0”的话,却不会影响 ODR0 位,所以引 脚电平不会改变。要想该引脚输出“高电平”,就需要对“BS0”位写入“1”,寄存器位 BSy 与 BRy 是相反的操作。
?
例子
我们找到 GPIOB 端口的输出数据寄存器 ODR 的地址是 0x4001 0C0C,ODR 寄存器是 32bit,低 16bit 有效,对应着 16 个外部 IO,写 0/1 对应的的 IO 则输出低/高电平。现在我们通过 C 语言指 针的操作方式,让 GPIOB 的 16 个 IO 都输出高电平,具体代码如下
1 // GPIOB 端口全部输出 高电平
2 *(unsigned int*)(0x4001 0C0C) = 0xFFFF;
总结
学习了寄存器地址映射的相关知识,能够对寄存器地址进行赋值或修改数值,为接下来的实验打下基础。
|