GPIO是标准的输入输出口,单片机与外部设备进行交互的常用接口。
GPIO的作用是用来控制连接在此GPIO口上的外设
每个GPIO口有两个32位配置寄存器,两个32位数据寄存器,
一个32位置位/复位寄存器,一个16位复位寄存器和一个32位锁定寄存器。
根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成多种模式。
有8种模式:
浮空输入,上拉输入,下拉输入,模拟输入
推挽输出,开漏输出,复用推挽输出,复用开漏输出
浮空输入:引脚电平完全由外部输入决定,内部无上拉下拉电阻,
常用于外部能提供稳定电平或者对输入电平变化敏感的场合eg:外部中断输入引脚
上拉输入: 内部通过上拉电阻将引脚电平拉高,默认高电平,
当外部输入低电平时,引脚电平被拉低
下拉输入: 内部通过下拉电阻将引脚电平拉低,默认低电平,
外部输入高电平时,引脚电平被拉高
模拟输入:通常用于模拟信号输入,此时 GPIO 引脚将模拟信号转换为数字信号供芯片处理,
通常用于连接传感器等模拟信号源,如温度传感器、压力传感器等
推挽输出: 可以输出强电流,能快速地将引脚电平拉高或拉低,驱动能力较强,
可直接驱动一些需要较大电流的负载,如 LED、小型继电器等。
开漏输出: 输出引脚只能拉低电平,高电平需通过外部上拉电阻实现。
这种模式常用于需要线与功能的场合,即多个开漏输出引脚连接在一起,
只要有一个引脚输出低电平,整个线路就为低电平;
只有所有引脚都为高阻态(通过外部上拉电阻实现高电平)时,线路才为高电平。常用于 I2C 等总线通信中。
复用推挽输出: 当 GPIO 引脚用于一些复用功能时,
如作为定时器的输出引脚、SPI 通信的时钟引脚等,使用复用推挽输出模式,
此时引脚的功能由相应的复用功能模块控制,输出信号的特性与推挽输出类似,
但信号的来源是复用功能模块而非简单的 GPIO 输出寄存器。
复用开漏输出: 与复用推挽输出类似,用于 GPIO 引脚的复用功能,但输出特性为开漏输出,
常用于一些特殊的复用功能场景,如某些通信协议中需要开漏输出特性来实现特定的总线功能。
下图为I/O端口位的基本结构:
一个GPIO端口有多个引脚,每个引脚对应的就是一个I/O端口位。
使用GPIO需要以下配置:
1.RCC开时钟 2.初始化GPIO 3.使用输入/输出的函数控制GPIO端口
在 STM32 中,为了降低功耗,每个外设的时钟默认是关闭的。
使用 GPIOx之前,必须通过该函数使能其时钟,这样后续对 GPIOx 的配置和操作才能生效。
示例:以下代码为按键控制小灯(按键按一下熄灭,再按一下点亮)
#include "stm32f10x.h" // Device header
// LED初始化函数
void LED_Init(void)
{
//开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//初始化GPIOA
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//将引脚初始化为高电平(LED 熄灭状态 )
GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);
}
// LED1点亮函数
void LED1_ON(void)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
// LED1熄灭函数
void LED1_OFF(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
// LED1状态反转函数
void LED1_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
}
// 按键初始化函数
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
// 检测按键是否按下
uint8_t KeyNum = 0;
uint8_t Key_GetNum(void)
{
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
{
delay_ms(20); // 消抖延时
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
delay_ms(20);
KeyNum = 1;
}
return KeyNum;
}
int main(void)
{
LED_Init();
Key_Init();
while (1)
{
KeyNum = Key_GetNum();
if (KeyNum == 1)
{
LED1_Turn();
}
}
}
在这段代码中,GPIO(通用输入输出)发挥着至关重要的作用,它是实现按键控制 LED 灯功能的基础。GPIO 实现对 LED 灯的控制和对按键状态的检测,通过合理配置 GPIO 的模式和电平状态,完成了按键控制 LED 灯亮灭的功能。
本文所述内容为本人通过网络自学后归纳所得,仅服务于个人复习与学习需求,无任何商业应用意图。