1、什么是存储器映射?
在图5-4中,连接被控总线的是FLASH,RAM和片上外设,这些功能部件共同排列在一个 4GB 的地址空间内。我们在编程的时候,操作的也正是这些功能部件。
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射。如果给存储器再分配一个地址就叫存储器重映射。
在这 4GB的地址空间中,ARM已经粗线条的平均分成了 8 个块,每块 512MB,每个块也都规定了用途。每个块的大小都有 512MB,显然这是非常大的,芯片厂商在每个块的范围内设计各具特色的外设时并不一定都用得完,都是只用了其中的一部分而已。在这 8 个 Block 里面,有 3 个块非常重要,也是我们最关心的三个块。Boock0 用来设计成内部 FLASH,Block1用来设计成内部 RAM,Block2用来设计成片上的外设。
寄存器都是外设的寄存器,寄存器都存在block2里面!!!
GPIO挂接在AHB1上的。
2、寄存器映射
在存储器 Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过 C语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
3、 STM32的外设地址映射
1)、总线基地址
2)、外设基地址
4、外设寄存器
在 XX外设的地址范围内,分布着的就是该外设的寄存器。GPIO有很多个寄存器,每一个都有特定的功能。每个寄存器为 32bit,占四个字节,在该外设的基地址上按照顺序排列,寄存器的位置都以相对该外设基地址的偏移地址来描述。这里我们以 GPIOH端口为例,来说明 GPIO 都有哪些寄存器,具体见表格 5-7。
5、 C语言对寄存器的封装
以上所有的关于存储器映射的内容,最终都是为大家更好地理解如何用 C 语言控制读写外设寄存器做准备,此处是本章的重点内容。
1)封装总线和外设基地址
在编程上为了方便理解和记忆,我们把总线基地址和外设基地址都以相应的宏定义起来,总线或者外设都以他们的名字作为宏名。
代码 5-4 首先定义了 “片上外设”基地址 PERIPH_BASE,接着在 PERIPH_BASE 上
加入各个总线的地址偏移,得到 APB1、APB2 等总线的地址 APB1PERIPH_BASE、
APB2PERIPH_BASE,在其之上加入外设地址的偏移,得到 GPIOA、GPIOH的外设地址,
最后在外设地址上加入各寄存器的地址偏移,得到特定寄存器的地址。一旦有了具体地址,
就可以用指针操作读写了,具体见代码 5-5。
6、封装寄存器列表