一、位带的简介
位操作就是可以单独的对一个比特位读和写,在stm32单片机中是通过访问位带别名区来实现的。 在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最 低 1MB 空间。这两个 1MB 的空间除了可以像正常的RAM 一样操作外,他们还有自己的位带别 名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些 字时,就可以达到访问位带区某个比特位的目的。
外设位带区
外设外带区的地址为:0X40000000~0X40100000, 大小为 1MB, 这 1MB 的大小在 103 系列大/中/小容量型号的单片机中包含了片上外设的全部寄存器, 这些寄存器 的地址为:0X40000000~0X40029FFF。 外设位带区经过膨胀后的位带别名区地址为: 0X42000000~0X43FFFFFF, 这个地址仍然在 CM3 片上外设的地址空间中。在 103 系列 大/中小容量型号的单片机里面,0X40030000~0X4FFFFFFF 属于保留地址,膨胀后的 32MB 位带 别名区刚好就落到这个地址范围内,不会跟片上外设的其他寄存器地址重合。 STM32 的全部寄存器都可以通过访问位带别名区的方式来达到访问原始寄存器比特位的效果。
SRAM 位带区
SRAM 的位带区的地址为:0X2000 0000~X2010 0000,大小为 1MB,经过膨胀后的位带别名区 地址为:0X2200 0000~0X23FF FFFF,大小为 32MB。操作 SRAM 的比特位这个用得很少。
位带区和位带别名区地址转换
位带区的一个比特位经过膨胀之后,虽然变大到 4 个字节,但是还是 LSB 才有效。虽然说造成了空间的浪费,但是要知道STM32 的系统总线是 32 位的,按照 4 个字节访问的时候是最快的,所以膨胀成 4 个字节来访问是最高效的。 我们可以通过指针的形式访问位带别名区地址从而达到操作位带区比特位的效果。
外设位带别名区地址
对于片上外设位带区的某个比特,记它所在字节的地址为 A, 位序号为 n(0<=n<=7),则该比特在别名区的地址为:
0X42000000 是外设位带别名区的起始地址,0x40000000 是外设位带区的起始地址, (A- 0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以 *8,一个位膨胀后是 4 个字 节,所以 *4,n 表示该比特在 A 地址的序号,因为一个位经过膨胀后是四个字节,所以也*4。
SRAM 位带别名区地址
对于SRAM 位带区的某个比特,记它所在字节的地址为A, 位序号为n(0<=n<=7),则该比特在别 名区的地址为:
公式分析同上。
统一公式
为了方便操作,我们可以把这两个公式合并成一个公式,把“位带地址+ 位序号”转换成别名区 地址统一成一个宏。
addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是外设,则 取出的是 4,+0X02000000 之后就等于 0X42000000,0X42000000 是外设别名区的起始地址。如 果是SRAM,则取出的是 2,+0X02000000 之后就等于 0X22000000,0X22000000 是SRAM 别名 区的起始地址。
addr & 0x00FFFFFF 屏蔽了高三位,相当于减去 0X20000000 或者 0X40000000,但是为什么是屏蔽高三位?因为外设的最高地址是:0X20100000,跟起始地址 0X20000000 相减的时候,总是低 5 位才有效,所以干脆就把高三位屏蔽掉来达到减去起始地址的效果,具体屏蔽掉多少位跟最高 地址有关。SRAM 同理分析即可。«5 相当于 *8*4,«2 相当于 *4,这两个我们在上面分析过。 最后我们就可以通过指针的形式操作这些位带别名区地址,最终实现位带区的比特位操作。
二、GPIO 位带操作
①实现GPIO寄存器映射
②实现GPIO位操作
在我们就可以用位操作的方法来控制GPIO 的输入和输出了,其中宏参数n 表示具体是哪一个 IO 口,n(0,1,2⋯16)。
主函数如下:
标签:位带,SRAM,别名,stm32,地址,操作,位带区,外设 From: https://www.cnblogs.com/Shion316/p/16972323.html