文章目录
前言
最近开始了STM32的学习,已经学习了一段时间了,来对学习过的内容进行一个总结,
这篇来对STM32的GPIO,即STM32里最常用的地方,通用输入输出口做一个总结,把自己的经验和遇到的问题分享给大家
。
一、GPIO口整体介绍
GPIO简介
-
GPIO是通用输入输出口,可以对输入/输出数据进行缓冲、隔离或者锁存
。就拿
STMF103C8T6来说
,可用的GPIO口有GPIOA、GPIOB、GPIOC等GPIO口,每个端口的编号为15-0。相应的端口号就是GPIOA0、GPIOA1…GPIO15. -
每个引脚都有许多功能,最基本的
输入/输出功能
可以驱动LED、产生PWM、驱动蜂鸣器等。
引脚配置为输入模式时,具有外部中断功能
。
引脚可以重映射,复用的端口具有GPIO功能
。例如让PA15、PA14、PA15这三个引脚来当作通用输入输出口来使用,即GPIO口。 -
可以配置为8种输入输出模式
- GPIO口的引脚电平:0-3.3V,部分引脚可以容忍5v
GPIO的结构
每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL, GPIOx_CRH),两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)组成。
下方为GPIO端口位结构
GPIO的8种工作方式
分别为
上拉输入、下拉输入、模拟输入、浮空输入、开漏输出、推挽输出、复用开漏输出、复用推挽输出
。不同的模式下IO口具有不同的驱动能力和不同的功能。我们来通过IO口的位结构来说明这八种方式。
GPIO的4种输入方式
GPIO的输入模式下,可以读取端口的高低电平和电压,用于读取按键输入、外界模块电平信号输入、ADC电压采集。模拟通信协议接收数据集等。
主要由
TTL肖特基触发器、带开关的上拉电阻和下拉电阻
组成,输入信号同时送给输入数据寄存器也送给片上外设,GPIO输入模式下没有复用功能。
浮空输入
浮空输入就是GPIO内部既无上拉电阻也无下拉电阻。GPIO内部的上拉电阻和下拉电阻开关都断开。
该模式下,引脚默认输入位高阻态,即浮空,不确定。IO口电平由外部输入信号决定。
上拉输入
上拉输入就是GPIO内部有上拉电阻。GPIO内部的上拉电阻开关打开,下拉电阻断开,
该模式下,引脚上拉,当没有外部输入时默认输入高电平.
下拉输入
下拉输入就是GPIO内部有下拉电阻。GPIO内部的下拉电阻开关打开,上拉电阻断开,
该模式下,引脚下拉,当没有外部输入时默认输入低电平.
模拟输入
GPIO口无效,输入输出寄存器全部失效,引脚直接接入内部的ADC。用于外部模拟信号的输入。
GPIO的4种输出方式
GPIO口的输出模式下,可以控制引脚输出高低电平,用以驱动LED、控制蜂鸣器。模拟通信协议输出时序等。
开漏输出
开漏输出模式下,P-MOS无效,N-MOS有效
。
开漏输出模式下,只有低电平才有驱动能力,高电平无驱动能力,引脚只能输出低电平
,可以作为通信协议的驱动方式比如I2C通信的引脚,使用开漏输出模式。
-
当输出数据寄存器写1,N-MOS断开,输出控制相当于断开,也就是高阻态
-
当输出数据寄存器写0,N-MOS导通,输出控制相当于接VSS,输出为低电平
推挽输出
推挽输出模式下,P-MOS和N-MOS均有效
。
推挽输出模式下,STM32对IO口具有绝对的控制权,
引脚可以输出高低电平
。
-
当输出数据寄存器写1,上管导通,下管断开,输出控制接到VDD,输出为高电平
-
当输出数据寄存器写0,上管断开,下管导通,输出控制接到VSS,输出为低电平
复用开漏输出
这种模式下,引脚不再是普通的IO口,
不仅具有开漏输出的特点,还具有片内外设的功能
。例如IO口用作USART的数据发送端TX或者接收端RX时,使用该模式。
复用推挽输出
这种模式下,引脚不再是普通的IO口,
不仅具有推挽输出的特点,还具有片内外设的功能
。例如IO口用作I2C的SCL或者SDA时,使用该模式。
二、GPIO的库函数以及初始化方法
GPIO库函数
红框里的为较为常用的几个库函数
初始化GPIO
1. 使用RCC开启GPIO的时钟
这里最常用的就是AHB、APB2、APB1外设时钟控制
而GPIO口时钟控制一般在APB2
这个时候我们根据下方的库函数可以开启GPIO的时钟
。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使用RCC开启GPIOA的时钟
2. 使用GPIO_Init()函数初始化GPIO
下方采用的是
GPIOA0初始化,采用的模式为推挽输出
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推免输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //GPIOB初始化
3. 使用输出或输入的函数控制GPIO
就是采用以下六个函数
//设置GPIO管脚的高低电平
GPIO_SetBits(GPIOA, GPIO_Pin_0); //PA0口置高电平
GPIO_ResetBits(GPIOA, GPIO_Pin_0); //PA0口置低电平
GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET); //Bit_RESET 清除端口值,也就是置低电平
GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET); //Bit_SET 设置端口值 也就是置高电平
GPIO_Write(GPIOA,~0x0001); //0000 0000 0000 0001 给端口寄存器相应位置值
通过以上三步走,GPIO口就可以实现输入/输出的功能,相应的IO口被设置为高低电平。
三、总结
GPIO口本质上就和51单片机的IO口差不多,但是GPIO口的功能更多,有八种模式可以选择
在初始化GPIO口时,可以选择输入输出模式,
当需要IO口输出高低电平时,使用输出模式,当需要读取IO口的高低电平时,使用输入模式。
还有就是
对输出寄存器写1,对应的引脚输出为高电平,写0,对应的引脚输出为低电平
。
对输入寄存器读取为1,证明对应的端口是高电平,读取为0,证明对应的端口是低电平
。
列举几种常用的外设对应的方式,LED可以使用推挽输出或者是开漏输出来驱动,按键一般配置为上拉输入或者是下拉输入模式。传感器模块也可以选择上拉输入或者是浮空输入。
但是要根据不同的情况选择不同的模式,来实现相应的功能。
再者,GPIO口的配置,一般都是三步走,
开启时钟,GPIO初始化,对相应的IO口置高低电平。
最后行文仓促,如有错误,欢迎指正
。