100ask七天物联网训练营学习笔记 - GPIO

100ask七天物联网训练营学习笔记 - GPIO

今天回看了训练营GPIO的课程讲解,认真查阅芯片手册结合自己的理解把内容总结一下。

1. GPIO介绍

GPIO是英文General-Purpose Input/Output的缩写,意为通用目的输入输出端口,是MCU中最简单也是最常用的外设,由于芯片引脚资源原因,部分外设往往要与GPIO端口复用芯片的引脚。这就导致部分GPIO端口除了基本的输入输出功能外,还可能作为其他外设的功能引脚,由外设进行控制。所有功能都需要通过软件来进行配置。下面我们来看看GPIO的配置。

还有一点,STM32通常工作电压为3.3V,部分GPIO口是可以兼容5V电压工作,可以从芯片手册来确定某个GPIO是否兼容5V电压。如果某个GPIOI/O Leve标注为FT,则说明它兼容5V电压。

请添加图片描述

2. GPIO硬件结构(以STM32F103为例)

2.1 GPIO功能描述

请添加图片描述

通过芯片手册我们可以看出,每组GPIO Port都有232-bit配置寄存器、232-bit数据寄存器,132-bit置位/复位寄存器,116-bit复位寄存器以及一个32-bit的锁定寄存器。GPIO可以设置的模式如下:

  • 浮空输入
  • 上拉输入
  • 下拉输入
  • 模拟输入
  • 开漏输出
  • 推挽输出
  • 复用推挽输出
  • 复用开漏输出

2.2 GPIO结构框图

请添加图片描述

  1. 保护二极管:当引脚电压高于VDD时,上侧二极管导通,当引脚电压低于VSS时,下侧二极管导通,可以有效防止过高或过低电压损坏芯片内部电路。
  2. P-MOS和N-MOS:
    • 推挽输出:推挽输出时P-MOS和N-MOS都参与工作,内部输出高电平,经过反向后,P-MOS管导通,N-MOS管关闭,对外输出高电平;内部输出低电平经过反向后,N-MOS导通,P-MOS关闭,对外输出低电平。在推挽模式下,GPIO输出具有一定的驱动能力,P-MOS负责灌电流,N-MOS负责拉电流。这种模式可以应对绝大部分使用情况。
    • 开漏模式:当设置为开漏模式后,P-MOS不在参与工作。当内部输出低电平时,经过反向,N-MOS导通,使得输出低电平;当内部输出高时,N-MOS关闭,P-MOS也是关闭,引脚即无法输出高电平也无法输出低电平,为高阻态。所以,开漏模式我们使用时想要输出高电平,必须外部上拉。开漏模式一般应用在需要“线与”功能的电路中,常见在IIC等通信总线。若当两个推挽输出结构连接在一块时,如果一个引脚输出高,一个引脚输出低,就会造成第一个引脚P-MOS导通,另一个引脚N-MOS导通,电流会从VCC直接流向GND发生短路。这也解释了为什么推挽输出不能实现“线与”。

请添加图片描述
请添加图片描述

  1. 输出数据寄存器:为输出控制电路输入信号,数据由GPIOx_ODR寄存器提供。
  2. 复用功能输出:GPIO由其他外设对引脚进行控制。例如,进行UART通信时,一个引脚作为TX,一个引脚作为RX
  3. 输入数据寄存器:引脚配置为输入模式时,内部先经过上拉下拉电阻,可以通过软件配置成上拉、下拉,再经过施密特触发器,即可以保证信号为输入,也将模拟信号转换为数字信号。
  4. 复用功能输入:与复用功能输出一致,作为某个外设的引脚由外设进行控制。
  5. 模拟输入:从信号进入施密特触发器前采集,直接使用模拟输入信号。例如引脚作为ADC的输入引脚。

3. GPIO配置(100ASK_STM32F103_MINI为例)

请添加图片描述
使用资源:

  • 用户LED,连接在GPIOA1,低电平使能。
  • 用户KEY,连接在GPIOA0,按下为低电平,松开后为高电平。

3.1 通过寄存器配置

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

4. 实验(100ASK_STM32F103_MINI为例)

本实验实现用户KEY按下,LED点亮,用户KEY松开,LED熄灭。

// main.c
#include <stdint.h>

#define RCC_BASE        0x40021000
#define RCC_APB2ENR     (RCC_BASE + 0x18)

#define GPIOA_BASE      0x40010800
#define GPIOA_CRL       (GPIOA_BASE + 0x00)
#define GPIOA_IDR       (GPIOA_BASE + 0x08)
#define GPIOA_ODR       (GPIOA_BASE + 0x0C)


int main(void) 
{   
    volatile uint32_t *rcc_apb2enr = (uint32_t *)RCC_APB2ENR; 
    
    volatile uint32_t *gpioa_crl = (uint32_t *)GPIOA_CRL;
    volatile uint32_t *gpioa_idr = (uint32_t *)GPIOA_IDR;
    volatile uint32_t *gpioa_odr = (uint32_t *)GPIOA_ODR;
    
    // 使能GPIOA时钟
    *rcc_apb2enr |= (1 << 2);
    
    // 清除GPIOA_CRL寄存器[7:4]、[3:0]位
    *gpioa_crl &= ~((0xFU << 0) | (0xFU << 4));
    
    // 设置GPIOA0为浮空输入模式、GPIOA1为推挽输出模式
    *gpioa_crl |= (0 << 0) | (1 << 2) | (1 << 4) | (0 << 6);
    
    while (1)
    {
        // 检测按键是否被按下,GPIOA0高电平表示按键未被按下
        if (*gpioa_idr & (1 << 0))
        {
            // GPIOA1 输出高电平,LED熄灭
            *gpioa_odr |= (1 << 1);
        }
        else
        {
            // GPIOA1 输出低电平,LED点亮
            *gpioa_odr &= ~(1U << 1);
        }
    }
}

请添加图片描述

实验完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值