• ARM开发初级-STM32F4寄存器-学习笔记03


    单片机的本质是在操作寄存器

    1. STM32的系统架构

    下图为stm32f4的总线矩阵(STM32F4x7-Datasheet的第19页),其中主控总线有8条,被控总线有7条,主设备和从设备通过各自的总线两两相交连接,图中两条总线相交且为圆圈的地方,表示这两条总线对应的主设备可以访问从设备,如I总线(指令总线),只有跟 M0、M2和M6这三根被控总线交叉的时候才有圆圈,就表示I总线只能跟这三根被控总线通信,这样就可以知道stm32f4的启动有三种分别是FLASH、内部SRAM、外部存储FSMC。

    总线矩阵用于主控总线之间的访问仲裁管理,仲裁采用循环调度算法。有了总线矩阵,就可以让主设备和从设备进行并行访问,提升了访问效率,同时也降低了功耗。需要注意的是,虽然总线矩阵使得多个主设备可以并行访问不同的从设备,但在一个定义的时间段内,只有一个主设备拥有总线矩阵的控制权,如果有多个主设备同时出现总线请求时就得进行仲裁。所以有了总线仲裁器,就能保证每个时刻只有一个主设备通过总线矩阵对从设备进行访问。

    注意并非所有主设备访问从设备都得经过总线矩阵,如上图中,有些主设备和从设备间有直通通道

    在这里插入图片描述

    1.1 八条主控总线

    • Cortex-M4F的三大总线
      • ICode总线(指令总线):ICode 中的 I 表示 Instruction,即指令。内核通过ICode 总线读取内部FLASH代码指令来执行程序。此总线访问的对象是包含代码的存储器(内部 Flash/SRAM 或通过 FSMC 的外部存储器)。
      • DCode(数据总线):DCode 中的 D 表示 Data,即数据,那说明这条总线是用来取数的。因为数据可以被 Dcode 总线和 DMA 总线访问,所以为了避免访问冲突,在取数的时候需要经过一个总线矩阵来仲裁,决定哪个总线在取数,取到的数据可以暂存在Cortex-M4内核里面的寄存器在进行处理。
        此总线用于将 Cortex-M4F 数据总线和 64 KB CCM 数据 RAM 连接到总线矩阵。内核通过此总线进行立即数加载和调试访问。此总线访问的对象是包含代码或数据的存储器(内部Flash 或通过 FSMC 的外部存储器)
      • System(系统总线):此总线用于将 Cortex-M4F 内核的系统总线连接到总线矩阵。此总线用于访问位于外设 或 SRAM 中的数据。也可通过此总线获取指令(效率低于 ICode)。此总线访问的对象是 112 KB 和 16 KB 的内部 SRAM、包括 APB 外设在内的 AHB1 外设、AHB2 外设以 及通过 FSMC 的外部存储器。
    • DMA总线
      • DMA1存储器总线:此总线用于将 DMA 存储器总线主接口连接到总线矩阵。DMA 通过此总线来执行存储器数据的传入和传出。此总线访问的对象是数据存储器:内部 SRAM(112 KB和16 KB) 以及通过 FSMC 的外部存储器
      • DMA2存储器总线
      • DMA2外设总线:此总线用于将 DMA 外设主总线接口连接到总线矩阵。DMA 通过此总线访问 AHB 外设或执行存储器间的数据传输。此总线访问的对象是 AHB 和 APB 外设以及数据存储器:内部 SRAM 以及通过 FSMC 的外部存储器。
    • 以太网总线:此总线用于将以太网 DMA 主接口连接到总线矩阵。以太网 DMA 通过此总线向存储器存取 数据。此总线访问的对象是数据存储器:内部 SRAM(112 KB 和 16 KB)以及通过 FSMC 的外部存储器。
    • USB OTG HS总线:此总线用于将 USB OTG HS DMA 主接口连接到总线矩阵。USB OTG DMA 通过此总线向存储 器加载/存储数据。此总线访问的对象是数据存储器:内部 SRAM(112 KB 和 16 KB) 以及通过 FSMC 的外部存储器。

    1.2 七条被控总线

    • 内部 Flash ICode 总线
      Flash:写好的程序编译之后都是一条条指令(二进制代码)和常量或常变量存放在FLASH

    • 内部 Flash DCode 总线

    • 主要内部 SRAM1 (112 KB)
      内部SRAM:常说的电脑内存条,程序函数内部的局部变量和全局变量,堆(malloc分配)栈(局部变量)等的开销都是基于内部的SRAM。内核通过 DCode 总线来访问它

    • 辅助内部 SRAM2 (16 KB)

    • AHB1 外设(包括 AHB-APB 总线桥和 APB 外设)
      两个AHB/APB桥在AHB和2个APB总线间提供同步连接。APB1操作速度限于42MHz,APB2操作于全速(最高84MHz),上面挂载着 STM32 各种各样的特色外设。我们经常说的 GPIO、串口、I2C、SPI 这些外设就挂载在这两条总线上,这个是我们学习 STM32 的重点,就是要学会编程这些外设去驱动外部的各种设备。

    • AHB2 外设

    • FSMC(Flexible static memory controller)
      FSMC是灵活的静的存储器控制器,通过FSMC我们可以扩展内存,如外部的SRAM,NANDFLASH 和 NORFLASH。但有一点要注意的是,FSMC 只能扩展静态的内存,即名称里面的 S:static,不能是动态的内存,比如 SDRAM 就不能扩展。

    1.3 高速总线

    在这里插入图片描述
    1、ICode、DCode、System
    2、FLASH连接总线
    3、SRAM 连接总线
    4、高速外设连接总线 AHB1/AHB2/AHB3
    5、连接“桥”的总线
    这些“高速总线”直接与“总线矩阵”连接在一起,其实这些高速总线实际上就是“总线矩阵”的延伸,或者说就是总线矩阵的一部分。

    1.4 高速外设与低速外设

    我们这里说“片内外设”时,暂都不包含 ROM(FLASH)和 SRAM。

    • 高速外设
      由于高速外设实在是太多了,一个总线不够,所以分了三个,分别是 AHB1/AHB2/AHB3,所有“高速外设”寄存器组分批挂接在 AHB1/AHB2/AHB3 上。

    • 低速外设
      “低速外设”的速度比较低,不能直接挂在“总线矩阵”上,所以先经过“桥”后再引出“低速总线”,挂在低速总线上。由于“低速外设”比较多,所以就分了两个低速总线,分别是 APB1/APB2,所有的“低速外
      设”分批挂接在 APB1/APB2 上。

    2. Cortex-M4存储空间

    芯片内CPU的地址总线决定芯片能访问的存储空间大小,Cortex-M4的地址总线32根

    • 32根地址线的理论空间是4GB
      • 1根地址线:可传输的地址为0和1,理论上可以访问2个字节

      • 2根地址线:可以传输地址为 00、01、10、11,理论上可以访问 4 个字节

      • 3 个地址线:可以传输的地址为 000、001、010、011、100、101、110、111,理论上可以访问 8 个字节。

      • 32 根地址线:可以产生 00000000 00000000 00000000 00000000、…、11111111 11111111 11111111 11111111的 232个地址,范围刚好为 4G,所以我们就说Cortex-M4的32 根地址线,理论上可以访问4G字节的存储器空间。Cortex-M4地址是从0x0000 0000到0xFFFF FFFF,这就是4GB的存储空间。
        32根地址线可以传输4G个地址信号,每个地址信号访问一个字节,4G地址信号则可以访问4G个字节,所以理论上的可访问范围为4G

      • 插入一个64位系统的小知识
        64位系统使用64位地址线的最大寻址空间为2的64次方bytes,计算后其可寻址空间达到了18446744073709551616 Bytes,即16384PB(PebiByte)或16777216TB(TebiByte)。但是,很多64位CPU使用40位地址线,最大寻址空间仅为1TB,加之别的种种原因,目前Windows 7 64位版最大仅能使用192GB内存,Windows 8 64位版最大仅能使用512GB内存。不过尽管系统所能支持的内存有这么大,但主板和CPU的限制导致一般的电脑所支持的内存最大只有16GB而已。

    • Cortex-M4的实际空间
      STM32理论上有4G的存储空间,但实际上没有这么大。在Cortex-M4中有很多空间是被保留,也就是在实际上没有用到这么多空间。
    • STM32的32的真实意思
      STM32不是指32根地址线,而是指CPU在处理数据时,每次可以处理的数据位宽是32个bit,也正是这个原因,STM32内部的寄存器大小都是32位,刚好等于位宽。

    3. 存储器映射

    3.1 Cortex-M4存储器映射

    被控单元的FLASH,RAM和各类片上外设,这些功能部件共同排列在一个 4GB 的地址空间内,每个外设都有自己独有地址。我们在编程的时候,可以通过他们的地址找到他们,然后来操作他们
    存储器本身没有地址,给存储器分配地址的过程叫存储器映射
    在这里插入图片描述

    3.2 STM32F407存储器映射

    STM32F407细分了Cortex-M4存储器映射,具体如下面两张图所示
    在这里插入图片描述
    下图是STM32F4x7-Datasheet的第54页
    在这里插入图片描述
    在 block 0 中我们看到除了Flash用来存储代码以外还有很多别的东西,比如Boot pins用来控制开机、System memory等。
    在 block 1 中我们 512MB 的 SRAM 其实真正使用的也只有 128KB。
    在 block 2 中是外设,也是我们最需要深入学习的部分之一,起始地址是 0x4000 0000。细看我们没有找到具体外设,看到的却是APB1、APB2、AHB1、AHB2、AHB3等。这是因为外设实在太多了,我们需要根据不同需求进行分装,具体的内容可以看下图(STM32F4x7-Datasheet的第16页)
    在这里插入图片描述

    3.3 访问寄存器

    在存储器 block 2 这块区域,也就是地址从0x4000 000—0x5FFF FFF这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。可以找到每个单元的起始地址,然后通过C语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
    在这里插入图片描述

    • 访问方法1
      在这里插入图片描述

    • 访问方法2
      我们访问GPIOA的控制寄存器组时、直接使用宏定义好 GPIO_TypeDef 类型的指针,而且指针指向 GPIOA端口的首地址,这样我们直接用宏GPIOA访问改外设的任意一个寄存器。(stm32f407xx.h”已经封装了所有的外设)

      typedef struct {
      uint32_t		MODER;      /*Address offset: 0x00 */
      uint32_t		OTYPER; 	/*Address offset: 0x04 */
      uint32_t		OSPEEDR; 	/*Address offset: 0x08 */
      uint32_t		PUPDR;	 	/*Address offset: 0x0C */
      uint32_t		IDR; 		/*Address offset: 0x10 */
      uint32_t		ODR; 		/*Address offset: 0x14 */
      uint32_t		BSRR; 		/*Address offset: 0x18 */
      uint32_t		LCKR; 		/*Address offset: 0x1C */
      } GPIO_TypeDef;
      
      #define     GPIOA_BASE        ( (unsigned int ) 0x40020000 )
      #define     GPIOA	 ((GPIO_TypeDef *) GPIOA_BASE)
      
      GPIOA->MODER = 0x20 ; 
      GPIOA->OSPEEDR = 0x16 ;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    4. 参考

    1. 干货|STM32寄存器版的基础知识—内存映射
    2. STM32新手入门-什么是寄存器
    3. STM32F4x7-Datasheet
    4. STM32F4xx中文参考手册
  • 相关阅读:
    如何使用 LeiaPix 让照片动起来
    22-08-12 西安 尚医通(05) JWT令牌、阿里云发送短信验证码
    Vue拖拽文件进行上传
    品牌发力 · 韧性增长 | 数说故事亮相第30届中国国际广告节
    【mycat】mycat水平分表
    nacos2.1.1集群部署
    《动手学深度学习 Pytorch版》 10.5 多头注意力
    贷款问题——C语言
    OpenCoord框架转换使用的问题
    英语语法基础
  • 原文地址:https://blog.csdn.net/baidu_41924187/article/details/125910339