一、位带操作
在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是
外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还
有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当
访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。
通过一下两张图便于理解:
要点备注:
(1)对位带别名区的某一地址(4字节)赋值0或1,位带区的对应位即置0或者1。
(2)由于stm32要求32位执行时效率高,所以位带区1位对应位带别名区32位。
8位一个地址,位带区1个位对应位带别名区的4个连续的地址。
基于要点结合各区的基地址,得到地址换算公式:
(1)对于片上外设位带区的某个比特,记它所在字节的地址为 A,位序号为 n(0<=n<=7),则个人认为n的取值为0~31
该比特在别名区的地址为:
AliasAddr = = 0x42000000 + ( (A-0x40000000)*8 + n) *4
(2)对于 SRAM 位带区的某个比特,记它所在字节的地址为 A,位序号为 n(0<=n<=7),则
该比特在别名区的地址为:
AliasAddr = = 0x22000000 + ( (A-0x20000000)*8 + n) *4
A:操作位所在的寄存器地址 n:位号
为了统一公式,把“位带地址+位序号”转换成别名区地址统一成一个宏。
外设外带区的地址为: 0X40000000~0X40100000,大小为 1MB,这 1MB在 103系列大/中/小容量型号的单片机中包含了片上外设的全部寄存器,
这些寄存器的地址为: 0X40000000~0X40029FFF 。即全部寄存器位带区没有全部用完外设区的516MB地址空间,
而外设别名区0X42000000~0X43FFFFFF就落在使用分保留区域0X40030000~0X5FFFFFFF ,不会跟片上外设的其他寄存器地址重合 。
1 // 把“位带地址+位序号”转换成别名地址的宏 2 #define BITBAND(addr, bitnum) ((addr &0xF0000000)+0x02000000+((addr &0x00FFFFFF)<<5)+(bitnum<<2))
对比(1)(2)两个公式,将地址拆分。
对外设: 0x4000 0000 + 0x0200 0000 + 屏蔽高2位 * 32 + 位号* 4
对SRAM: 0x2000 0000 + 0x0200 0000 + 屏蔽高2位 * 32 + 位号* 4
通过指针的形式操作这些位带别名区地址,最终实现位带区的比特位操作。
1 1 // 把一个地址转换成一个指针 2 2 #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) 3 3 4 4 // 把位带别名区地址转换成指针 5 5 #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr,bitnum))
1 //n可以去0~15,对应GPIO的16个引脚 2 3 #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C 4 5 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) 6 7 PBout(0) = 0;//PB0输出低电平,点亮LED
二、启动文件讲解
7