存储器映射

  对于Cortex-M3来讲,有一块4G大小的存储器空间。存储器映射指的是芯片厂商为这个空间分配地址的操作。这4G空间被均匀地划分为8个大小为512MB的存储块(block),并且每个块都各具特色。下面主要介绍Block1~Block2。

Block0

  Block0的地址范围为0x0000_0000~0x1FFF_FFFF。它被设计用来存放代码程序,其中主要有FLASH、SYSTEM MEMORY和OPTION BYTES:

    FLASH:起始地址为0x0800_0000,存放用户程序和掉电保存数据。FLASH容量从16k到512k不等,以STM32F10x8系列为例,8代表FLASH容量为64k,所以结束地址就为0x0801_FFFF。

    SYSTEM MEMORY:系统存储器,存放了BootLoader程序,禁止用户改动,该程序主要用于串口下载。

    OPTION BYTES:选项字节,可以配置读写保护、看门狗等。

  这里简单说一下地址分配。整块4G存储器开始地址标为0x0000_0000,结束地址为0xFFFF_FFFF,地址表示采用了十六进制,一共8*4=32bit,而2^32刚好就是4G。存储器的基本单元是一个字节,每个地址都对应这样一个单元,因此用32位地址来表示,其容量刚好就是4GB。同理,根据Block0的起止地址,也可以计算得到其容量为512MB。

Block1

  Block1的地址范围为0x2000_0000~0x3FFF_FFFF。其中0x2000_0000~0x2000_FFFF被划为SRAM,主要是用于程序运行的堆栈开销。

Block2

  Block2的地址范围为0x4000_0000~0x5FFF_FFFF。这块空间被充分用作外设寄存器。根据总线不同,将外设分为三大块,第一块是APB1总线外设,起始地址为0x4000_0000;第二块是APB2总线外设,起始地址为0x4001_0000;最后一块为AHB总线外设,起始地址为0x4001_8000。

寄存器映射

  寄存器映射主要针对于Block2。这种映射不同于存储器映射的分配地址操作,而是在程序中对具有特定功能的内存单元进行命名的过程,每个内存单元都是四个字节,称作寄存器。例如GPIOA外设有个寄存器地址范围为0x4001_0800~0x4001_0803,该寄存器是用来配置GPIOA部分端口工作模式的,因此被映射为GPIOA_CRL。由此可知,这种映射方便了对寄存器的访问操作,因为如果每次访问寄存器都要查地址范围的话是很痛苦的。

GPIOA_CRL

  如何实现这种映射的呢?以GPIOA_CRL为例,其映射地址 = 外设总基地址(块基地址)+ 总线相对于外设总基地址的偏移 + 具体外设基地址相对于总线基地址的偏移 + 寄存器相对于具体外设基地址的偏移。

  外设总基地址恰好就是Block2的起始地址0x4000_0000;

  GPIO属于APB2总线外设,因此查阅芯片手册如下图所示,我们其实直接可以得到APB2起始地址和GPIOA的起始地址,但是程序中一般不这么做,而是以偏移量来表示层次关系。从图中可计算到总线相对于外设总基地址的偏移为0x1_0000,GPIOA相对于APB2基地址的偏移为0x800。

    

  再查阅GPIO的寄存器组,如下图所示。可以得到CRL寄存器相对于GPIO基地址偏移为0x00。综上GPIOA_CRL的基地址为:0x4000_0000+0x1_0000+0x800+0x00。

    

程序中地址映射

  STM32固件库中,有个头文件叫stm32f10x.h,其中就定义了寄存器的映射,部分代码如下:

  外设基地址PERIPH_BASE:

#define PERIPH_BASE           ((uint32_t)0x40000000)

  总线基地址,在外设基地址上加上偏移:

#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)

  

  GPIO外设基地址,在APB2总线基地址上加上偏移:

#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)

  定义GPIO外设结构体,因为结构体成员在内存中是连续的,这种形式与寄存器组非常类似,所以用结构体能够很好的管理寄存器:

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;

  定义GPIOA结构体指针,因为单单定义GPIO外设结构体,并不能确定其内存地址,因此用指针将其绑定到GPIOA外设基地址:

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)

  访问寄存器方式的对比,映射访问明显更为直观:

//直接的地址访问
*(unsigned int *)(0x4001_0800)|= 0x0001;
//映射访问
GPIOA->CRL |= 0x0001;

  

  

