本帖最后由 jcky001 于 2023-6-15 09:55 编辑
为什么需要位带操作?因为编程需要操作某个bit位来达到我们想要的功能,比如点灯需要操作GPIOA->ODR 的某个bit假设是第2bit,写1就可以让GPIO输出一个高电平。
复制代码
这样写其实有三个隐含的操作: //1.读取ODR寄存器的值到内存//2.改写第2bit的值//3.再把改写后的值写进ODR寄存器 这样的缺点:效率低 位带操作就是为了解决这个问题,前提是硬件支持这么做。 位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见。51 单片机中通过关键字 sbit 来实现位定义,STM32没有这样的关键字,而是通过访问位带别名区来实现,例如 - sbit LED P1^2
- LED = 1;//输出高电平
- LED = 0;//输出低电平
复制代码
这样的优点:效率高
什么是位带别名区?STM32本身不支持位操作,它发明了一种位带操作来让32的某些资源支持位操作。 这两个区域一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。 这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。 位带别名区就是就是就是本来位的区域,变成了字的区域。 这里有个形象的解释: 打个形象的比方,以某个村,就张村把,该村有3户人家分别为A,B,C,我想给张村的A送礼,但是明文规定,不能给具体的个人送礼,但是可以给村委会送礼,那我该怎么办呢,OK,即日起,A不叫A了,改名叫做村委会1,B和C分别改叫做村委会2和村委会3,哦了,可以给A送礼了,虽然我送礼的对象是村委会1,听起来好像比个人级别高一点,但是最终收到礼物的还是个人A。同理,STM32不允许对某个端的某一个IO口进行操作,也就是PA.1 = 0或者PA.1 = 1这样的操作是非法的,好了,那我就给PA.1起个别名,将原来PA.1的位地址扩展成一个32位的字地址,对32位的地址进行操作,这个是STM32允许的,肯定是可以的,STM32对所有的寄存器配置,都是对某个32位地址的操作,因此说白了,操作一个32位寄存器来影响某个位的操作叫做位带操作。
什么是位带区?我们可以看到下面图中有两个位带区,分别是SRAM区里的0x20000000-0x200FFFFF地址段和片内外设区里的0x40000000-0x400FFFFF地址段(图中标号①处),它们的地址空间大小都是1M字节,在SRAM段内和外设地址段内的这1M大小的空间就是位带区,说白了就是支持位带操作的区域就是位带区。
位带区跟位带别名区有怎样的关系?从上面映射图上可以看到,SRAM区里的0x22000000-0x23FFFFFF地址段和外设区里0x42000000-0x43FFFFFF地址段都是位带别名区,两个别名区空间大小都是32MB。那么,这32MB的位带别名区地址空间是怎么与1MB的位带区地址空间对应起来的呢? 答案:地址映射 那么问题来了?将1M字节里面的每一个bit映射到32M字节里面去,那么怎么映射呢? 首先明确一些概念: 1字节= 8bit
1字 = 4字节 = 32bit
看图
将1bit映射到1个字空间(扩大了32倍) 映射前的1个字节 = 映射后的8个字(扩大了32倍 8 * 4 = 32字节) 那么就得出以下结论: 映射前的1个字节 = 映射后的32个字节 映射前的1M字节 = 映射后的32M字节
0x40000000地址处的1个bit变成了0x42000010地址处的32个bit 为什么要将1bit空间要映射到一个字空间里去呢?我映射到1字节或者2字节的地址空间不行吗?我只能说,STM32是一个32位的机器,内核按字寻址的话寻址速度是最快的,所以别问这么多为什么,如果问了,答案就是为了速度。就好比你买个电脑用一个小箱子装着但是顺丰快递发货走的是集装箱,理论上来说装到集装箱里空运是最快的,要不然没办法上飞机啊......各位想想好像是这么个道理哈
|