STM32 Hal库版—GPIO

一、GPIO的简介

1.1.GPIO的介绍

GPIO的全称是General Purpose Input Output,即通用输入输出端口,它和51单片机里的IO口一样,只是一个输入输出的端口,负责采集外部器件的信息或者控制外部期间工作。

1.2.GPIO的特点

  • 不同型号,IO数量可能不一样,可通过选型手册快速查询
  • 快速反转,每次翻转最快只要两个时钟周期
  • 每个IO口都可以做中断(STM32最可贵的特点)
  • 支持8种工作模式

1.3.GPIO的电气特性

STM32工作电压范围在2V ~ 3.6V内,一般选3.3V为工作电压,要是接上了5V的电压,不通过特定的电路,会导致烧毁。GPIO识别的电压范围有两种类型的端口:第一种是COMS端口,电压在-0.3V ~ 1.164V判定为逻辑0,1.833V ~ 3.6V判定为逻辑1,设计电压的时候不要把电压设计在1.164V ~ 1.833V之间;第二种是TTL端口,它的端口能够兼容3.3V和5V的电压。想了解该GPIO到底是输出哪一种电平类型的端口,可以通过查询STM32的数据手册,I/O电平的框框里,有FT的是TTL端口,空白的是COMS端口。单个IO口最大的输出电流为25mA。
在这里插入图片描述

二、GPIO引脚分布及结构

2.1.引脚分布

STM32引脚类型:电源引脚(以V开头的引脚)、晶振引脚(8号引脚是低速输入,9号引脚是低速输出;23号引脚是高速输入,24号引脚是高速输出)、复位引脚(25号引脚)、下载引脚(具体的引脚需要参考手册)、BOOT引脚(138号引脚和PB2_BOOT1)、GPIO引脚(以P开头的引脚):
在这里插入图片描述

2.2.GPIO基本结构(F1系列)

在这里插入图片描述
根据红线划分控制器的外部和内部,外部的IO引脚是看得见的银色引脚。
① 保护二极管:保护二极管共有两个,用于保护引脚外部过高或过低的电压输入。当引脚输入电压高于VDD 时,上面的二极管导通,当引脚输入电压低于 VSS 时,下面的二极管导通,从而使输入芯片内部的电压处于比较稳定的值。虽然有二极管的保护,但这样的保护却很有限,大电压大电流的接入很容易烧坏芯片。
② 上拉、下拉电阻:它们阻值大概在 30~50K 欧之间,可以通过上、下两个对应的开关控制,这两个开关由寄存器控制。当引脚外部的器件没有干扰引脚的电压时,即没有外部的上、下拉电压,引脚的电平由引脚内部上、下拉决定,开启内部上拉电阻工作,引脚电平为高;开启内部下拉电阻工作,则引脚电平为低。需要注意的是,STM32 的内部上拉是一种“弱上拉”,这样的上拉电流很弱,如果有要求大电流还是得外部上拉。
③ 施密特触发器:可以将非标准方波,整形成方波。当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;当输入在正负向阈值电压之间,输出不改变。
在这里插入图片描述
④ P-MOS 管和 N-MOS 管:这个结构控制 GPIO 的开漏输出推挽输出两种模式。开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。推挽输出:这两只对称的 MOS 管每次只有一只导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载拉电流。推拉式输出既能提高电路的负载能力,又能提高开关速度。

三、GPIO的八种模式

GPIO八种模式特点及引用
输入浮空输入用,完全浮空,状态不定
输入上拉输入用,用内部上拉,默认为高电平
输入下拉输入用,用内部下拉,默认为低电平
模拟功能ADC、DAC
开漏输出软件IIC的SDL、SCL等
推挽输出驱动能力强,25mA,通用输出
开漏式复用功能片上外设功能(硬件IIC的SDL、SCL引脚等)
推挽式复用功能片上外设功能(SPI的SCK、MISO、MOSI引脚等)

3.1.输入浮空

