STM32 GPIO
引脚说明
GPIO全名为General Purpose Input Output,即通用输入输出。有时候简称为“IO口”。通用,说明它是常见的。输入输出,就是说既能当输入口使用,又能当输出口使用。(端口,就是元器件上的一个引脚。)
GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能
STM32F103ZET6芯片为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使用之外,还可以复用位外设功能引脚(比如串口)
GPIO基本结构
每个GPIO内部都有这样的一个电路结构
电路元件
保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。
P-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。
TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。
GPIO工作方式
GPIO支持4种输入模式(浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式(开漏输出、开漏复用输出、推挽输出、推挽复用输出)。同时,GPIO还支持三种最大翻转速度(2MHz、10MHz、50MHz)。
每个I/O口可以自由编程,但I/O口寄存器必须按32位字被访问。
输入模式:
l 浮空输入(GPIO_Mode_IN_FLOATING):引脚电平是真实的外部连接器件电压,电平有不确定性
l 上拉输入 (GPIO_Mode_IPU):默认通过电阻上拉到VCC,不接外部器件时可以读出高电平
l 下拉输入 (GPIO_Mode_IPD):默认通过电阻下拉到GND,不接外部器件时可以读出低电平
l 模拟输入 (GPIO_Mode_AIN):将外部信号直接传输到数模转换通道上
输出模式:
l 开漏输出(GPIO_Mode_Out_OD):只能输出低电平,高电平由电阻上拉决定
l 开漏复用功能(GPIO_Mode_AF_OD):用于外设功能使用
l 推挽式输出(GPIO_Mode_Out_PP):可以输出强高和强低,通常使用该功能控制LED
l 推挽式复用功能(GPIO_Mode_AF_PP):用于外设功能使用
GPIO配置
1.使能GPIO的时钟
STM32中的每一个外设都对应了一个时钟,当我们想要使用某一个外设的时候,必须先要开启它的时钟才行。
所有的 GPIO 都挂载到 APB2 总线上,具体的时钟由 APB2 外设时钟使能寄存器(RCC_APB2ENR)STM32中有一个专门管理时钟和复位的外设RCC。来控制
在编程时,可以使用标准库里提供的函数RCC_APB2PeriphClockCmd(),快速的使能相应的GPIO时钟。
/*以GPIOC为例,使能它的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
2.初始化GPIO引脚至相应的模式
当我们使用GPIO口之前,我们还需要对它进行一些初始化的操作,比如要设置它的速度、模式和引脚号。
简单来说,推挽输出既可以输出高电平,也可以输出低电平;开漏输出只能输出低电平,若要输出高电平,需要外接上拉电阻才行。利用单片机点亮LED,直接将GPIO配置为推挽输出模式。
接下来,我们可以使用标准库中的GPIO_Init()函数来进行GPIO的初始化操作。
关于该函数的使用方法,看代码注释。
/*下面的代码,将GPIOC的13号引脚配置为推挽输出,速度为50MHz*/
/*Step1:定义一个GPIO_InitTypeDef类型的结构体,该类型是标准库里定义的*/
GPIO_InitTypeDef GPIO_InitStructure;
/*Step2:选择要控制的GPIO引脚为Pin13*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
/*Step3:设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*Step4:设置引脚速率为50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*调用库函数GPIO_Init(),初始化GPIO*/
GPIO_Init(GPIOC, &GPIO_InitStructure);
3.控制GPIO引脚输出高低电平
我们当然可以直接操作参考手册里描述的寄存器来输出高低电平,在这里,我们使用标准库中帮我们封装好的函数GPIO_SetBits()和GPIO_ResetBits()来操作GPIO的输出电平。
GPIO_SetBits(GPIOC,GPIO_Pin_13); //将PC13引脚输出高电平
GPIO_ResetBits(GPIOC,GPIO_Pin_13); //将PC13引脚输出低电平
4.使用GPIO控制LED
基于之前新建的工程模板,将上述的三个步骤所介绍的内容组合在一起,我们就可以实现一个点亮Led灯的项目。
#include "stm32f10x.h"
void delay( uint32_t nCount);
void LED_Init(void);
int main(void)
{
/*使能GPIOC时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/*配置相关引脚,进行LED的初始化*/
LED_Init();
while(1)
{
/*将PC13引脚输出高电平,熄灭小灯*/
GPIO_SetBits(GPIOC,GPIO_Pin_13);
/*延时,以实现闪烁效果*/
delay(0x0FFFFF);
/*将PC13引脚输出低电平,点亮小灯*/
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
/*延时,以实现闪烁效果*/
delay(0x0FFFFF);
}
}
void delay( uint32_t nCount) //简单的延时函数
{
for(; nCount != 0; nCount--);
}
/*配置相关引脚,进行LED的初始化*/
void LED_Init(void)
{
/*下面的代码,将GPIOC的13号引脚配置为推挽输出,速度为50MHz*/
/*Step1:定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*Step2:选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
/*Step3:设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*Step4:设置引脚速率为50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*调用库函数,初始化GPIO*/
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*将PC13引脚输出高电平,熄灭LED*/
GPIO_SetBits(GPIOC,GPIO_Pin_13;
}
总结
2022.5.7-5.8完成第二次小结,继续学习更多知识