当前位置:   article > 正文

【STM32】标准库与HAL库对照学习教程特别篇--GPIO详讲_hal gpio

hal gpio


STM32全部教程【STM32】标准库与HAL库对照学习系列教程大全

一、前言

本篇内容是的STM32GPIO的详讲,是为库函数配置做铺垫,本篇以STM32F103ZE为例,详细对GPIO进行讲解。

二、GPIO简介

1、定义

GPIO英文全称general purpose intput output,是通用输入输出端口的简称,可以通过软件来控制其输入和输出。STM32芯片的GPIO引脚外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。

2、分类

  • STM32从管脚类型被分为了:电源管脚、晶振管脚、复位管脚、下载管脚、BOOT管脚、GPIO管脚
  • GPIO管脚类的所有管脚又被分为了:PA类、PB类、PC类、PD类…,根据芯片类型不同类数也不同,但每类引脚最多只有16个,例如:PA0~PA15。

3、复用

STM32芯片有很多的内置外设,些外设的外部引脚都是与GPIO共用的,也就是说,一个引脚除了输入输出电平,还可以使用别的功能,但默认功能是电平的输入输出,要使用其他功能的时候,就需要GPIO的复用。例如:IIC通信就是GPIO引脚的复用。

三、GPIO工作模式

1、输入模式

  • 浮空输入
  • 上拉输入
  • 下拉输入
  • 模拟输入

2、输出模式

  • 开漏输出
  • 复用开漏输出
  • 推挽输出
  • 复用推挽输出

3、输出速度

  • 低速
  • 中速
  • 高速

四、GPIO图形分析

1、GPIO的基本构成

GPIO其内部结构图,如下:
在这里插入图片描述

图片在STN32F1xx中文参考手册的105页

  • (1)保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止异常常电压引入芯片导致芯片烧毁。
  • (2)上拉、下拉电阻控制引脚默认状态的电压打开上拉的时候引脚默认电压为高电平,打开下拉的时候引脚默认电压为低电平
  • (3)TTL施密特触发器基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,可以将电平分为高电平与低电平,也就是1和0的数字信号,并且符合TTL电平协议,这就是STM32可以产生TTL信号的原因。
  • (4)P-MOS管和N-MOS管输出电平信号P-MOS管和N-MOS管决定,高电平时,P-MOS管导通,N-MOS管关闭输出高电平低电平时,P-MOS管关闭,N-MOS管导通输出低电平,这就使得GPIO具有“推挽输出”和“开漏输出”的模式 。

注释: VDD_FT 代表IO口,兼容3.3V和5V,如果没有标注“FT”,就代表着不兼容5V

在这里插入图片描述

图片在数据手册34页

2、GPIO八种模式分析


  • 浮空输入模式
    在这里插入图片描述
    浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。MCU直接读取I/O口电平,但I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的

  • 上拉输入模式
    在这里插入图片描述
    IO内部闭合上拉电阻的开关,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平,如果I/O口输入低电平,那么引脚就为低电平,MCU读取到的就是低电平

  • 下拉输入模式
    在这里插入图片描述
    IO内部打开下拉电阻开关,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平 如果I/O口输入高电平,那么引脚就为高电平,MCU读取到的就是高电平

  • 模拟输入模式
    在这里插入图片描述
    当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态。

注:当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出。

除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律 要配置为复用功能模式


  • 开漏输出模式
    在这里插入图片描述
    在开漏输出模式时,只有N-MOS管工作,如果我们控制输出为低电平时,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1高电平时,则P-MOS管和N-MOS管都关闭,输出指令不会起到作用,此时IO端口要输出高电平,就要让I/O端口外部的上拉或者下拉决定,如果没有上拉或者下拉 IO口就处于悬空状态。

  • 推挽输出模式
    在这里插入图片描述
    在推挽输出模式时,N-MOS管和P-MOS管都工作,如果我们控制输出为低电平,则P-MOS管关闭,N-MOS管导通,I/O端口输出低电平,若控制输出为高电平,则P-MOS管导通N-MOS管关闭,I/O端口输出高电平

注:此时输入是可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。I/O口的电平是输出的电平。


  • 开漏复用输出模式
    在这里插入图片描述
    GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效; 输出的高低电平的来源于其它外设,输入同样可用,通过输入数据寄存器可获取I/O实际状态 除了输出信号的来源改变,其他与开漏输出功能相同

  • 复用推挽输出模式
    在这里插入图片描述
    GPIO复用为其他外设(如 I2C),输出数据寄存器GPIOx_ODR无效;输出的高低电平的来源于其它外设,输入同样可用,通过输入数据寄存器可获取I/O实际状态,除了输出信号的来源改变其他与开漏输出功能相同。

五、HAL库与标准库的GPIO配置结构体对比

1、标准库定义


typedef struct
{
  uint16_t GPIO_Pin;             //要配置的GPIO管脚            

  GPIOSpeed_TypeDef GPIO_Speed;  //GPIO管脚输出速度的配置

  GPIOMode_TypeDef GPIO_Mode;    //GPIO管脚模式配置
                                     
}GPIO_InitTypeDef;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

结构体第一个元素可配置的引脚

