我也不知道为什么叫Bitband,但是Bitband这个东西是效率高,直接操作绝对内存.
因为Bit-Banding是M4的特性,所以应该看M4的开发指南(感叹一句:现在就是科技进步太快,所以东西跟不上了.)
上面有权威说明Bit-Banding区域:
对照手册,支持Bit-Banding的区域,很多,只要是AHB1,APB1,APB2的都可以支持.
接着还有一页:
要是把所有地址列出来,也是够费劲的.网上一般只操作那个GPIO,其实其他外设也可以用,用于查询标志什么也是很方便的.除了FSMC,RNG,HASH,CRYP,DCMI,USB OTG FS外,其他都支持,其中CRYP本身F407就不支持.甚至BKPRAM都是支持的哦.另外还有SRAM的低1MB也是支持Bit-Banding,不过,又有哪个东西,片内有1M RAM那么大.当也不是所有SRAM都可以,其中CCM部分就不行.
但是我们没SRAM2,只有SRAM1,SRAM1又有两个部分,均可Bit-Banding.
知道怎么Bit-Banding也得知道他的公式啊.比如我们要翻转PA1这个IO,首先要找到PA1的源地址[未映射地址],是0x40020000
然后ODR寄存器偏移0x14,就是0x40020014,如目标还在Bit1.
位段操作地址应该是:
0x42000000[位段基地址] + ((0x40020014 - 0x40000000)[偏移]*32)+(1[位于Bit1位置]*4)=0x42400284.
看程序范例,使用了三条汇编:
如果操作寄存器呢?至少需要5条,如果要置0,那就更多了.
当然,计算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;
再观察我们的操作:
再看BitBand读取.常用于判断标志位?这三句比较部分的,很节省指令啊.
总结Bit-Banding最简化操作,需要3个周期写,3个周期判断.我也不知道是多少时间,不过,ARM Cortex-M4是多级流水线的,如果说是4个周期[取指-译码等等..]也不对,说一个也不对[这个指令完了下一个立马可以执行],反正就是省时省力.