转:http://www.cnblogs.com/alvis-jing/p/3662539.html
有32个美女给你,你32个一起处理是不是有点棘手呀??没事、、那就一个一个“慢慢”来、、为何我这里慢慢要加双引号?因为其实处理一个比处理32个要快很多很多、、好,停住这美好的遐想,来认识下《位绑定》的“地盘”。
位绑定的概念:对于51单片机只有8位,对于M3来说,有32位,也就是说把32位中的某一位通过一个简单的地址的变换的算法来实现对该位的操作,它能够映射到一个地址的空间,也就是说一个位它占一个地址,就好比如把惠州放在广东省的某一个地址,叫做惠州市,通过搭去惠州的车票就可以来到惠州市这个地址,别去东莞哈、但是这个位只有在地址的最低位有效,因为地址可能是指向一个32位的内存单元、、因为是LSB 有效、、所以对其操作的时候就大可不必通过屏蔽其他位来对绑定的位进行操作、也正是最低位有效,所以只要看最低位即可、因为你买的是惠州的车票,所以就不用屏蔽东莞了,因为车不会去东莞、请看“美女”照片:
从图片中我们可以看出,一个位就绑定了一个地址,看到这,你会觉得奇怪?为什么位带区地址是从0x2000 00000开始,而绑定的地址是从0x2200 0000开始的呢?啊哈、、别急哈、、正所谓心急吃不了热豆腐、、
由于M3核处理都是按32位整体处理的,并没有单独对一个位进行操作,所以位绑定就可以实现CPU对单独一个位进行操作,只需要一个指令周期、其速度可显而知、、但是整个M3内核并没有全部允许位绑定,只有两个区有,分别为:
SARM区:0x2000_0000‐0x200F_FFFF 这个SRAM绑定的地址就是从0x2200 0000开始的
片上外设区:0x4000_0000‐0x400F_FFFF 这个区绑定的地址就是从0x4200 0000开始的、、
其映射表分别如下:
现在知道为啥了吧、、还不知道的、、来人、、拉出去调戏10分钟、、
知道的、、来人、、再赏美女十个、、
那怎么绑定呢??开头提到的算法又是什么呢??其实说是算法有点吓人、、因为在别人听来总是感觉算法很难、其实也就是两条公式(一条为SRAM,一条为片上外设)如下:其中A为字节所在的地址,n为位序列号
SRAM区映射的地址 AliasADDr = 0x22000000 + ((A - 0x20000000) * 8 + n) * 4 = 0x22000000 + ((A - 0x20000000) * 32 + n * 4
片上外设区映射的地址 AliasADDr = 0x42000000 + ((A - 0x20000000) * 8 + n) * 4= 0x42000000 + ((A - 0x20000000) * 32 + n * 4
OK,有了这个算法,我们可以来进行C编程了、、
首先我们来找找GPIOA~E的地址;鼠标的光标放在GPIOA~E处,右击,
可以看到GO TO Definition,点击它,就可以找到GPIOA~E的地址,以此类推,我们就可以找出背后的“大哥大”了、、如图:
好了、、有了地址、但是我们还需要每个IO口的输出输入寄存器的偏移地址:
没错了、我们以0x08 0x0c为例
1 #define GPIOA_ODR_A (GPIOA_BASE + 0X0C) 2 #define GPIOA_IDR_A (GPIOA_BASE + 0X08) 3 ... 4 #define GPIOA_ODR_E (GPIOE_BASE + 0X0C) 5 #define GPIOA_IDR_E (GPIOE_BASE + 0X08) 6 7 #define BitBand(Addr,BitNum) *((volatile unsiged long *)(Addr&0xf0000000)+0x2000000+((Addr&0xfffff)<<5)+(BitNum<<2)) 8 9 #define PAout(n) BitBand(GPIOA_ODR_A,n) 10 #define PAin(n) BitBand(GPIOA_IDR_A,n) 11 ... 12 #define PEout(n) BitBand(GPIOE_ODR_A,n) 13 #define PEin(n) BitBand(GPIOE_IDR_A,n)
我来解释下:
Addr&0xf0000000 因为我们不知道到底是SRAM还是片上外设区,所以我们这里取其最高位 因为最高位有可能为4 也有可能为2
Addr&0xfffff 可以看到位绑定的范围0x2000_0000‐0x200F_FFFF 0x4000_0000‐0x400F_FFFF 所以我们这里把高三位屏蔽掉,就相当于 A - 0x20000000的效果了、、
为什么我这里要用《5 和《2 呢?对比一下、、我们可以知道《5相当于*32 《2相当于*4 那我们为什么要用左移符号呢??原因在这:因为左移的处理速度要比乘的快很多、、我们尽量把乘除转化为加减和左右移
写到这里、、没错了、、这下子我们就可以像操作51那样方便操作32位的芯片了、、、
这下子应该明白为什么32个美女一起处理的话会慢很多而且很麻烦了吧、、、哈、、