DSP

STM32F1学习-深入理解存储器(存储器映射以及bit-band)

2019-07-13 18:14发布

1.存储器映射 STM32F1的系统结构 存储器映射 STM32F1的存储器的映射 存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。 从系统结构图中我们可以看出,所有内部设备都是AHB System Bus上,AHB系统总线又分成两个连接的桥,APB1的操作速度限于36MHZ,APB2的操作速度是全速(最高72MHZ)可以很清晰的从图中看出每个桥连接的内部设备。 寄存器(GPIOX)组起始地址 我们以GPIOA为例子。首先我们得明确一点:GPIOA是挂载在APB2上,APB2是从AHB系统总线中分出来的。   从stm32f10x.h头文件中,我们可以得到一些程序段: typedef unsigned int uint32_t;//说明CRL等寄存器是十六位的。 typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef; 首先我们明确GPIO_TypeDef是一个结构体变量。 下面的程序段最好从下往上看更好理解。 #define PERIPH_BASE((uint32_t)0x40000000)  #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)  #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) PERIPH_BASE 是外设基地址,为了便于我们可以把这个比作是AHB系统总线的地址,那么APB2的地址就是在外设基地址的基础上加上偏移量。由程序段看出来偏移量是0x10000,同样的理解。GPIOA的地址就是在APB2的地址的地址基础上加上一个偏移地址,由程序段中可以看出是0x800。所以我们可以得到GPIOA的起始地址地址是0x4000_0000+0x1_0000+0x0800 = 0x4001_0800。 从STM32的中文参考手册中,我们看到CRL、CHL、IDR、ODR、BSRR、BRR、LCKR的偏移量都是004H。 因为CRL、CHL、IDR、ODR、BSRR、BRR、LCKR寄存器都定义的是16位的地址,所以定义32的地址需要 这么理解:一个地址存储八位信息,(char一个字节是八位最大的整数是2^8-1)比如:0x4001_0800存储8位的信息,0x4001_0801存储8位信息......0x4001_0804存储8位信息。一共存储32位信息。GPIOx的某一位的CRL需要4个位(两个位控制模式,两个位控制速度)来控制。4*8(CRL只控制低8位)=32。 因此GPIOA各个寄存器的实际地址 寄存器                偏移地址         实际地址=基地址+偏移地址  GPIOA->CRL     0x00  0x40010800+0x00 
GPIOA->CRH;   0x04   0x40010800+0x04  GPIOA->IDR;     0x08   0x40010800+0x08  GPIOA->ODR    0x0c  0x40010800+0x0c  GPIOA->BSRR   0x10   0x40010800+0x10  GPIOA->BRR     0x14   0x40010800+0x14 GPIOA->LCKR   0x18   0x40010800+0x18    2.bit-band理解   Bit Banding功能是相对于以往能够进行bit操作的单片机而言的。通过Bit Banding功能可以像51单片机的bit操作一样。MCS51可以简单的将P1口的第2位独立作:P1.2=0;P1.2=1  就是这样把P1口的第三个脚(BIT2)置0或置1了。而现在STM32的位段、位带别名区就为了实现这样的功能。只不过他是为需要操作的地址(1字节)的每一个位(共8位)起个别名,分别对应别名区的一个字(word)。也就是别名区的大小是Bit Band的32倍。这样,32MB的别名区地址的操作,就是对相应Bit Band区的位的操作。Bit Banding功能是相对于以往能够进行bit操作的单片机而言的。 和bit-bind有关的寄存器     STM32有两个Bit Band区域,分别是: 0x2000 0000——0x2010 0000:该地址是STM32的SRAM低1MB的地址区域; 0x4000 0000——0x4010 0000:该地址是STM32的Peripherals低1MB的地址区域; 另外,STM32还有两个对应的Bit Band区域的别名区,分别是: 0x2200 0000——0x23FF FFFF:共32MB的空间,对应相应1MB的每一个位; 0x4200 0000——0x43FF FFFF:共32MB的空间,对应相应1MB的每一个位;   接下来的问题是如何确定Bit Band区字节的位所对应的那个别名区的字(word)。Bit Band区和别名区是一一对应的,具体的公式为: bit_word_addr=bit_band_base+ (byte_offset×32) + (bit_number×4); bit_band_base:32MB别名区首地址; byte_offset:1MB位段区偏移量,即为bit-band 区中包含目标位的字节的编号; bit_number:位段中目标位的位位置(0-7);  举个例子(通过别名区访问地址): 1、想操作SRAM中Bit Band区地址为 0x2000 0018字节的第2位 计算别名区对应子地址:0x2200 0000 +(18*32)+(2*4) = 0x2200 0248 所以,对0x2200 0248地址的操作,就是对0x2000 0018字节的第2位进行操作; 注意:别名字的位[31:1]在 bit-band 位上不起作用。写入 0x01 与写入 0xFF 的效果相同。写入0x00 与写入0x0E 的效果相同。 好了,整理了大概有5个小时,有部分是参考: 【疑问】 可以bit-bind的区域是:0x2000_0000-0x2010_0000  和0x4000_0000-0x4010_0000。具体是哪些寄存器,在头文件怎么实现的?比如是0x40010800+0x0c是PAout(); 其他的寄存器是怎么实现的?   转自:https://blog.csdn.net/u013355826/article/details/51953250