历史上的今天
今天是:2025年02月02日(星期日)
2020年02月02日 | STM32F1学习-深入理解存储器(存储器映射以及bit-band)
2020-02-02 来源:eefocus
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 的效果相同。
史海拾趣
|
Altium Designer 6 中,制件的原理图文件中若有中文字,用自带的\"智能PDF\"导出时,则在产生的PDF中显示不了中文字符.本人用Altium Designer 6.3~Altium Designer 6.9都试过,均有此问题,不知能否解决,请哪位大侠指点,若不能人为修改,是否要等待A ...… 查看全部问答> |
|
下面的六个程序片段主要完成这些事情: 输出Hello, World混乱C语言的源代码下面的所有程序都可以在GCC下编译通过,只有最后一个需要动用C++的编译器g++才能编程通过。 hello1.c 01 #define _________ } 02 ...… 查看全部问答> |
|
请教Modbus高手makesoft:实现Modbus协议一定需要超时检测吗? 首先声明,我对Modbus不熟悉,尤其是如何实现它,最近才从网上下载了协议研究了一下,特此向高手请教。搞清楚这些问题,才能有效地在芯片中实现相应的功能,满足大家的需要。此帖的目的是继续另一帖的讨论:建议STM32的芯片加上串口超时功能, ...… 查看全部问答> |
|
在STM32的DS里面,管脚介绍的表格中Main function(after reset)一栏中,大部分的IO口都是如PA7样式的口 ...… 查看全部问答> |
|
我用CCS编程调试时,出现了“error: identifier \\"sinwt\\" is undefined”的错误信息,请请教一下是怎么回事?是不是需要加入某个头文件?还是我的写法有问题啊?谢谢大家~~~… 查看全部问答> |
|
在使用CCS的过程中,我发现在有关于有软件延时的程序中会出现问题,感觉延时没起到作用,比如一个简单的例子,让灯闪烁,使用delay函数(函数体内用两个for循环嵌套那种),这种延时就不会有效果,而用i=50000; while ...… 查看全部问答> |
|
全部代码都已测试通过,若发现有什么问题请和我联系。因为时间仓促,基本上都是一些硬件测试程序。记得要把例程和固件库放在同一目录下,全部工程共用一个库的。至于SD卡里的文件只是几个测试图片和音 ...… 查看全部问答> |
|
在EK-LM4F120XL Launchpad中, 我分别用 AIN0(PE3口)采样1.3V电压 AIN1(PE2口)采样0.65V电压, AIN8(PE5口)采样1.95V电压, AIN9(PE4口)采样2.6V电压, 假如以3.0V作为参考电压,那么在数据寄存器中采样结果应该是: 1775,对应1.3V电压 ...… 查看全部问答> |