#define GPIO_Pin_0                 ((uint16_t)0x0001)  
#define GPIO_Pin_1                 ((uint16_t)0x0002)  
#define GPIO_Pin_2                 ((uint16_t)0x0004)  
#define GPIO_Pin_3                 ((uint16_t)0x0008)  
#define GPIO_Pin_4                 ((uint16_t)0x0010)  
#define GPIO_Pin_5                 ((uint16_t)0x0020)  
#define GPIO_Pin_6                 ((uint16_t)0x0040)  
#define GPIO_Pin_7                 ((uint16_t)0x0080)  
#define GPIO_Pin_8                 ((uint16_t)0x0100)  
#define GPIO_Pin_9                 ((uint16_t)0x0200)  
#define GPIO_Pin_10                ((uint16_t)0x0400)  
#define GPIO_Pin_11                ((uint16_t)0x0800)  
#define GPIO_Pin_12                ((uint16_t)0x1000) 
#define GPIO_Pin_13                ((uint16_t)0x2000)  
#define GPIO_Pin_14                ((uint16_t)0x4000)  
#define GPIO_Pin_15                ((uint16_t)0x8000) 
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

结构体第二个元素配置的速度

typedef enum
{ 
  GPIO_Speed_10MHz = 1,  //中速
  GPIO_Speed_2MHz,       //低速
  GPIO_Speed_50MHz       //高速
}GPIOSpeed_TypeDef;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

结构体第三个元素配置的模式

typedef enum
{ GPIO_Mode_AIN = 0x0,           //模拟输入模式
  GPIO_Mode_IN_FLOATING = 0x04,  //浮空输入模式
  GPIO_Mode_IPD = 0x28,          //下拉输入模式
  GPIO_Mode_IPU = 0x48,          //上拉输入模式
  GPIO_Mode_Out_OD = 0x14,       //开漏输出模式
  GPIO_Mode_Out_PP = 0x10,       //推挽输出模式
  GPIO_Mode_AF_OD = 0x1C,        //开漏输出模式
  GPIO_Mode_AF_PP = 0x18         //复用推挽输出模式
}GPIOMode_TypeDef;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

定义文件在stm32f10x.gpio.h中

2、HAL库定义


typedef struct
{
  uint32_t Pin;      //要配置的GPIO管脚

  uint32_t Mode;    //GPIO管脚模式配置
  
  uint32_t Pull;    //GPIO管脚上拉、下拉配置
  
  uint32_t Speed;   //GPIO管脚输出速度的配置
} GPIO_InitTypeDef;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

结构体第一个元素可配置的引脚

#define GPIO_PIN_0                 ((uint16_t)0x0001)  
#define GPIO_PIN_1                 ((uint16_t)0x0002)  
#define GPIO_PIN_2                 ((uint16_t)0x0004)  
#define GPIO_PIN_3                 ((uint16_t)0x0008)  
#define GPIO_PIN_4                 ((uint16_t)0x0010)  
#define GPIO_PIN_5                 ((uint16_t)0x0020)  
#define GPIO_PIN_6                 ((uint16_t)0x0040)  
#define GPIO_PIN_7                 ((uint16_t)0x0080)  
#define GPIO_PIN_8                 ((uint16_t)0x0100)  
#define GPIO_PIN_9                 ((uint16_t)0x0200) 
#define GPIO_PIN_10                ((uint16_t)0x0400)  
#define GPIO_PIN_11                ((uint16_t)0x0800)  
#define GPIO_PIN_12                ((uint16_t)0x1000)  
#define GPIO_PIN_13                ((uint16_t)0x2000) 
#define GPIO_PIN_14                ((uint16_t)0x4000)  
#define GPIO_PIN_15                ((uint16_t)0x8000)  
#define GPIO_PIN_All               ((uint16_t)0xFFFF)  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

结构体第二个元素配置的模式

#define  GPIO_MODE_INPUT                  0x00000000u     //输入模式

#define  GPIO_MODE_OUTPUT_PP              0x00000001u     //推挽输出模式

#define  GPIO_MODE_OUTPUT_OD              0x00000011u     //开漏输出模式

#define  GPIO_MODE_AF_PP                  0x00000002u     //复用推挽输出模式

#define  GPIO_MODE_AF_OD                  0x00000012u     //复用开漏输出模式

#define  GPIO_MODE_AF_INPUT               GPIO_MODE_INPUT //模拟输入模式         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结构体第三个元素上拉下拉的配置模式

#define  GPIO_NOPULL        0x00000000u   //没有上拉下拉

#define  GPIO_PULLUP        0x00000001u   //上拉

#define  GPIO_PULLDOWN      0x00000002u   //下拉
  • 1
  • 2
  • 3
  • 4
  • 5

结构体第四个元素输出速度配置

#define  GPIO_SPEED_FREQ_LOW              (GPIO_CRL_MODE0_1)  //低速
#define  GPIO_SPEED_FREQ_MEDIUM           (GPIO_CRL_MODE0_0)  //中速
#define  GPIO_SPEED_FREQ_HIGH             (GPIO_CRL_MODE0)    //高速
  • 1
  • 2
  • 3
#define GPIO_CRL_MODE_Pos                    (0U)                              
#define GPIO_CRL_MODE_Msk                    (0x33333333UL << GPIO_CRL_MODE_Pos) /*!< 0x33333333 */
#define GPIO_CRL_MODE                        GPIO_CRL_MODE_Msk                 /*!< Port x mode bits */

#define GPIO_CRL_MODE0_Pos                   (0U)                              
#define GPIO_CRL_MODE0_Msk                   (0x3UL << GPIO_CRL_MODE0_Pos)      /*!< 0x00000003 */
#define GPIO_CRL_MODE0                       GPIO_CRL_MODE0_Msk                /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */
#define GPIO_CRL_MODE0_0                     (0x1UL << GPIO_CRL_MODE0_Pos)      /*!< 0x00000001 */
#define GPIO_CRL_MODE0_1                     (0x2UL << GPIO_CRL_MODE0_Pos)      /*!< 0x00000002 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

定义在stm32f1xx_hal_gpio.h文件内

到这里,STM32GPIO的介绍就结束啦!
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/126121
推荐阅读
相关标签
  

闽ICP备14008679号