打印

发布 bitBanding 例子程序

[复制链接]
6423|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
americ|  楼主 | 2008-3-20 23:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


Cortex?-M3 将片内外设和SRAM都做了位映射。=====这么处理,单片机就无法直接支持4G字节内存。哈。

(08年,笔记本电脑正在4G内存热炒,也来凑个热闹)

SRAM空间2000... 映射到2200...
实际上,为片内SRAM仅保留了2000,0000 - 200f,ffff。
Cortex?-M3 仅保留1Mbyte空间,马马虎虎====要知道,受到07年的飞身直落,08年的DDR2仅相当于1M折合1元*币!(不好意思,又来了。20080313Hy512M DDR2-667仅58元*币--板上8颗芯片?每颗芯片64Mbyte不到8元?实际上DDR芯片非存储部分占用了相当大面积,近乎一半,不能简单除法。内存与逻辑生产工艺也不相同。片内SRAM相当占面积,更不要提主流CPU内的高速缓存RAM......)


闲话少说,言归正传:
0x2000 0000   bit0 对应   0x2200 0000
0x2000 0000   bit1 对应   0x2200 0004
0x2000 0000   bit2 对应   0x2200 0008
......
0x200f ffff   bit15对应   0x23ff fffc    呵呵


由于32位系统,一次处理4个字节比较直观;所以,总是把4个字节一起处理;于是,字节地址0123就被一

次性处理掉了;总之,地址没有123那样连续,而是0,4,8,c,0这样蹦蹦跳跳。
=======为每一个bit分配一个 “32bit MCU 可以方便处理的地址”,需要占用32倍地址空间。


因此,嗯,是这样的,地址的计算公式,稍微复杂了点:
bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)

SRAM
2200 0000 加上偏移
SRAM_BB_BASE

void get_bit(u8 db8)
{
  vu32 VarAddr;
  VarAddr = (u32)&db8;
  VarAddr = (0x22000000 | ((VarAddr - 0x20000000) << 5) );
  bit0  = (*(vu8 *) VarAddr);  //VarAddr += 4;
......

}


特殊功能寄存器:
4200 0000 加上偏移
PERIPH_BB_BASE

#include "stm32f10x_map.h"

#define BIT_1 1
#define BIT_2 2
#define BIT_3 3
#define BIT_4 4
#define BIT_5 5

#define IO_ODR 0x0c

#define IO_OUT(a,b) (*(vu8 *)(PERIPH_BB_BASE | ((a - PERIPH_BASE + IO_ODR) << 5) + (b << 2)))

#define bitX  IO_OUT(GPIOD, BIT_Pin_3)
========bitX仅仅负责输出哦!ODR 可以输出0,也可以输出1。IDR才能输入,读取。还有BSRR,BRR,根据需要取用。

或者干脆

//       C9   C 40011000   ODR  C   bit 9
//              42220000      180      24
#define dd0           (*(vu8 *)0x422201A4)
//看明白了么?

dd0 = 1;


bitX = 1;

bitX = 0;










沙发
grant_jx| | 2008-3-21 00:10 | 只看该作者

写的怪怪的,有卖弄文字的嫌疑。不过还是要支持一下

在STM的官方的固件库下面有个Examples里有个CortexM3文件夹,Example1给出了bitbanding详解的使用描述。


偏移用的基地址都是固定的
#define RAM_BASE       0x20000000
#define RAM_BB_BASE    0x22000000
 
三个对位操作的宏定义,清零、置位、读位:
#define  Var_ResetBit_BB(VarAddr, BitNumber)    
          (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | RAM_BB_BASE | ((BitNumber) << 2)) = 0)
   
#define Var_SetBit_BB(VarAddr, BitNumber)       
          (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | RAM_BB_BASE | ((BitNumber) << 2)) = 1)

#define Var_GetBit_BB(VarAddr, BitNumber)       
          (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | RAM_BB_BASE | ((BitNumber) << 2)))
   
 

