i.MAX RT 系列之寄存器映射
一、 前言 在《i.MAX RT 系列之存储器映射》中,我们了解了存储器及其功能分配,想必大家也都知道存储器本身是没有地址的,给存储器分配地址的过程叫做存储器映射。那么寄存器是什么?寄存器映射又是什么?
二、 寄存器映射
存储器中 Block2 设计的是片上外设,在相应的地址空间中以四个字节为一个单元,共32bit ,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作(方法:找到每个单元的起始地址,然后通过指针的操作方式来访问这些单元)。
例如,我们找到 GPIO1 端口的输出数据寄存器 DR 的地址是 0x401B 8000(在《初识 i.MX RT 系列芯片》表 4-5 中有标出), DR 寄存器是 32bit ,对应 32 个外部 IO,写 0/1 对应的 IO 则输出低/高电平。
// GPIO1 端口全部输出高电平 *(unsigned int*)(0x401B8000) = 0xFFFFFFFF; |
代码 1-1 通过绝对地址访问内存单元
0x401B 8000 在编译器看来,只是一个普通的变量,是一个立即数,要想让编译器认为是指针,我们将其强制转换成指针类型,即 (unsigned int *)0x401B 8000 ,然后再对这个指针进行 * 操作。 但如果每次都通过这种方式来访问的话,不仅容易出错,也不好记忆。所以为了方便,可以根据每个单元的功能不同给对应的内存单元取一个别名。这个别名对应的内存区就是寄存器,而给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
如 1-1 代码可以通过寄存器方式写成如下格式: //GPIO1 端口全部输出高电平 #define GPIO1_DR * (unsigned int*)(0x401B8000) GPIOF_DR = 0xFFFFFFFF; |
代码 1-2 通过寄存器别名访问内存单元
二、 RT1060 外设基地址映射2.1 总线基地址 RT1060 片上外设区的 5 条 AIPS 总线挂载着不同的外设,相应总线的最低地址我们称为该总线的基地址,总线基地址也是挂载在该总线上的首个外设的地址。
总线名 | 称总线基地址 | AIPS-1 | 0x4000 0000 | AIPS-2 | 0x4010 0000 | AIPS-3 | 0x4020 0000 | AIPS-4 | 0x4030 0000 | AIPS-5 | 0x4200 0000 |
表 2.1 总线基地址
2.2 外设基地址 总线上挂着各种外设,这些外设也有自己的地址范围,特定外设的首个地址称为 “ XX 外设基地址”,也叫 XX 外设的边界地址。具体有关 RT1060 外设的边界地址请参《IMXRT1060RM》(参考手册)的第 3 章中的存储器映射表。
外设名称 | 外设基地址 | GPIO1 | 0x401B 8000 | GPIO2 | 0x401B C000 | GPIO3 | 0x401C 0000 | GPIO4 | 0x401C 4000 | GPIO5 | 0x400C 0000 | GPIO6 | 0x4200_0000 | GPIO7 | 0x4200_4000 | GPIO8 | 0x4200_8000 | GPIO9 | 0x4200_C000 |
表 2.2 GPIO 外设基地址
注意:GPIO1~GPIO4 的外设基地址都位于 AIPS-2 总线地址的范围,GPIO5 挂在 AIPS-1 总线上, GPIO6~GPIO9 挂在 AIPS-5 总线上。不过除了所属总线及地址的差异外,它们的功能都一样。 四、外设寄存器 在某个外设的地址范围内,分布着的就是该外设的寄存器。以 GPIO 外设为例, GPIO是 RT1060 可控制的通用输入输出端口引脚,基本功能是控制引脚输出高电平/低电平。最简单的应用就是把 GPIO 的引脚连接到 LED 灯的阴极,LED 灯的阳极接电源,然后通过RT1060 控制该引脚的电平,从而实现控制 LED 灯的亮灭。 RT1060 的 GPIO 有很多个 32bit 寄存器,每个寄存器都有特定的功能,占 4 个字节,在该外设的基地址上按照顺序排列,因此寄存器的位置可以用相对该外设基地址的偏移地址来描述。这里我们以 GPIO1 端口为例,来说明 GPIO 都有哪些寄存器。
寄存器名称 | 类型寄存器 | 地址 | 相对于 GPOI1 的地址偏移 | GPIO1_DR | 数据寄存器 | 0x401B 8000 | 0h | GPIO1_GDIR | 方向寄存器 | 0x401B 8004 | 4h | GPIO1_PSR | 状态寄存器 | 0x401B 8008 | 8h | GPIO1_ICR1 | 中断配置寄存器 | 0x401B 800C | Ch | GPIO1_ICR2 | 中断配置寄存器 | 0x401B 8010 | 10h | GPIO1_IMR | 中断掩码寄存器 | 0x401B 8014 | 14h | GPIO1_ISR | 中断状态寄存器 | 0x401B 8018 | 18h | GPIO1_EDGE_SEL | 边沿选择寄存器 | 0x401B 801C | 1Ch | GPIO1_DR_SET | 数据寄存器设置 | 0x401B 8084 | 84h | GPIO1_DR_CLEAR | 数据寄存器 cLear | 0x401B 8088 | 88h | GPIO1_DR_TOGGLE | 数据寄存器切换 | 0x401B 808C | 8Ch |
表 3.1 GPIO1 端口的寄存器地址列表
由于每个 GPIO 端口的控制方式完全一致,GPIO1~GPIO9 都具有同样功能的寄存器用于控制对应端口引脚的特性,所以在《IMXRT1060RM》(参考手册)中对寄存器地址如下:
表 3.2 GPIO 端口的寄存器地址列表
表格上面的三行文字说明了 GPIO1~GPIO9 端口的基地址,然后表格列出各寄存器相对端口基地址的偏移。例如,想要知道 GPIO3 的状态寄存器(PSR)实际地址时,可以根据公式算出: GPIO3 基地址:0x401B 8000+(3-1)×0x4000 = 0x401C 0000 PSR 寄存器相对基地址的偏移为 8h ,所以: GPIO2_PSR 寄存器地址:0x401C 0000 + 0x08 = 0x401C 0008
芯片对外设寄存器的这种统一安排不仅方便理解,也简化了程序中对寄存器地址的定义。有关外设的寄存器说明可参考《IMXRT1060RM》(参考手册)中具体章节的寄存器描述部分,在编程的时候我们需要反复查阅外设的寄存器说明。下一讲我们以“ GPIO 中断配置寄存器 GPIO_ICR1 ”为例,讲解如何理解寄存器的说明,更多精彩有待下回分解,赶紧将博主关注起来吧~
【参考文献】
|