STM32F4-DISCO 学习之深入理解Bitband

/ 0评 / 1

我也不知道为什么叫Bitband,但是Bitband这个东西是效率高,直接操作绝对内存.

因为Bit-Banding是M4的特性,所以应该看M4的开发指南(感叹一句:现在就是科技进步太快,所以东西跟不上了.)

QQ截图20150929191428

上面有权威说明Bit-Banding区域:

QQ截图20150929191428

对照手册,支持Bit-Banding的区域,很多,只要是AHB1,APB1,APB2的都可以支持.QQ截图20150929191428

接着还有一页:

QQ截图20150929191428

要是把所有地址列出来,也是够费劲的.网上一般只操作那个GPIO,其实其他外设也可以用,用于查询标志什么也是很方便的.除了FSMC,RNG,HASH,CRYP,DCMI,USB OTG FS外,其他都支持,其中CRYP本身F407就不支持.甚至BKPRAM都是支持的哦.另外还有SRAM的低1MB也是支持Bit-Banding,不过,又有哪个东西,片内有1M RAM那么大.当也不是所有SRAM都可以,其中CCM部分就不行.

QQ截图20150929191428

但是我们没SRAM2,只有SRAM1,SRAM1又有两个部分,均可Bit-Banding.

QQ截图20150929191428

知道怎么Bit-Banding也得知道他的公式啊.比如我们要翻转PA1这个IO,首先要找到PA1的源地址[未映射地址],是0x40020000

QQ截图20150929191428

然后ODR寄存器偏移0x14,就是0x40020014,如目标还在Bit1.

QQ截图20150929191428

位段操作地址应该是:

0x42000000[位段基地址] + ((0x40020014 - 0x40000000)[偏移]*32)+(1[位于Bit1位置]*4)=0x42400284.

看程序范例,使用了三条汇编:

QQ截图20150929191428

如果操作寄存器呢?至少需要5条,如果要置0,那就更多了.

QQ截图20150929191428

当然,计算Bit Band地址非常麻烦,Keil有他的方法.其实这个在TI的芯片上早就有呢,叫__attribute__((bitband)),比如现在定义一个结构体.比如我为ODR设置一个:

typedef struct
{
    __IO uint32_t BIT0:1;
    __IO uint32_t BIT1:1;
    __IO uint32_t BIT2:1;
    __IO uint32_t BIT3:1;
    __IO uint32_t BIT4:1;
    __IO uint32_t BIT5:1;
    __IO uint32_t BIT6:1;
    __IO uint32_t BIT7:1;
    __IO uint32_t BIT8:1;
    __IO uint32_t BIT9:1;
    __IO uint32_t BIT10:1;
    __IO uint32_t BIT11:1;
    __IO uint32_t BIT12:1;
    __IO uint32_t BIT13:1;
    __IO uint32_t BIT14:1;
}GPIO_TypeDef_ODR __attribute__((bitband));

然后我还新建修改一个GPIO的结构体:

typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO GPIO_TypeDef_ODR ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDefTest;

 再观察我们的操作:

QQ截图20150929191428

再看BitBand读取.常用于判断标志位?这三句比较部分的,很节省指令啊.

QQ截图20150929191428

总结Bit-Banding最简化操作,需要3个周期写,3个周期判断.我也不知道是多少时间,不过,ARM Cortex-M4是多级流水线的,如果说是4个周期[取指-译码等等..]也不对,说一个也不对[这个指令完了下一个立马可以执行],反正就是省时省力.

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注