上拉/下拉电阻为断开状态,施密特触发器打开,输出被禁止。输入浮空模式下,IO 口的电平完全是由外部电路决定。如果 IO 引脚没有连接其他的设备,那么检测其输入电平是不确定的。该模式可以用于按键检测等场景。

3.2.输入上拉

上拉电阻导通,施密特触发器打开,输出被禁止。在需要外部上拉电阻的时候,可以使用内部上拉电阻,这样可以节省一个外部电阻,但是内部上拉电阻的阻值较大,所以只是“弱上拉”,不适合做电流型驱动。

3.3.输入下拉

下拉电阻导通,施密特触发器打开,输出被禁止。在需要外部下拉电阻的时候,可以使用内部下拉电阻,这样可以节省一个外部电阻,但是内部下拉电阻的阻值较大,所以不适合做电流型驱动。

3.4.模拟功能

上下拉电阻断开,施密特触发器关闭,双 MOS 管也关闭。其他外设可以通过模拟通道输入输出。该模式下需要用到芯片内部的模拟电路单元单元,用于 ADC、DAC、MCO这类操作模拟信号的外设。

3.5.开漏输出

STM32 的开漏输出模式是数字电路输出的一种,从结果上看它只能输出低电平 Vss 或者高阻态,常用于 IIC 通讯(IIC_SDA)或其它需要进行电平转换的场景。

3.6.推挽输出

STM32 的推挽输出模式,从结果上看它会输出低电平 VSS 或者高电平VDD。推挽输出跟开漏输出不同的是,推挽输出模式 P-MOS 管和 N-MOS 管都用上。

3.7.开漏式复用功能

一个 IO 口可以是通用的 IO 口功能,还可以是其他外设的特殊功能引脚,这就是 IO 口的复用功能。一个 IO 口可以是多个外设的功能引脚,需要选择作为其中一个外设的功能引脚。当选择复用功能时,引脚的状态是由对应的外设控制,而不是输出数据寄存器。除了复用功能外,其他的结构分析请参考开漏输出模式。

3.8.推挽式复用功能

复用功能介绍请查看开漏式复用功能,结构分析请参考推挽输出模式。

四、GPIO寄存器

4.1.GPIO寄存器介绍

CRL、CRHIDRODRBSRRLCK
配置工作模式,输出速度输入数据输出数据设置ODR寄存器的值配置锁定

4.2.端口配置寄存器(GPIOx_CRL 和 GPIOx_CRH)

在这里插入图片描述

这两个寄存器都是 GPIO 口配置寄存器,不过 CRL 控制端口的低八位CRH 控制端口的高八位。寄存器的作用是控制 GPIO 口的工作模式工作速度,一共有32各框,每两个对应一个GPIO引脚,如控制GPIOA的第3个引脚,就控制CNF3和MODE3的框,寄存器描述如下图所示:
在这里插入图片描述
想要控制B~G的GPIO也是类似操作。再通过在特定位置输入特定值,来达到需要的效果:
在这里插入图片描述

图里的CNFy[1:0]如果输入了10,该如何区分上拉模式还是下拉模式,通过ODR寄存器来设置:

在这里插入图片描述

4.3.端口输出数据寄存器(GPIOx_ODR)

在这里插入图片描述

该寄存器用于控制 GPIOx 的输出高电平或者低电平低 16 位有效,分别对应每一组 GPIO 的 16 个引脚。当 CPU 写访问该寄存器,如果对应的某位写 0(ODRy=0),则表示设置该 IO 口输出的是低电平,如果写 1(ODRy=1),则表示设置该 IO 口输出的是高电平,y=0~15。此外,除了 ODR 寄存器,还有一个寄存器也是用于控制 GPIO 输出的,它就是 BSRR 寄存器。
在这里插入图片描述

4.4.端口置位/复位寄存器(GPIOx_BSRR)

在这里插入图片描述