使用方法:
/* A mapping formula shows how to reference each word in the alias region to a corresponding bit in the bit-band region. The mapping formula is:
  bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number x4)

where:
   - bit_word_addr: is the address of the word in the alias memory region that maps to the targeted bit.
   - bit_band_base is the starting address of the alias region
   - byte_offset is the number of the byte in the bit-band region that contains the targeted bit
   - bit_number is the bit position (0-31) of the targeted bit */

/* Get the variable address --------------------------------------------------*/ 
  VarAddr = (u32)&Var; 

/* Modify variable bit using bit-band access ---------------------------------*/
  /* Modify Var variable bit 0 -----------------------------------------------*/
  Var_ResetBit_BB(VarAddr, 0);  /* Var = 0x00005AA4 */
  Var_SetBit_BB(VarAddr, 0);    /* Var = 0x00005AA5 */
  
  /* Modify Var variable bit 11 -----------------------------------------------*/
  Var_ResetBit_BB(VarAddr, 11);             /* Var = 0x000052A5 */
  /* Get Var variable bit 11 value */
  VarBitValue = Var_GetBit_BB(VarAddr, 11); /* VarBitValue = 0x00000000 */
  
  Var_SetBit_BB(VarAddr, 11);               /* Var = 0x00005AA5 */
  /* Get Var variable bit 11 value */
  VarBitValue = Var_GetBit_BB(VarAddr, 11);    /* VarBitValue = 0x00000001 */
  
  /* Modify Var variable bit 31 -----------------------------------------------*/
  Var_SetBit_BB(VarAddr, 31);               /* Var = 0x80005AA5 */
  /* Get Var variable bit 31 value */
  VarBitValue = Var_GetBit_BB(VarAddr, 31); /* VarBitValue = 0x00000001 */
    
  Var_ResetBit_BB(VarAddr, 31);             /* Var = 0x00005AA5 */
  /* Get Var variable bit 31 value */
  VarBitValue = Var_GetBit_BB(VarAddr, 31); /* VarBitValue = 0x00000000 */




使用特权

评论回复
板凳
amixice| | 2008-3-21 10:37 | 只看该作者

Bit-Banding不是什么时候都有意义



对SFR,全局变量等编译器知道具体地址的数据操作,BitBanding才有意义
地址是常数, 编译器给你算好地址之后这个速度是快些.

如果是个局部变量, 或者全局数组中的某个元素[index不确定], 地址不是常数, 先算出地址, 再去操作, 速度还不如用 与/或 来的快.

使用特权

评论回复
地板
zhiwei| | 2008-3-21 12:49 | 只看该作者

对于定义的变量

含标志等的数据,进行位操作,如果编译器够好的话,应该能产生相关的bitband指令吧。有空研究一下。

使用特权

评论回复
5
dld2| | 2008-3-21 12:56 | 只看该作者

路过

笑笑

使用特权

评论回复
6
americ|  楼主 | 2008-3-23 17:13 | 只看该作者

RAM早就有了!!

但是,寄存器.映射.........

americ发布!
至少,在americ发布之前,相关代码并不是那么容易得到。
甚至 相关资料,都不够。




看看 ST 提供的代码吧::
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

#define SPI_FLASH_CS_LOW()     GPIO_ResetBits(GPIOE, GPIO_Pin_7)

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BRR = GPIO_Pin;
}


消耗的ROM足够存放高清电影,消耗的时间足够SPI传送一次。
呵呵。



本文 重点是 “寄存器的映射”!



用途:

ST原本就有 用在很多地方:

最常用之一,其他芯片的片选!

还有,模拟一些接口,RD,WR等。

还有其他很好用途,嘿嘿,下次再发布。

使用特权

评论回复
7
香水城| | 2008-3-24 18:15 | 只看该作者

哈哈,正如2楼所说是有点怪怪的,说明楼主思想很活跃

不管怎样,立论清楚;加精鼓励原创!

使用特权

评论回复
8
americ|  楼主 | 2008-3-27 01:49 | 只看该作者

开头写那么多,为了

为了强调,存储器已经相当便宜。几元*币已经可以买到www xxx 的芯片。

可是我们还没有很好的接口来利用。




使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

288

帖子

2

粉丝