单片机学习----GPIO通用输入输出口

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 灯亮灭的功能。

本文所述内容为本人通过网络自学后归纳所得,仅服务于个人复习与学习需求,无任何商业应用意图。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值