欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

STM32学习笔记 —— 1.1 什么是寄存器(概念分析)

程序员文章站 2022-03-06 10:31:02
问题引入: 用一句话回答以下问题: 什么是寄存器? 什么是寄存器映射? 什么是存储器映射? (本章重点在 1.1.3 和 1.1.4) 1.1 STM32芯片实物图 (图) 1. 学会看丝印图 芯片型号、内核提供商等其他信息 2. 学会辨别正方向(芯片上的小圆点与PCB上的小圆点对应) 以小圆点为基 ......

问题引入:

用一句话回答以下问题:

  • 什么是寄存器?
  • 什么是寄存器映射?
  • 什么是存储器映射?

(本章重点在 1.1.3 和 1.1.4)

1.1 stm32芯片实物图

(图)

  1. 学会看丝印图
    • 芯片型号、内核提供商等其他信息
  2. 学会辨别正方向(芯片上的小圆点与pcb上的小圆点对应)
    • 以小圆点为基础,逆时针旋转,从1号引脚开始递增(图)
    • 如果芯片上没有小圆点,那么就把丝印图正对着自己,左上角的引脚为1号引脚,同样逆时针旋转递增。
    • 所有芯片的引脚排列都是逆时针的,无论是lqfp还是dip封装的。

1.2 stm32芯片架构简图

(图)

芯片主要是由内核和外设组成。

内核(主控制器):

  • cortex - m4内核(由arm公司设计)用于控制外设。

外设(从控制器):

  • flash、sram、usart、gpio、iic、spi等(由soc公司设计)

总线:

  1. 内核与外设通过总线连接,其分为:i(指令)、s(系统)、d(数据)总线。

  2. 几个总线同时访问某个外设或者内核,产生竞争的时候,总线矩阵会使用调度算法进行仲裁。

  3. stm32f42xx的总线接口

(图)

  • 黄色为主控制器,红色为从控制器。
  • 指令总线主要访问flash,程序可以从内置flash、外置flash和sram中启动。
  • 总线交叉处有圆点,说明可以连接,例如:程序只能存储在sram1中,不能存储在sram2中。
  • 数据总线主要用于取常量。常量的存储区域和程序的存储区域是一样的。
  • 系统总线主要访问sram和寄存器。

1.3 存储器映射

  1. 存储器本身是不具有地址信息的,地址信息是由用户或者厂商分配的,为存储器重新分配地址的过程即为存储器映射。

  2. cortex - m4内核是32位的,可以寻址2的32次方,也就是4gb(0x0000 0000 - 0xffff ffff)的内存空间,

  3. 这4gb的内存空间被分成了8个block,每个block都有特定的功能,每个block大小为512mb。(教程里有每个block的功能划分)

    • block0用于设计flash,429igt6只用了1mb。

    • block1用于设计sram,用于存储变量,429igt6用了256kb,被分成了三个部分:sram1为112kb,sram2为16kb,sram3为64kb。

    • block2用于设计片上外设。外设根据速度不同被分成四条总线进行控制:ahb1、ahb2、apb2、apb1。

      (图)

    • block3是fmc的bank1 - bank2,用于扩展外部存储,一个bank为256mb,板上拓展了一个大小为8mb的sram。

    • block4是fmc的bank3 - bank4

      • 四个bank通过一个片选信号控制四片拓展芯片 。
    • block5用于fmc
    • block6用于fmc
    • block7为cortex - m4的内部外设,是由arm公司设计的,如:nvic等。

  4. 通过地址和偏移量间接访寄存器。

1.4 寄存器映射

问题引入:

  • 如何通过控制寄存器的方法,让gpioh的16个引脚均输出高电平?

通过绝对地址访问内存单元:

//gpio端口全部输出高电平
*(unsigned int *)(0x40021c14) = 0xffff;
  1. 0x40021c14是输出数据寄存器ocr的地址,如何找到?

    1. 在《stm32中文参考手册》2.3.1 嵌入式sram这节中,可以查到gpioh外设的起始地址为0x4002 1c00。
    2. 在 7.4.6 gpio端口输出数据寄存器这节中,可以查到偏移地址为0x14。
  2. (unsigned int *)的作用是什么?

    • 0x4002 1c14是我们人为理解的地址,但是直接写在程序中,只是一串十六进制常量,需要将其强制类型转换为指针类型,才能使用间接访问运算符访问该地址内存的数据。

通过寄存器别名方式访问内存单元:

#define gpioh_odr *(unsigned int *)(0x40021c13)
gpioh_odr = 0xff;

什么是寄存器?

  • 给具有特定功能的内存单元取一个别名,这个别名就是寄存器,给已经分配好地址的特定内存单元取别名的过程叫做寄存器映射。

什么是存储器映射?

  • 给存储器分配地址的过程叫做存储器映射,再分配一个地址的过程叫做重映射。