STM32 GPIO控制引脚详解
一、GPIO基本资料
GPIO为通用输入输出口,可配置8种输入输出模式,引脚电平为0~3.3V(部分可容忍5V)。
输出模式下可控制端口输出高低电平,以驱动LED ,控制蜂鸣器,模拟通信协议输出时序(I2C,SPI)等。
输入模式下可读取端口的高低电平或电压,以读取按键输入,外接模块电平信号输入,ADC电压采集,模拟通信协议接收数据等。
二、GPIO结构
图一
图二
图三
如图一, STM32中,所有GPIO挂载在APB2总线上。按GPIOA,GPIOB, GPIOC…命名,每GPIO外设16引脚(0~15/PX0~PX15)。
如图二,寄存器是特殊的储存器,内核通过APB2总线对寄存器进行读写,完成输出读写电平的功能。
(一)GPIO中寄存器
1. 端口输出数据寄存器:普通IO口输出,同时控制16个端口,只能整体读写。
单独读写某一位方法:
(1)先读寄存器,后通过按位于,按位或更改某一位,最后将数据写回(此方法较为麻烦)。
(2)通过位设置/清除寄存器进行单独读写。
(3)读写“位带”区域(类比51位寻址)。
2. 端口输入数据寄存器:读取GPIO输入状态。
3. 位设置/清除寄存器:单独操作输出寄存器某一位,而不影响其他位,高16位进行清除,低16位进行位设置。对输出数据寄存器置1(清除),则位设置寄存器对应位写1(0),其他位写0(1)。
4. 端口位清除寄存器: 与位设置/清除寄存器高16位功能相同。
5. 端口配置寄存器:配置GPIO工作模式
(二)施密特触发器:对输入电压进行整形。高于某一阈值,则输出高电平,低于某一阈值,则输出低电平。(注意:输入电压高于上限后施密特触发器输出电压维持高电平,直到下一次输入电压低于下限,不是低于上限后即输出低电平)
(三)保护二极管:输入电流大于3.3V时,上方二极管导通,防止过大电流对GPIO的伤害。电流小于0V时同理。
三、GPIO模式
(一)推挽/开漏输出
推挽输出模式下,P-MOS, N-MOS均有效,数据输出寄存器为1,P-MOS接通, N-MOS断开,输出高电平。反之,输出低电平。
开漏输出模式下,P-MOS无效。数据输出寄存器为0,N-MOS导通,输出低电平。数据输出寄存器为1,N-MOS断开,即输出断开,此时为高阻模式,无驱动能力。(对比推挽输出,高低电平均有驱动能力)
开漏输出为通信协议驱动方式,可避免各设备相互干扰。同时,可提供5V电压。
两种模式下,高低电平均具有较强驱动能力,IO口由STM32控制
(二)上拉/下拉/浮空输入
三种模式均为数字输入,可读取引脚电平。
上拉输入内部连接上拉电阻(上通下断),悬空时默认高电平;
下拉输入内部连接下拉电阻(下断上通),悬空时默认低电平;
浮空输入时,上拉电阻与下拉电阻均断开,使用时连接连续驱动源,否则引脚悬空,电平不稳定。
(三)模拟输入:数字输入关闭,GPIO无效,从引脚直接接入片上外设(ADC),所以不需经施密特触发器进行电压整形。
(四)复用推挽输出:引脚由片上外设控制,普通输入模式有效,高电平为高阻态,无驱动能力,低电平接VSS。
(五)复用开漏输出:引脚由片上外设控制,普通输入模式有效,高电平接VDD,低电平接VSS。
注:一个端口只能有一个输出,但可以有多个输入,输入模式下输出无效。
四、电亮LED
(一) 操作GPIO
1. 使用RCC开启GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
2. 使用GPIO_Init函数初始化GPIO
GPIO_InitTypeDef GPIO_InitStruct
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
3. 使用输出或输入函数控制GPIO GPIO_ResetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN);
代码完成
#include "stm32f10x.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,EN ABLE);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);//配置GPIOB
GPIO_ResetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN); //PB0输出0,灯亮
while(1)
{
}
}
作者:baisi不解