该寄存器也用于控制 GPIOx 的输出高电平或者低电平,BSRR 是只写权限,而 ODR 是可读可写权限。BSRR 寄存器 32 位有效,在低 16 位(0-15)相应的位写 1(BSy=1),那么对应的 IO 口会输出高电平,往相应的位写 0(BSy=0),对 IO 口没有任何影响;高 16 位(16-31)作用是:对相应的位写 1(BRy=1)会输出低电平,写 0(BRy=0)没有任何影响,y=0~15。总结:对于 BSRR 寄存器,在高16位写1会置0;在低16位写1会置1,写 0 的话,对 IO 口电平是没有任何影响的。
在这里插入图片描述
首先需要读出来 ODR 寄存器的值,然后对整个 ODR 寄存器重新赋值来达到设置某个或者某些 IO 口的目的,而 BSRR 寄存器直接设置即可,这在多任务实时操作系统中作用很大。。BSRR寄存器还有一个好处,就是 BSRR 寄存器改变引脚状态的时候,不会被中断打断,而 ODR 寄存器有被中断打断的风险。

五、GPIO配置

5.1.通用外设驱动模型

  1. 初始化:时钟设置、参数设置、IO设置(可选)、中断设置(开中断、设NVIC)(可选)
  2. 读函数:从外设读取数据(可选)
  3. 写函数:往外设写入数据(可选)
  4. 中断服务函数:根据中断标志,处理外设各种中断事务(可选)

5.2.使能时钟

Hal库驱动函数:__HAL_RCC_GPIOx_CLK_ENABLE();它主要操作的寄存器是RCC_APB2ENR(为什么会操作APB2总线呢,因为根据手册可知,GPIO挂在APB2总线上),功能是开启GPIO时钟。这个函数是在stm32f1xx_hal_rcc.h里面,例如:打开GPIOA时钟的时候,它的寄存器里面的操作是:RCC->APB2ENR |= RCC_APB2ENR_IOPAEN将控制GPIOA的时钟开关置1(打开),图三是偏移到控制GPIOA时钟开关的位置。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5.3.设置工作模式

Hal库驱动函数:HAL_GPIO_Init(...);它主要操作的寄存器是CRL、CRH、ODR,功能是初始化GPIO。该函数有两个参数,第一个是确定GPIOA~G组的结构体指针,里面操控的都是GPIO的寄存器CRL、CRH、IDR、ODR、BSRR 、LCK等;第二个是操作功能的结构体指针,例如在PB5和PE5都设置为推挽输出,高速传输。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5.4.设置输出状态(可选)

Hal库驱动函数:HAL_GPIO_WritePin(...);它主要操作的寄存器是BSRR,作用是控制IO输出高/低电平;HAL_GPIO_TogglePin(...);它主要操作的寄存器也是BSRR,作用是每次调用,IO输出的电平就会翻转一次。
在这里插入图片描述
在这里插入图片描述

5.5.读取输入状态(可选)

Hal库驱动函数:HAL_GPIO_ReadPin(...);它主要操作的寄存器是IDR作用是读取IO的电平。
在这里插入图片描述在这里插入图片描述

六、实验

使两个LED灯闪烁,下面是主函数:


#include "./SYSTEM/delay/delay.h"

void led_init(void);                       

int main(void)
{
    HAL_Init();                             
    sys_stm32_clock_init(RCC_PLL_MUL9);      
    delay_init(72);                          
    led_init();                             
    
    while(1)
    { 
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);    
        HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);   
        delay_ms(500);
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);  
        HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);   
        delay_ms(500); 
    }
}


void led_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    __HAL_RCC_GPIOB_CLK_ENABLE();                         
    __HAL_RCC_GPIOE_CLK_ENABLE();                          

    gpio_initstruct.Pin = GPIO_PIN_5;                      
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;            
    gpio_initstruct.Pull = GPIO_PULLUP;                    
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;         
    HAL_GPIO_Init(GPIOB, &gpio_initstruct);               

    gpio_initstruct.Pin = GPIO_PIN_5;                   
    HAL_GPIO_Init(GPIOE, &gpio_initstruct);                
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值