看见cm3的BIT_BAND很有意思,仔细琢磨了一下,和大家一起分享! 首先追溯到51,51单片机RAM内从从20H往后到3FH是位访问区,每一个字节的每一个位也对应有从00h开始的的每一个字节的最后一位,例如20H.0对应00h,20H.1对应于01h,.....其中00h,01h中起作用的也只是最后一位,其他位都是没意义的,又如FLAG1 BIT 00H,这样的话如果Setb FLAG1 这条语句执行,实际上市对RAM中20H这个字节的Bit0置一了,由此看来,这能ARM也是受Intel的影响和启发啊! 其次:开始讲cm3的BIT_BAND,处理器存储器映射包括两个 bit-banding 区域。它们分别为 SRAM 和外设存储区域中的最低的 1MB。这些 bit-band 区域将存储器别名区的一个字映射为 bit-band 区的一个位。 请看下图:file:///C:/Documents%20and%20Settings/jishu/桌面/isp/未命名.jpg 图中1M的 bit band区域的每一个字节的每一位分别有 bit band别名区的每一个字(四字节)对应,那么,这是不是和51的位区原理一样啊?呵呵,但是我们要知道,这里的位区可不是51里面的那么几十个字节啊,而是偌大的空间,很多人会认为,这样好浪费啊,每一个位对应一个字,那么这个字的其他剩余31个字节就等于是浪费的啊,虽然这是对的,是有点浪费,但是这样做的好处是不可估量的,想象看吧,我们这么举个例子来看看,就比如说现在忘SRAM的首地址写一个字节吧,也就是地址:0x2000 0000 ,但是我们想往0x2000 0000 这个字节的bit 3写1而保证其他的位都不发生变化,我们会怎么做,当然了,这肯定都会,就是一个读-修改-写的过程嘛,首先读出来这个字节给一个temp临时字节类型变量,然后同11110111b相与,然后再把temp给0x2000 0000完成位修改的操作 ,这样麻烦啊,还要定义一个变量,还一不小心把别的位也改变了,岂不出问题?现在好了,我们知道0x2000 0000这个字节对应的bit 0位是对应在别名区的0x2200 0000 往后的一个字(四字节)中,那么,我现在直接像这个别名区写一个最后一位为1就可以了的一个字:(*(u32 *) 0x2200 000b) = 1,这样一条语句就可以往0x2000 0000 这一字节的bit 3写1了,不用定义变量,不用担心会影响其他位,这样带来的好处同刚才我们认为的浪费空间的想法来比,不言而喻啦! 第三:方法和思想都清楚啦,接下来就是要寻找一个有效的方法来高效的写入啦,否则要是这样写一个位都算老半天该往那一个别名区的地址里写数,那可就麻烦了,所以请大家先看一个图,我手画然后扫描上去的,不是很好看,大家将就着看吧,别因为我图画的不好就认为我人品不好啊,我可是花了半天时间扫描的呢: C:Documents and Settingsjishu桌面isp1.jpg Cortex-M3 存储器映射有 2 个 32MB 别名区,它们被映射为两个 1MB 的 bit-band 区: 32MB SRAM 别名区和32MB 外设别名区,我这里图示的是SRAM位区同他们的别名区所对应的关系: SRAM是从0x2000 0000 开始的,他的别名区是从0x2200 0000 开始的,这一点首先要弄清楚,0x2000 0000的每一个位对应于0x2200 0000 往后的一个一个字,如:(0x2200 0000).0对应0x2200 0000 ~0x2200 0003这一个字空间,你只需要定义一个指向32位地址的指针:(u32 *) 0x2200 0000,往这个指针对应的地址中写1就是对:(0x2200 0000).0这一位置一,写0就是清零,诚然,这个别名区的一个字中,1到31位都没有用到,也就是我们先前所说的浪费空间问题,不过优点已经很明显了!依此类推,向图中的0x2000 4001的第 3位,图上是BIT 3(我这里没有将第一位写成BIT0)写1,那么由途中对应的关系,我们就应该向0x2208 0024地址往后的四个字节中写1即: *((u32 *)0x2208 0024)=1;这怎么用公式算呢,很好算,首先我们先确定两个区的基地址,我现在要向 0x2000 4001的第三位写一,它偏移了0x2000 0000 一共是(0x2000 4001 -0x2000 0000)个字节外加3位,而图中我们可以看到,位区的每一个字节的每一个位对应别名区中四个字节,所以总的表达式是: 0x2200 0000 +(0x2000 4001 -0x2000 0000)*8*4 +3*4 这样表达式就小荷才露尖尖角啦:会变的部分有两个: 1.(0x2000 4001 -0x2000 0000),我们称其为字节偏移,用byte_offset表示 2. 3 ,这个我们称其为比特偏移,用bit_offset表示, 那么通用表达式就是: 0x2200 0000 +(byte_offset*32)+(bit_offset*4),得出的便是在别名区中相对于首地址0x2200 0000偏移的字节数。 当然啦,我们这里是对SRAM而言的,如果对外设位区的话,那么以上式子中就不是0x2200 0000了,而应该改成0x4200 0000 啦,说到这里,大家都应该龇牙笑了吧?因为都懂了,不会吧?你为什么不笑,还不懂?那和我联系好了:chuzhujun@foxmail.com |