STM32存储器映射和寄存器映射的更多相关文章

  1. 单片机STM32学习笔记之寄存器映射详解

    我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射,那什么叫寄存器映射?寄存器到底是什么? 在存储器Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一 ...

  2. STM32片上Flash内存映射、页面大小、寄存器映射

    STM32片上Flash内存映射.页面大小.寄存器映射 STM32有4种Flash module organization,分别是:low-density devices(32KB,1KB/page) ...

  3. 转载-STM32片上FLASH内存映射、页面大小、寄存器映射

    原文地址:http://blog.chinaunix.net/uid-20617446-id-3847242.html 本文以STM32F103RBT6为例介绍了片上Flash(Embedded Fl ...

  4. 使用寄存器点亮LED(第2节)—寄存器映射代码讲解

    // 打开 GPIOB 端口的时钟 *( unsigned int * )0x40021018|= ( 1 << 4 ); // 配置PC2 IO口为通用推挽输出,速度为10M *( un ...

  5. [原创]基于Zynq PS与PL之间寄存器映射 Standalone & Linux 例程

    基于Zynq PS与PL之间寄存器映射 Standalone & Linux 例程 待添加完善中

  6. 【Mybatis高级映射】一对一映射、一对多映射、多对多映射

    前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...

  7. 使用CodeSmith快速生成映射文件和映射类

    一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法. CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来 ...

  8. Hibernate征途(七)之复合主键映射和集合映射

    把这两种映射放到一起说,是因为这两种映射不像前面的复用型映射.数量和方向型映射那么分类鲜明,所以放到了这个“其他”里面. 复合主键映射 在关系模型中,复合主键和其他的主键方式没有很大区别,但是反映到对 ...

  9. Hibernate征途(五)之继承映射和组件映射

    之所以把这两种映射放到一起说,是因为二者都是以复用为目的,减少了代码和配置量,这是相同点:二者之间的不同点类似继承和实现的区别:继承的类是一个事物的抽象,而实现的接口仅仅是功能的抽象. 继承映射 如上 ...

随机推荐

  1. Linux网络文件共享服务之NFS

    一.NFS服务简介 NFS全称network file system 网络文件系统,基于内核的文件系统,有sun公司开发,通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件,它基于r ...

  2. Java多线程,对锁机制的进一步分析

    1 可重入锁 可重入锁,也叫递归锁.它有两层含义,第一,当一个线程在外层函数得到可重入锁后,能直接递归地调用该函数,第二,同一线程在外层函数获得可重入锁后,内层函数可以直接获取该锁对应其它代码的控制权 ...

  3. ASP.NET Core下Ocelot的简单使用

    一.创建demo项目 1.新建webapi项目,命名为“DemoProject”,去掉HTTPS勾选 using Microsoft.AspNetCore.Mvc; using System.Coll ...

  4. springIOC源码接口分析(二):ConfigurableBeanFactory

    一 继承功能 1 SingletonBeanRegistry接口 此接口是针对Spring中的单例Bean设计的.提供了统一访问单例Bean的功能,类中定义了以下方法: 2 HierarchicalB ...

  5. C语言系列之实验楼笔记(一)

    创建C程序的几个过程: 1.编辑:创建和修改C程序的源代码 2.编译:编译器可以将源代码转成机器语言.linux 这些文件扩展名.o 3.链接:通过一次完成编译和链接 4.执行;运行程序 打开xfce ...

  6. 15、WAN

    WAN wide area network 覆盖较大地理范围的数据通信网络使用网络提供商和电信公司所提供的传输设施传输数据 通过不同WAN协议,将LAN延伸到远程站点的其他LAN广域网接入处于OSI七 ...

  7. QQ IP 地址查询相关

    1.QQwry.dat格式分析和查询IP位置的PHP程序 以前的追捕数据库太大,而且很久没有更新了. 所以我想到利用QQwry.dat这个文件查询IP所在位置,QQwry.dat 在很多地方都能找到, ...

  8. python strip()方法使用

    描述 python strip() ,用于去除述字符串头尾指定字符(默认为空格或换行符)或字符序列. 注意:此方法只能去除头尾的空格或是换行符,不能去除中间的. 语法: str.strip([char ...

  9. Codeforces_818

    A.winners总数为(k+1)diplomas. #include<bits/stdc++.h> using namespace std; long long n,k; int mai ...

  10. SpringBoot Jpa 分页查询最新配置方式

    这是已经被废弃的接口 Sort sort = new Sort(Sort.Direction.DESC,"bean类中字段"); //创建时间降序排序 Pageable pagea ...