STM32F103系列芯片是一款广泛应用于嵌入式系统开发的微控制器。了解其地址映射和寄存器映射原理,以及GPIO端口的初始化基本步骤,对于理解该系列芯片的工作原理和编程开发具有重要意义。在本文中,我们将详细讲解STM32F103系列芯片的地址映射和寄存器映射原理,并介绍GPIO端口初始化的基本步骤,帮助读者更好地掌握这一领域的知识。
文章目录
一、STM32F103芯片的地址映射和寄存器映射原理
1、寄存器
听到寄存器,你是否明白,什么是寄存器?寄存器的作用是什么?为什么要有寄存器?
这三连问是否把你难住了呢? ╭(#°Д°)╮
我来为你解答一下
-
寄存器是计算机中用于存储和处理数据的一种高速存储器。它位于CPU内部,与其他存储器(如内存)相比,寄存器的容量较小,但速度更快。
-
寄存器的作用是暂时存储CPU需要处理的数据和指令。它可以存储临时变量、计算结果、地址等信息。寄存器的读写速度非常快,CPU可以直接从寄存器中读取数据,而不需要访问其他存储器,这样可以大大提高计算机的运行速度。
-
寄存器的存在是为了提高计算机的执行效率。由于寄存器位于CPU内部,与CPU的工作速度相匹配,因此可以更快地访问和处理数据。寄存器的容量较小,可以存储的数据量有限,但是它的快速读写能力使得CPU能够更高效地执行指令,提高计算机的整体性能。
现在应该明白一点了吧!!!
接下来我们来了解一下寄存器的分类
基本寄存器 基本寄存器只能并行送入数据,也只能并行输出。
移位寄存器 移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入、并行输出,也可以串行输入、串行输出,还可以并行输入、串行输出,或串行输入、并行输出,十分灵活,用途也很广
2、地址映射和寄存器映射原理
为了方便你的理解,我接下来将利用图文一起说明
我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射,那什么叫寄存器映射?寄存器到底是什么?
说到映射大家可能就会想到函数映射,脑海里会有一个画面:左边一个集合中的某个元素“射”出一条带箭头的直线指向右边的集合的某个元素。其实外围设备的内存映射原理是一样的,只不过左边的集体变成了CPU,右边的集合变成了外围设备,那条带箭头的线就是连接CP和外设地址引脚的地址总线。存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射,也就是如下的图。
想必你现在你该理解大致的映射原理了吧! ๑ ͡° ͜ ͡° ๑
接下来,就是详细的讲解
地址映射:由百度词条可知为了保证CPU执行指令时可正确访问存储单元,需将用户程序中的逻辑地址转换为运行时由机器直接寻址的物理地址,这一过程称为地址映射。
寄存器映射:在存储器的区域单元中,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
二、GPIO端口的初始化基本步骤
1、GPIO的自我介绍
我的名字叫 GPIO(英语:General-purpose input/output),通用型之输入输出的简称,我的功能类似8051的P0—P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。
2、时钟介绍
-
概述
时钟是单片机的脉搏,是单片机的驱动源,使用任何一个外设都必须打开相应的时钟。这样的好处是,如果不使用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果。每个时钟tick,系统都会处理一步数据,这样才能让工作不出现紊乱。
-
原理
首先,任何外设都需要时钟,51单片机,STM32,430等等,因为寄存器是由D触发器组成的,往触发器里面写东西,前提条件是有时钟输入。 -
stm32与51单片机时钟比较
51单片机不需要配置时钟,是因为一个时钟开了之后所有的功能都可以用了,而这个时钟是默认开启的,比如有一个水库,水库有很多个门,这些门默认是开启的,所以每个门都会出水,我们需要哪个门的水的时候可以直接用,但是也存在一个问题,其他没用到的门也在出水,即也在耗能。这里水库可以认为是能源,门可以认为是每个外设的使用状态,时钟可以认为是门的开关。
3、输入输出模式设置
GPIO有四种输入模式和四种输出模式,共八种模式。
输入模式:
-
浮空输入(GPIO_Mode_IN_FLOATING):什么电阻都不接,由施密特触发器输入,输入阻抗大,为一个不确定的值。
-
上拉输入(GPIO_Mode_IPU ):输入数字信号1
-
下拉输入(GPIO_Mode_IPD):输入数字信号0
-
模拟输入(GPIO_Mode_AIN):用于ADC外设的输入
输出模式;
- 开漏输出(GPIO_Mode_Out_OD):输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
- 推挽输出(GPIO_Mode_Out_PP):推挽电路是两个参数相同的三极管或 MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。
- 复用开漏输出(GPIO_Mode_AF_OD)
- 复用推挽输出(GPIO_Mode_AF_PP)
GPIO内部工作图:
输入讲解:
-
浮空输入:此时的VDD和VSS 所在的路径的两个开关都是断开的状态,此时IO口的电平状态是不确定的,由外部输入决定。
-
上拉输入:此时IO口默认是高电平
-
下拉输入:此时IO口默认是低电平
-
模拟输入:此时的信号不经过TTL施密特触发器,直接进入ADC模块,CPU不能直接读取寄存器上的引脚状态。
输出讲解:
-
开漏输出:此时只有N-MOS工作,而P-MOS不工作。当我们控制输出为0时,N-MOS管导通,使其IO口输出低电平。当我们控制输出为1时,此时N-MOS截止。输出指令就不会起到作用而是由I/O端口外部的上拉或者下拉决定,如果没有上拉或者下拉 IO口就处于悬空状态。
-
推挽输出:此时,N-MOS管和P-MOS管都工作,如果控制输出为0,则P-MOS管截止,N-MOS管导通,若控制输出为1,则P-MOS管导通N-MOS管截止。
-
复用开漏输出:即在开漏输出的基础上向复用功能输出端输出。
-
复用推挽输出:即在推挽输出的基础上向复用功能输出端输出。
4、最大速率设置
当STM32的GPIO端口设置为输出形式时,有三种速度能够挑选:2MHz、10MHz和50MHz,这个速度是指I/O口驱动电路的速度,是用来挑选不同的输出驱动模块,到达最佳的噪声控制和降低功耗的意图。
高频的驱动电路,噪声也高,当你不需求高的输出频率时,请选用低频驱动电路,这样十分有利于进步体系的EMI功能。
当然假设你要输出较高频率的信号,但却选用了较低频率的驱动模块,你很可能会得到失真的输出信号。
实际上芯片内部在I/O口的输出部分组织了多个响应速度不同的输出驱动电路,用户能够依据自己的需求挑选适宜的驱动电路。
留意:GPIO的引脚速度是指I/O口驱动电路的响应速度而不是输出信号的速度,输出信号的速度与你的程序有关。
5、GPIO初始化步骤
对于该基本步骤的讲解,我们以stm32LED灯闪烁的代码举例讲解~~~~
-
代码
#include "stm32f10x.h" #define LED_GPIO GPIOA /**< LED引脚端口号 */ #define LED_PIN GPIO_Pin_1 /**< LED引脚编号 */ /*LED引脚配置*/ void LED_GPIO_Init(void) { /*打开时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /*配置GPIO*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 模式-推挽输出 */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_Init(LED_GPIO, &GPIO_InitStructure); /*初始化电平*/ GPIO_SetBits(LED_GPIO, LED_PIN); /* 默认输出高电平关闭LED */ } /*设置LED开关*/ void Set_LEDState(unsigned char state) { GPIO_WriteBit(LED_GPIO, LED_PIN, (BitAction)state); } //粗略延时 void Delay_ms1( volatile unsigned int t) { unsigned int i,n; for (n=0;n<t;n++) for (i=0;i<800;i++); } int main(void) { LED_GPIO_Init(); /* LED引脚配置 */ while(1) { Set_LEDState(1);//LED熄灭 Delay_ms1(500);//延时时间 Set_LEDState(0);//LED亮 Delay_ms1(500);//延时时间 } }
GPIO初始化步骤:
使能GPIOx口的时钟
/*打开时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
指明GPIOx口的哪一位,这一位的速度大小以及模式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 模式-推挽输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = LED_PIN;
调用GPIOx初始化函数进行初始化
/*初始化电平*/
GPIO_SetBits(LED_GPIO, LED_PIN); /* 默认输出高电平关闭LED */
调用GPIO-SetBits函数,进行相应位的置位
/*初始化电平*/
GPIO_SetBits(LED_GPIO, LED_PIN); /* 默认输出高电平关闭LED */
三、结尾
希望你看完我的文章过后,会有一定的收获!!!
₍ᐢ…ᐢ₎♡
感谢大佬的友情链接
[学习、理解STM32F103系列芯片的地址映射和寄存器映射原理,GPIO端口初始化_stm32f103寄存器功能_不知名小菜鸟9号的博客-优快云博客](https://blog.youkuaiyun.com/qq_66144143/article/details/127289607)
学习和理解STM32F103系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤 - qgrwljzy - 博客园 (cnblogs.com)