STM32 学习笔记(位带 操作)

发布时间 2023-04-08 16:04:43作者: 疾风山羊骑士

在 STM32F4xx 器件中,外设寄存器和 SRAM 均映射到一个位段区域,这样可实现单个位段的 读写操作。

 

 

既然是一个区映射到另一个区,首先我们要知道其在目标区所在的偏移量(目标区【目标位所在的位段区域】的地址减去目标区起始地址,长度单位未知,且设长度为字节编号),然后知道其映射区(位带别名区)的起始地址。

由于Bit Band region中的1bit地址要拓展成32bit的地址,那么bit banding的映射规则是映射区的长度是目标区的32倍(长度为字节编号)?

那为什么不是直接偏移量*32+映射区的起始地址?因为这只是求得1字节内第0位对应的映射地址(由于1字节有8个比特)。而要是求第1-7位呢?很明显还缺少一个偏移量,1字节内位与位的间隔(由于1bit映射成32bit,目标所在位段的位与位的间隔明显是4字节长度【1*32/8=4(字节)】)

查了下Bit banding的映射公式

可通过一个映射公式说明别名区域中的每个字与位段区域中各个位之间的对应关系。

什么是字?

什么是位?

【字和位均是数据存储单位。

每一个逻辑0或者1便是一个位。它的英文名字叫(bit),是计算机中最基本的单位。

16个位为一个字,它代表计算机处理指令或数据的二进制数位数,是计算机进行数据存储和数据处理的运算的单位。

*16?(1位对应1字?)

然而是*32.(1位对应四字节,两字?)

为什么Bit Band region中的1bit地址要拓展成32bit的地址?查资料说是因为stm32的数据总线是32位,对于它的cpu来说一次处理32bit才是最快最有效的。

映射公式:bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)

其中:

bit_word_addr 代表别名区域中将映射到目标位的字的地址。

bit_band_base 代表别名区域的起始地址。

byte_offset 代表目标位所在位段区域中的字节编号。

1字节=8bit;

字节编号=目标位所在位段区域的地址-该位段区域的起始地址;

(byte_offset x 32)

在32位机器中,应用BitBand进行映射的时候,一位bit会膨胀成32位;

bit_number 代表目标位的位位置 (0-7)。

图解如下:

 

 红色点即为对应的bit_word_addr 。

 

字节编号*32的图解:

 

 

对于SRAM上

 

 

由于在STM32中有两个区域支持BitBand,分别是SRAM区和外设区,这两个区域和同名区的对应关系分别为:
SRAM:0x20000000(RAM_Base) ----- 0x20100000
位带别名区:0x22000000(RAM_BB_Base) ----- 0x23FFFFFF
外设: 0x40000000 ----- 0x40100000
位带别名区:0x42000000 ----- 0x43FFFFFF

很明显0x300=0x20000300-0x20000000

十进制计算:
 0x22000000 + (0x300*32) + (2*4)

=0x22000000++(

=0x22000000++(

=0x22000000+0x6000+0x8

=0x22006008

二进制计算:

0x22000000 + (0x300*32) + (2*4)

=0x22000000+1100000000<<5+10<<2

=0x22000000+110000000000000+1000

=0x22000000+0x6000+0x8

=0x22006008

对于外设上

 

 

 

 

 

 

很明显stm32外设包含这些外设(USB OTG HS,以太网 MAC,DMA2,DMA1……GPIOI, GPIOH, GPIOG, GPIOF……TIM2)由表可知整个外设的起始地址是0x4000 0000.

由于寄存器的位不一定只有8位,所以bit_number 代表目标位的位位置 (0-取决于该寄存器的位数)。

在STM32微控制器中,GPIOF_ODR是GPIOF外设的一个寄存器,用于控制GPIOF端口的输出状态。GPIOF_ODR寄存器包含了16个单独的位,每一位对应GPIOF端口的一个引脚。bit_number 代表目标位的位位置 (0-15),以引脚来映射(1-16)*1。

 

而GPIOF_MODER寄存器包含了32个单独的位,每两个连续的位对应GPIOF端口的一个引脚,具体地说,GPIOF_MODER寄存器的第0位和第1位对应GPIOF的第0个引脚,以此类推。bit_number 代表目标位的位位置 (0-31),以引脚来映射(1-16)*2。

 

例题:

LED0对应的引脚为PF9;

LEDO在GPIOF_ODR对应的bit-word-addr地址:

0x4200 0000+(0x4002 1414-0x4000 0000)*32+9*4=0x424282A4:

其中0x4002 1414为

0x4002 1400+0x04=0x4002 1414

 

 

LEDO在GPIOF_MORDER对应的bit-word-addr地址:

0x42000000+(0x4002 1400-0x4000 0000)*32+18*4=42428048;

其中0x4002 1400为

0x4002 1400+0x00=0x4002 1400