欢迎来到矽芯硬翌的科技主义教室!
Ps:记录STM32入土路上的艰苦旅程,加油UPUPUP!
文章目录
前言
已经学习过一边STM32,但没有系统的记录下来,导致很多东西都是只知道名字但不了解具体是什么原理。借用这个暑假在详细记录一下STM32的入土实况!!加油以下是记录一些寄存器的相关知识内容,下面案例可供参考
一、寄存器是什么?
学过数电、模电,汇编的同学都对寄存器这个名词不陌生,但它到底是个什么样的东西呢?先借用一下百度词条:
(来自百度百科):存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。
到底该如何给更好的理解STM32中的寄存器呢?通过本次的介绍应该会有足够的了解!
二、STM32内部世界
1.STM32神秘样貌
本次包括以后使用和介绍的都是芯片为:STM32F103ZET6的开发板。先看一张正面的引脚图。
芯片正面是丝印, ARM 应该是表示该芯片使用的是 ARM 的内核, STM32F103ZET6是芯片型号,后面的字应该是跟生产批次相关,最上面的是 ST 的 LOGO。芯片四周是引脚,左下角的小圆点表示 1 脚,然后从 1 脚起按照逆时针的顺序排列(所有芯片的引脚顺序都是逆时针排列的)。开发板中把芯片的引脚引出来,连接到各种传感器上,然后在STM32 上编程(实际就是通过程序控制这些引脚输出高电平或者低电平)来控制各种传感器工作,通过做实验的方式来学习 STM32 芯片的各个资源。
1.1 芯片内有什么?
平常看到的 STM32 芯片是已经封装好的成品,主要由内核和片上外设组成。若与电脑类比,内核与外设就如同电脑上的 CPU 与主板、内存、显卡、硬盘的关系。
STM32F103 采用的是 Cortex-M3 内核,内核即 CPU,由 ARM 公司设计。 ARM 公司并不生产芯片,而是出售其芯片技术授权。芯片生产厂商(SOC)如 ST、 TI、 Freescale,负责在内核之外设计部件并生产整个芯片,这些内核之外的部件被称为核外外设或片上外设。如 GPIO、 USART(串口)、 I2C、 SPI 等都叫做片上外设。具体参照下图。
芯片和外设之间是通过各种总线链接的,其中驱动单元有四个,被动单元也有四个。简单的说驱动单元可以理解为CPU内部组成部分,被动单元可以理解为外设。接下来简单介绍一下各个部件。
- IClode总线
编写好的程序通过编译之后都是一条条的指令,这些指令存储在单片机的FLASH中的,STM32内核想要读取这些指令来执行程序就必须通过IClode总线,这个I的意思就是Instruction,即指令的意思。 - 驱动单元(简单理解为CPU内部组成部件)
- DCode总线。D表示的是data(数据),这条总线的目的是读取数据。对于STM32来说,用const关键字修饰的数据(常量)是保存在内部FLASH内的,全局or局部数据(变量)都放在内部的SRAM中。
- DMA总线。DMA总线主要也是用来传输数据的,这个数据可以来自外设寄存器、内部FALSH,内部SRAM。当数据同时被Dcode总线和DMA总线访问时,可以通过总线矩阵仲裁避免冲突。
- 系统总线。该总线主要用来访问外设寄存器,寄存器变成都是通过读写这跟总线完成。
- 被动单元
- 内部的闪存存储器,即FLASH。编写的程序存储在这个地方,内核通过ICode总线读取指令。
- 内部SRAM,即RAM(变量存储区),堆栈等的都是存在于此,内核通过DCode总线访问。
- FSMC,即静态存储器控制器。STM32F10xx中的一个特色外设,可用于扩展内存。
- AHB到APB桥,APB1、APB2是从AHB总线上延伸出来的,上面挂载着STM32各种各样的特色外设。常用的GPIO、串口、I2C、SPI这些外设就挂载在这两条总线上。
下面是整个系统框图:
被控单元的 FLASH, RAM, FSMC 和 AHB 到 APB 的桥(即片上外设),这些功能部件共同排列在一个 4GB 的地址空间内。在编程时,可以通过 C 语言对它们进行数据的读和写。
2.存储器映射
含义:芯片厂商给存储器分配地址的过程就称为存储器映射,如果给存储器再分配一个地址就叫存储器重映射。
下图为官方寄存器映射图:
2.1 存储器区域功能划分
在这 4GB 的地址空间中, ARM 已经平均分成了 8 个块,每块 512MB,每个块也都规定了用途。
下图为存储器功能分类图:
在这8 个 Block 里面,最关心的有三块:Block0、Block1、Block2。 Block0 用来设计成内部 FLASH, Block1 用来设计成内部 RAM, Block2 用来设计成片上的外设。
- 存储器 Block0 内部区域功能划分
- 储存器 Block1 内部区域功能划分
- 储存器 Block2 内部区域功能划分
2.2 寄存器映射
最开始的时候有一个问题,什么是寄存器?现在可以给出一个很好的解答,在存储器Block2这块区域设计上是片上外设,这其中有很多地址单元,这些地址单元可以通过C语言指针的方式来访问。但是这些地址单元比较复杂难记,使用时也比较容易出现错误,为了方便记忆给这些地址单元取一个名称,这个名称就是所谓的寄存器。比如GOPIX端口的输出数据寄存器的地址为0X40010C0C,给这个寄存器起的名称就为ODR,之后见到的多数这样的名称就可以很好的理解为是一个寄存器,而不被为一大堆的英文吓跑。
之前已经解释过映射的含义,那什么是寄存器映射呢?给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
以下是一个映射过程:
// GPIOB 端口全部输出 高电平
2 #define GPIOB_ODR *(unsigned int*)(GPIOB_BASE+0x0C)
3 GPIOB_ODR = 0xFF; //代码不过多解释
2.3 STM32外设地址映射
APB1总线的地址最低,也叫做外设基地址
对于GPIO来说属于高速外设,挂接在APB2总线上。
记下来就是关于寄存器的映射了,STM32的GPIO中有很多的寄存器,每一个寄存器都有自己相应的地址。
以GPIOB为例:
3.修改寄存器的位操作
C语言的位操作:
1.变量某位赋值与连续赋值:寄存器 |= 值
//例如:a = 1000 0011b
a |= (1<<2) //a = 1000 0111 b 单独赋值
a |= (3<<2*2) // 1011 0011b 连续赋值
2.变量某位清零与连续清零:寄存器 &= ~() 值
//例子:a = 1001 1111
a = &= ~(1<<2)
//结果 a = 1001 1011
a &= ~(3<<2*1);
//结果a = 1001 0011
3.变量某位取反:寄存器 ^= 值
(异或操作)
//例子:a = 1001 0011b
a ^= (1<<6);
//结果:a = 1101 0011b
总结
这里对文章进行总结:
主要了解学习了STM32的内部结构和存储器、寄存器是什么,存储器和寄存器映射以及一些C语言的移位操作,这些对将来的变成和理解打下了坚实的基础。