文章目录
前言
位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见。51 单片机中通过关键字 sbit 来实现位定义,STM32 没有这样的关键字,而是通过访问位带别名区来实现。
提示:以下是本篇文章正文内容
一、示意图
在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。
二、位带区
1.外设位带区
外设外带区的地址为:0X40000000~0X40100000,大小为 1MB,这 1MB 的大小在 103系列大/中/小容量型号的单片机中包含了片上外设的全部寄存器,这些寄存器的地址为:0X40000000~0X40029FFF 。
外设位带区地址为: AliasAddr= =0x42000000+ (A-0x40000000)*8*4 +n*4
0X42000000 是外设位带别名区的起始地址,0x40000000 是外设位带区的起始地址,(A-0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以8,一个位膨胀后是 4 个字节,所以4,n 表示该比特在 A 地址的序号,因为一个位经过膨胀后是四个字节,所以也*4。
2.SRAM 位带区
SRAM 的位带区的地址为:0X2000 0000~X2010 0000,大小为 1MB,经过膨胀后的位带别名区地址为:0X2200 0000~0X23FF FFFF,大小为 32MB。
SRAM 位带区地址为: AliasAddr= =0x22000000+ (A-0x20000000)*8*4 +n*4
,分析同上。
3.统一公式
为了方便操作,我们可以把这两个公式合并成一个公式,把“位带地址+位序号”转换成别名区地址统一成一个宏。
// 把“位带地址+位序号”转换成别名地址的宏
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))
addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是外设,则取出的是 4,+0X02000000 之后就等于 0X42000000,0X42000000 是外设别名区的起始地址。如果是 SRAM,则取出的是 2,+0X02000000 之后就等于 0X22000000,0X22000000 是 SRAM 别名区的起始地址。
实际应用:
1 // 把一个地址转换成一个指针
2 #define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
3
4 // 把位带别名区地址转换成指针
5 #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum