一、GPIO基本概念

GPIO全称General Purpose Input Output,中文意思是通用输入输出端口。它可以通过软件来控制其输入和输出。STM23芯片通过GPIO引脚与外部设备连接,可实现与外部的通信、控制以及数据采集的功能。

STM32的GPIO口按组可划分为GPIOA端口,GPIOB端口,GPIOC等端口,分组的数量与STM32芯片的引脚总数有关。GPIO口的每一个分组下通常都有16个引脚(Pin 脚),比如GPIOA分组,其引脚编号就是从GPIO_Pin_0开始到GPIO_Pin_15。

二、GPIO的内部结构

如下图所示,我们可以将GPIO的内部结构分为两大块,第一部分是GPIO的输入通路,第二部分是GPIO的输出通路。

上半部分为输入部分,包含模拟输入与复用功能输入电路,输入数据寄存器,内部上下拉电阻和TTL肖特基触发器几大块。这部分电路允许外部信号直接进入芯片内部,可以是模拟信号,也可以是数字信号。

  • 假设外部设备通过I/O引脚传输数字信号进来,到达肖特基触发器,这时肖特基触发器会将外部信号中可能包含的毛刺等不平滑的部分进行信号整形,从而得到一个比较标准的TTL电平信号,最后输入到GPIO的输入数据寄存器里面。

  • 如果外部输入的信号是一个模拟信号,肖特基触发器这部分的电路将作为旁路电路,信号不经过肖特基触发器,而直接给到芯片内部的ADC模式转换器。

下半部分为输出部分,包含位设置/清楚寄存器、输出数据寄存器、输出控制电路和MOS管开关电路。当芯片需要向外发送信号时,输出驱动电路会根据需要选择P-MOS或N-MOS晶体管来形成推挽输出或开漏模式。

  • 假设推挽模式下,芯片向外输出一个高电平信号,那么对应管脚的输出数据寄存器的值将被置1,PMOS管将会导通,NMOS管截止,I/O口输出一个3.3V作用的高电平;如果芯片向外输出一个低电平信号,输出数据寄存器的值将被置0,PMOS管截止,NMOS管导通,I/O口输出一个0V左右的TTL低电平。
  • 如果是开漏模式下,PMOS管这部分的电路是不会工作的。那么当芯片需要输出低电平时,控制信号会使得NMOS管导通,从而拉低输出引脚到地(0V)。当芯片输出一个高电平时,NMOS管会截止,输出电平取决于外部上拉电阻和电源电压,如果外部上拉电阻连接到电源VCC,那么输出引脚将被拉高,否则输出高阻态。

GPIO普通功能和复用功能的主要区别在于,复用功能下,信号是由芯片的其他片上外设输出,或者外部输入信号直接输出到芯片的其他片上外设。

三、GPIO的工作模式

GPIO的工作模式可以分为两大类,输入模式和输出模式。其中输入模式包含四种,输出模式也包含四种。

输入模式:

  • 输入浮空:输入信号的初始高低电平状态不确定,取决于外部电路
  • 输入上拉:输入信号的初始电平状态为高电平
  • 输入下拉:输入信号的初始电平状态为低电平
  • 模拟输入:输入为模拟信号,信号通过I/O口直接传输给芯片的其他片上外设

输出模式:

  • 推挽输出:可以输出高电平信号,也可以输出低电平信号,由GPIO的数据寄存器控制
  • 开漏输出:只能输出低电平信号或高阻态
  • 复用推挽输出:信号来源于芯片上其他的片上外设,可以输出高低电平
  • 复用开漏输出:信号来源于芯片上其他的片上外设,只能输出低电平

四、GPIO的简单应用----点亮LED灯

如图所示为开发板的LED驱动电路,在这个简单的驱动电路中,如果想要把LED灯点亮,那么在PA8这一端就应该给一个低电平信号,形成电压差,电流才能流过整条通路。

点亮LED灯的代码基本配置步骤:

1.开启GPIO外设时钟

2.初始GPIO外设(工作模式、工作速率、GPIO引脚)

3.设置PA8引脚为低电平

具体操作:

1.复制一份工程模板文件,并将“工程模板”文件夹名称改为“LED实验”

2.创建led_drv.c和led_drv.h文件,并将其分别存放到“LED实验\driver”目录下的src文件夹和inc文件夹

3.使用KEIL5打开当前LED实验工程,将led_drv.c文件添加到driver工程分组下

4.编写led_drv.c文件

#include "led_drv.h"

void LED_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        //1、打开时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        
        //2、配置GPIO
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;       //引脚
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //工作速率
        GPIO_Init(GPIOA,&GPIO_InitStruct);
        
        //3、灯初始状态灭灯
        GPIO_SetBits(GPIOA,GPIO_Pin_8); //设置高电平
}

void LED_On(void)
{
    GPIO_ResetBits(GPIOA,GPIO_Pin_8);  //设置低电平
}

void LED_Off(void)
{
    GPIO_SetBits(GPIOA,GPIO_Pin_8);  //设置高电平
}

5.编写led_drv.h文件

#ifndef __LED_DRV_H__
#define __LED_DRV_H__

#include "stm32f10x.h"

void LED_Init(void);
void LED_On(void);
void LED_Off(void);

#endif

6.修改main.c文件,点击编译无错误无警告,把生成的.hex文件烧录到STM32开发板中

#include "stm32f10x.h"
#include "led_drv.h"


int main(void)
{
    LED_Init();//初始化LED
    while (1)
    {
        LED_On();//点亮LED灯
    }
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