STM32的寻址范围
存储器映射
存储器指的是额可以存储数据的设备(FLASH SRAM) 本身没有地址信息 对存储器分配地址的过程称为存储器映射
如星忆公司生产的芯片(可以理解为是SRAM的升级)
19根地址线 就是2的19次方个可以访问的地址
16根数据线 每个地址可以写入两个字节 总共芯片的容量就是 1mb
存储器映射
存储器功能划分 (F1芯片为例)
第一个Block 0 存放着代码 也就是FLASH (ROM) FLASH就是一个存储器 映射到Block 0 (这个地址模块上)
其实学习stm32就是学习外设 主要是前三个地址模块 Block 0 1 2
每个划分的模块地址大小都为 512MB
Block 0 范围为512mb
寄存器映射
寄存器是单片机内部一种特殊的内存(可以存放数据)可以实现对单片机各个功能的控制 简单来说
寄存器就是单片机内部的控制结构
STM32寄存器分类
内核就是M3/4/7之类的 最主要还是学习外设的寄存器
寄存器映射 (F1系列为例)
寄存器是特殊的存储器 ,给寄存器地址命名的过程就叫寄存器映射
生活中的例子
如51单片机是8位 i/o口就是P1.0一直命名到P1.1 而STM32单片机有十六位 如一个GPIO端口GPIOA 就可命名为PA0 PA1 一直命名到PA15
这个内存是用来控制外设GPIO的 命名为GPIO (寄存器的映射) 有GPIOA_ODR GPIOB_ODR 等 偏移量 如GPIOA_ODR的第一位地址是0x4001 0800 以寄存器GPIOA_ODR为单位 一次偏移就地址加0Ch 其他详细内容将会在GPIO视频讲解
如直接操作寄存器地址 把一个地址强转换为指针类型 转化为unsigned int *型的指针 然后最外面的是对这个指针直接取值 对值进行操作 把这个地址赋值为0xFFFF(4个字节 32位)
定义了寄存器名字(寄存器映射) 再操作
寄存器地址的计算
1.总线基地址
GPIO外设基地址即偏移量
外设和寄存器的关系:总结来说,就是插上外设后,cpu就可以检测和连接到外设上的寄存器,把它当成内存来使用,然后就是对这些寄存器进行读写,写控制寄存器来控制外设,读状态寄存器来检测外设状态(外设会把当前状态信息放到指定寄存器上),通过读写数据寄存器来交换数据。
一根总线上挂载着许多外设 寄存器在外设的内部 通过读写寄存器从而控制外设的状态
要找到寄存器 首先找到寄存器挂载的总线 (总线基地址) 然后看外设对于总线基地址的偏移量(外设基于总线基地址的偏移量) 再对于单独的外设 (外设基地址) 看寄存器对于外设基地址的偏移量 (寄存器相对外设基地址的偏移量) 从而找到寄存器
寄存器地址计算过程
对寄存器的更好的映射方法
使用结构体,可以很方便的完成对寄存器的映射
如何理解 GPIO_BASE存放的就是GPIOA 中第一个寄存器GPIOA_CRL (四个字节 一个寄存器就是四个字节) 的地址 #define GPIOA 后面的意思是把这个地址转化为一个指针 这个指针访问的是GPIO_TypeDef 类型的数据 (如 int* p p=&a 就是p是一个地址 电脑要通过这个地址访问数据类型为int的数据)但是我们要访问GPIOA这个寄存器 一共是28个字节 没有数据类型为28个字节的名字 所以我们就定义了一个结构体结构体的数据类型是由里面的成员决定的 定义了结构体 GPIOA_Typeef 里面都是unsigned int类类型的数据(使用了sbit 命名成了uint32_t)一共七个 一共28个字节 所以
#define GPIOA ((GPIO_TypeDef*)GPIO_BASE)意思是 通过GPIO_BASE这个地址访问 数据 这个数据是我们自己定义的28个字节的数据类型数据
(GPIO_TypeDef*)GPIO_BASE就是个指针 然后我们给这个指针取了个名字叫GPIOA
然后可以通过GPIOA 访问GPIOA里面7个寄存器 如(&GPIOA→ODR就是GPIOA中第四个寄存器的地址) GPIOA→ODR=0XFFFF就是将值0xFFFF写入这个寄存器中
然后这个就是 这个引用了这个指针的值
总结