STM32F2位带操作

来源:互联网 发布:淘宝金利来男士钱包 编辑:程序博客网 时间:2024/05/02 03:30
手册中说:
In the STM32F20x and STM32F21x both the peripheral registers and the SRAM are mapped to a bit-band region, so that single bit-band write and read operations are allowed.
在这两个系列中外设和SRAM都有各自映射的位带区,以实现对位的单独操作。
The operations are only available for Cortex
®-M3 accesses, and not from other bus masters (e.g. DMA).
使用局限于M3内核。
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 × 4)
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-7) of the targeted bit  
这里的位就是目标位。

位带区在SRAM上的地址范围:0x20000000 ~ 0x200FFFFF(SRAM区中最低1MB)
位带识别区在SRAM上的地址范围: 0x22000000 ~ 0x220FFFFF
位带区在片上外设的地址范围:0x4000 0000-0x400F FFFF(片上外设区中的最低1MB),
位带识别区在片上外设的地址范围:0x4200 0000~0x42FF FFFF;
对应关系:位带区的每个bit位的值 对应 位带识别区1个 32位的地址的内容;
所以位带操作是:当你通过位带别名区访问这些32位的地址的内容时,就可以达到访
问位带区对应的比特位。

举例:
要给GPIO PC15做拉高拉低操作。
首先找到操作寄存器的地址:
GPIO为外设,故需用外设的基地址:                   PERIPH_BASE               ((uint32_t)0x40000000)
GPIOC在AH1外设上,故在之前基础上再做偏移:AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000)
同时需要再加上GPIOC的偏移:                         GPIOC_BASE                  (AHB1PERIPH_BASE + 0x0800)
然后找到位设置寄存器:                                   GPIOC_BSRR                  (GPIOC_BASE + 0x18)

最终得到的地址为 :0x40020818
通常情况下向这个地址赋值即可实现指定位拉高拉低操作:
*((volatile unsigned long *)0x40020818) = 0x80000000  //!<拉高
*((volatile unsigned long *)0x40020818) = 0x00008000  //!<拉低

但通过位带,按照公式获取位带操作地址:
/*这是拉高时寄存器地址*/
 AddrH = 
*((volatile unsigned long *)((0x40020818 & 0xF0000000)+0x2000000+((0x40020818 & 0xFFFFF)<<5)+(15 << 2)))  
AddrH = 1;   //!<置1就拉高 

/*这是拉低时寄存器地址*/
 AddrL = 
*((volatile unsigned long *)((0x40020818 & 0xF0000000)+0x2000000+((0x40020818 & 0xFFFFF)<<5)+((15+16) << 2))) 
AddrL = 1;   //!<置1就拉低  

使用宏定义,即:(Addr为GPIOC_BSRR 拉高时BitNum为15 拉低时BitNum是(15+16)
#define BitBand(Addr,BitNum) *((volatile unsigned long *)((Addr & 0xF0000000)+0x2000000+((Addr & 0xFFFFF)<<5)+(BitNum << 2))) 

精简之后,位带操作 
#define BitBand(Addr,BitNum) *((volatile unsigned long *)(PERIPH_BB_BASE|((Addr-PERIPH_BASE)<<5)|(BitNum << 2)))
原创粉丝点击