位带简介
位操作就是可以单独对一个比特位进行读和写。
STM32位带示意图:
位带区和未带别名区地址转换:
对于片上外设位带区的某个位,设它所在字节的地址为A,位序号为n(0~7),那么该位在别名区的地址为:
AliasAddr = 0x42000000 + (A-0x40000000)* 8* 4 + n*4
0x42000000 是外设位带别名区的起始地址。
0x40000000 是外设位带区的起始地址。
(A-0x40000000) 表示改为前面有多少个字节。
一个字节有8位,所以x8,一个位膨胀后是4个字节,所以也x4。
n表示该位在A地址的序号,因为一个位经过膨胀后是4个字节,所以也x4。
对于SRAM位带区的某个位,记它所在字节的地址为A,位序号为n(0~7),则该位在别名区的地址为:
AliasAddr = 0x22000000+(A-0x20000000)* 8* 4 + n*4
统一公式:
//把 “ 位带地址+位序号 ”转化成别名地址的宏
#define BITBAND(addr,bitnum) ((addr & 0xF0000000) +0x02000000+((add &0x00FFFFFF)<<5)+(bitnum<<2))
因为外设的最高地址是:0x20100000,跟起始地址相减的时候,总是低5位才有效。所以屏蔽了高3位。
最后就可以通过指针的形式操作这些位带别名区地址。
// 把一个地址转换成一个指针
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
//把位带别名区地址转换成指针
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
main.c文件
#include "stm32f10x.h"
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF<