[信息] STM32F429内核与存储器映射

[复制链接]
753|5
 楼主| 火星国务卿 发表于 2021-4-23 13:59 | 显示全部楼层 |阅读模式

        一、STM32 芯片架构简图

        pIYBAF_8CNWAIsD2AAD81K-Bsec767.png

        STM32 有三种启动方式,从 FLASH 启动(包含系统存储器),从内部 SRAM 启动,从外部 RAM 启动。

        二、存储器映射

        存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射,具体见下图。 如果给存储器再分配一个地址就叫存储器重映射。

        o4YBAF_8COiAGVacAAJupcyfxC4639.png

        在这 4GB 的地址空间中, ARM 已经粗线条的平均分成了 8 个块,每块 512MB,每个块也都规定了用途,具体分类见下表。每个块的大小都有 512MB,显然这是非常大的,芯片厂商在每个块的范围内设计各具特色的外设时并不一定都用得完,都是只用了其中的一部分而已。

        o4YBAF_8CPSAYeZ4AANGJyfaroI586.png

        在这 8 个 Block 里面,有 3 个块非常重要,也是我们最关心的三个块。 Boock0 用来设计成内部 FLASH, Block1 用来设计成内部 RAM, Block2 用来设计成片上的外设,下面我们简单的介绍下这三个 Block 里面的具体区域的功能划分。

        1、存储器 Block0 内部区域功能划分

        Block0 主要用于设计片内的 FLASH, F429 系列片内部 FLASH 最大是 2MB,STM32F429IGT6 的 FLASH 是 1MB。

        o4YBAF_8CQiABppyAALzpVs5HGI558.png

        2、储存器 Block1 内部区域功能划分

        Block1 用于设计片内的 SRAM。 F429 内部 SRAM 的大小为 256KB,其中 64KB 的CCM RAM 位于 Block0,剩下的 192KB 位于 Block1,分 SRAM1 112KB, SRAM2 16KB,SRAM3 64KB, Block 内部区域的功能划分具体见下表。

        pIYBAF_8CRWANXA7AAGswKV4TTw737.png

        3、储存器 Block2 内部区域功能划分

        Block2 用于设计片内的外设,根据外设的总线速度不同, Block 被分成了 APB 和 AHB两部分,其中 APB 又被分为 APB1 和 APB2, AHB 分为 AHB1 和 AHB2,具体见下表。还有一个 AHB3 包含了 Block3/4/5/6,这四个 Block 用于扩展外部存储器,如 SDRAM,NORFLASH 和 NANDFLASH 等。

        o4YBAF_8CSaAfWNyAALLiK80tS8740.png

        三、寄存器映射

        根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。

        1、STM32 的外设地址映射

        片上外设区分为四条总线,根据外设速度的不同,不同总线挂载着不同的外设, APB挂载低速外设, AHB 挂载高速外设。相应总线的最低地址我们称为该总线的基地址,总线基地址也是挂载在该总线上的首个外设的地址。其中 APB1 总线的地址最低,片上外设从这里开始,也叫外设基地址。

        (1)总线基地址

        pIYBAF_8CT2AYdoJAAGWql943Bo135.png

        (2)外设基地址

        总线上挂载着各种外设,这些外设也有自己的地址范围,特定外设的首个地址称为“ XX 外设基地址”,也叫 XX 外设的边界地址。

        o4YBAF_8CVKAPe8JAAJLt8dLXFY615.png

        (3)外设寄存器

        GPIO 有很多个寄存器,每一个都有特定的功能。每个寄存器为 32bit,占四个字节,在该外设的基地址上按照顺序排列,寄存器的位置都以相对该外设基地址的偏移地址来描述。

        pIYBAF_8CWWAHrAXAALI06AZE2U832.png

        2、C 语言对寄存器的封装
        (1)封装总线和外设基地址

        为了方便理解和**,我们把总线基地址和外设基地址都以相应的宏定义起来,总线或者外设都以他们的名字作为宏名。

        o4YBAF_8CXKAG7trAAN9CGLGI9w755.png

        (2)封装寄存器列表

        GPIOA-GPIOH 都各有一组功能相同的寄存器,如 GPIOA_MODER/GPIOB_MODER/GPIOC_MODER 等等,它们只是地址不一样,但却要为每个寄存器都定义它的地址。为了更方便地访问寄存器,我们引入 C 语言中的结构体语法对寄存器进行封装。

        o4YBAF_8CY6AM5VeAARFgpdwbFA131.png

        o4YBAF_8CZyAQAQjAAFMjszMBZE524.png

        这样的地址偏移与 STM32 GPIO 外设定义的寄存器地址偏移一一对应,只要给结构体设置好首地址,就能把结构体内成员的地址确定下来,然后就能以结构体的形式访问寄存器了。

        o4YBAF_8CayACObHAAH_50M1FCY525.png

        3、修改寄存器的位操作方法

        用 C 语言对寄存器赋值时,我们常常要求只修改该寄存器的某几位的值,且其它的寄存器位不变,这个时候我们就需要用到 C 语言的位操作方法了。

        (1)把变量的某位清零

        此处我们以变量 a 代表寄存器,并假设寄存器中本来已有数值,此时我们需要把变量a 的某一位清零,且其它位不变。

        pIYBAF_8Cb2AVuQfAAHcqzK-dtc757.png

        (2)把变量的某几个连续位清零

        由于寄存器中有时会有连续几个寄存器位用于控制某个功能,现假设我们需要把寄存器的某几个连续位清零,且其它位不变。

        pIYBAF_8CdGAOg7NAAP1OzS-pKw932.png

        (3)对变量的某几位进行赋值

        寄存器位经过上面的清零操作后,接下来就可以方便地对某几位写入所需要的数值了,且其它位不变,这时候写入的数值一般就是需要设置寄存器的位参数。

        o4YBAF_8Cd6AJLfJAAC6m2puROw295.png

        (4)对变量的某位取反

        某些情况下,我们需要对寄存器的某个位进行取反操作,即 1 变 0 , 0 变 1,这可以直接用如下操作,其它位不变。

        pIYBAF_8CjiAM9OMAABY_vLiBfk720.png
       
tfqi 发表于 2021-5-11 10:34 | 显示全部楼层
总是理解不到点上去
zljiu 发表于 2021-5-11 10:34 | 显示全部楼层
光是真么看 没有什么效果
coshi 发表于 2021-5-11 10:34 | 显示全部楼层
非常感谢楼主的介绍
wiba 发表于 2021-5-11 10:37 | 显示全部楼层
这个是什么总线结构啊
aoyi 发表于 2021-5-11 10:37 | 显示全部楼层
如何确定这三种启动方式呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

683

主题

1544

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部