1,51学习就是配置特殊寄存器 po123 TCON TMOD SCON SBUF TH TL IE IP优先级 PSW累加器
    2,stm32芯片使用的是 100pin的 STM32F103VET6,芯片四周是引脚,左下角的小圆点表示1脚,然后从1脚起按照逆时针的顺序排列,所有芯片的引脚顺序都是逆时针排列的
    3,的STM32 芯片是已经封装好的成品,主要由内核和片上外设组成。若与电脑 类比,内核与外设就如同电脑上的 CPU与主板、内存、显卡、硬盘的关系,芯片和外设之间通过各种总线连接,其中驱动单元有 4 个,被动单元也有4 个
    image.png![KNDDJGL%[KKBWVF6W634U.png](https://cdn.nlark.com/yuque/0/2020/png/1510344/1592894744067-719f3d18-7105-477e-a14b-796af8212da9.png#align=left&display=inline&height=288&margin=%5Bobject%20Object%5D&name=KNDDJGL%25%5BKKBWVF6W634U.png&originHeight=536&originWidth=739&size=138049&status=done&style=none&width=397)
    4,ICode总线 :程序编译之后都是一条条指令,存 放在 FLASH 中,内核要读取这些指令来执行程序就必须通过 ICode总线,每时每刻都需要被使用
    5,驱动单元:DCode 总线,系统总线(访问外设),DMA 总线
    6,被动单元:内部的闪存存储器,内部的 SRAM,FSMC,AHB 到 APB 的桥
    7,存储器 映射:在51的时候,不同存储器有不同的地址,访问不同的地址有不同的语言,32比51好,被控单元的FLASH,RAM,FSMC和AHB到APB的桥(即片上外设), 这些功能部件从小到大共同排列在一个 4GB 的地址空间内,2的32次方正好4G,分为8个512M,
    8, 存储器的功能:从下到上8个512M
    image.png
    9,在这 8个 Block里面,有 3个非常重要。
    Block0 主要用于设计片内的 FLASH,我们使用的STM32F103ZET6的 FLASH 都是 512KB,属于大容量。
    Block1 用 于 设 计 片 内 的 SRAM 。STM32F103ZET6的 SRAM 都是 64KB。
    Block2 用于设计片内的外设,根据外设的总线速度不同,Block 被分成了 APB 和 AHB 两部分,其中 APB 又被分为 APB1 和 APB2
    10,寄存器映射 : 存储器Block2这块区域,设计的是片上外设,它们以四个字节为一个单元,共 32bit, 每一个单元对应不同的功能,控制这些单元时就可以驱动外设。我们找到每个单(寄存器),这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
    51纸只操作21个寄存器,32操作的寄存器上百上千,所以通过绝对地址访问内存单元不好记忆且容易出错,我们可以通过寄存器的方式来操作
    11,C语言对寄存器的封装 (重难点)
    封装总线和外设基地址:在编程上为了方便理解和记忆,我们把总线基地址和外设基地址都以相应的宏定义起 来,总线或者外设都以他们的名字作为宏名
    image.png
    代码定义了 “片上外设”基地址 PERIPH_BASE,接着在 PERIPH_BASE上加 入各个总线的地址偏移,得到 APB1、APB2 总线的地址 APB1PERIPH_BASE、 APB2PERIPH_BASE,在其之上加入外设地址的偏移,得到 GPIOA-G 的外设地址,最后在 外设地址上加入各寄存器的地址偏移,得到特定寄存器的地址。一旦有了具体地址,就可 以用指针读写;
    代码再使用 (unsigned int ) 把 GPIOB_BSRR 宏的数值强制转换成了地址,然后再用“” 号做取指针操作,对该地址的赋值,从而实现了写寄存器的功能。同样,读寄存器也是用 取指针操作,把寄存器中的数据取到变量里,从而获取 STM32 外设的状态
    image.png
    封装寄存器列表: GPIOA-GPIOE 都各有一组功能相同 的寄存器,如 GPIOA_ODR/GPIOB_ODR/GPIOC_ODR 等等,它们只是地址不一样,但却要为每个寄存器都定义它的地址。为了更方便地访问寄存器,我们引入 C 语言中的结构体 语法对寄存器进行封装。
    代码用 typedef 关键字声明了名为 GPIO_TypeDef的结构体类型,结构体内有 7个 成员变量,变量名正好对应寄存器的名字。C 语言的语法规定,结构体内变量的存储空间 是连续的,其中 32 位的变量占用 4个字节,16位的变量占用 2个字节,如:
    image.png
    代码用 typedef 关键字声明了名为 GPIO_TypeDef 的结构体,有 7 个 成员变量,变量名对应寄存器的名字。结构体内变量的存储空间是连续的,其中 32 位的变量占用 4 个字节,16 位的变量占用 2 个字节。这样地址偏移与 STM32 GPIO 外设定义的寄存器地址偏移对应,只要给结构体设置好首地址,就能把结构体内成员的地址确定下来,然后就能以结构体的形式访问寄存器。image.png
    代码先用 GPIO_TypeDef 类型定义一个结构体指针 GPIOx,并让指针指向地址 GPIOB_BASE(0x4001 0C00),使用地址确定下来,然后根据 C 语言访问结构体的语法,用 GPIOx->ODR 及 GPIOx->IDR 等方式读写寄存器。 最后,我们更进一步,直接使用宏定义好 GPIO_TypeDef 类型的指针,而且指针指向 各个 GPIO 端口的首地址,使用时我们直接用该宏访问寄存器即可。
    12,数组,结构体区别:数组(x,int)是同类型数据,结构体是各类数据都一样,但排列还是一样的
    13,存储器重映射:函数在映射f : A→B中,与A中的元素a对应的B中的元素b叫做a的象,a叫做b的原象,对应法则f;映射是“一对一”或“多对一”的对应关系,32中的“多对一”关系就是重映射。
    存储器本身并没有地址信息,它的地址是由芯片厂商分配好的,不可修改。给存储器编址的过程称为存储器地址映射。其中,映射到端口寄存器的存储器单元称为存储器映射寄存器,其地址称为存储器映射寄存器地址
    对应法则f是存储器映射寄存器地址,集合A是存储器,集合B是外设寄存器。所以它们构成的映射为:存储器映射寄存器地址:存储器存储单元→外设寄存器
    重映射就是CPU将外设寄存器重复编址到存储器的过程,也就是某一个外设寄存器在存储器里被映射了多个地址空间。
    14,寻址方式:外设基地址+偏移地址。0x40000000是分配给外设的第一个地址称外设基地址。工程师用结构体封装寄存器组,因为结构体成员的内存地址是连续的,只要知道首个结构体成员的地址和成员的数据类型就能找到对应的寄存器地址。具体还是得看函数调用。