学习和理解STM32F103系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)
前言
GPIO 是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。STM32F103 芯片为144脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG ,同时每组GPIO口组有16个GPIO口。通常简略称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。- STM32的大部分引脚除了当GPIO使用之外,还可以在复用位
外设功能引脚 (比如串口)
一、STM32F103系列芯片的地址映射、寄存器映射原理
1.寄存器
- 寄存器是中央处理器内的组成部分,它们可用来
暂存指令、数据和地址 - 按照功能的不同,可将寄存器分为
基本寄存器和移位寄存器 两大类:基本寄存器只能并行送入数据,也只能并行输出;移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入、并行输出,也可以串行输入、串行输出,还可以并行输入、串行输出,或串行输入、并行输出 - 存放数据的寄存器是最好理解的:如果你需要读取一个数据,直接到这个寄存器所在的地方来“问问”它,数据是多少就行了;问寄存器这个动作,叫做
访问寄存器 - 指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令
2.映射原理
地址映射: 由百度词条可知为了保证CPU执行指令时可正确访问存储单元,需将用户程序中的逻辑地址转换为运行时由机器直接寻址的物理地址,这一过程称为地址映射寄存器映射: 在存储器的区域单元中,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射
二、GPIO端口的初始化设置
1.GPIO简介
-
GPIO (General-purpose input/output),通用型之输入输出的简称:功能类似8051的P0—P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO) -
每个GPIO内部都有这样的一个电路结构: -
保护二极管 :IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。 -
P-MOS管和N-MOS管 :由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。 -
TTL肖特基触发器 :信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。
2.GPIO输入、输出模式及说明
- GPIO支持
4种输入模式 (浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式 (开漏输出、开漏复用输出、推挽输出、推挽复用输出) - 每个I/O口可以自由编程,但I/O口寄存器必须按
32位字 被访问
2.1 浮空输入模式
GPIO_Mode_IN_FLOATING - I/O端口的电平信号直接进入输入数据寄存器:也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的
2.2 输入上拉模式
GPIO_Mode_IPU - I/O端口的电平信号直接进入输入数据寄存器:但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平
2.3 输入下拉模式
GPIO_Mode_IPD - I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平
2.4 模拟输入模式
GPIO_Mode_AIN - I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等
2.5 开漏输出模式
GPIO_Mode_Out_OD - 通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平
2.6 开漏复用输出模式
GPIO_Mode_AF_OD - 与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的
2.7 推挽输出模式
GPIO_Mode_Out_PP - 通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。这里要注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平
2.8 推挽复用输出模式
GPIO_Mode_AF_PP - 与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的
3.GPIO的初始化设置
- 使能GPIOx口的时钟
- 指明GPIOx口的哪一位,这一位的速度大小以及模式
- 调用GPIOx初始化函数进行初始化
- 调用GPIO-SetBits函数,进行相应位的置位
3.1 单个GPIO端口
GPIO_InitTypeDef GPIO_InitStructure;
第一步:使能GPIOA的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
第二步:设置GPIOA参数:输出OR输入,工作模式,端口翻转速率
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_8; //设定要操作的管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
第三步:调用GPIOA口初始化函数,进行初始化。
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA
第四步:调用GPIO-SetBits函数,进行相应为的置位。
GPIO_SetBits(GPIOA,GPIO_Pin_0); //输出高
3.2 多个GPIO端口
GPIO_InitTypeDef GPIO_InitStructure;
第一步:使能GPIOA,GPIOE的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
第二步:设置GPIOA,GPIOE参数:输出OR输入,工作模式,端口翻转速率
第三步:调用GPIOA口初始化函数,进行初始化。
第四步:调用GPIO-SetBits函数,进行相应为的置位。
把第二、三、四步合并分别设置GPIOA和GPIOE
先设置GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO-InitST);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
再设置GPIOE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO-InitST);
GPIO_SetBits(GPIOE,GPIO_Pin_3);
总结
本文只简单介绍了STM32F103系列芯片中的地址映射原理、寄存器映射原理;同时通过分析GPIO输入输出模式、介绍GPIO的初始化设置步骤,一定程度上加深了大家对于STM32F103系列芯片的理解与认识。同时也期待大家能够积极留言,指出我存在的问题,谢谢!
参考文献: https://blog.csdn.net/cleveryoga/article/details/120927837
|