STM32—GPIO相关知识

一、GPIO简介

GPIO(General Purpose Input Output)通用输入输出口,GPIO是控制或者采集外部器件信息的外设,即负责输入和输出。GPIO按组分配(GPIOA~GPIOG),每组16个引脚(PA0~PA15),其中部分IO口只能使用3.3V电平,但绝大部分IO口兼容5V电平(带有FT标志)。若引脚设置为模拟输入模式,则不能接入5V电平。在STM32中,所有的GPIO都挂载在APB2总线上。

GPIO有以下八种工作模式:

模式性质特征

浮空输入

数字输入

可读取引脚电平,若引脚悬空,则电平不确定

上拉输入

数字输入

可读取引脚电平,内部连接上拉电阻,悬空时默认高电平

下拉输入

数字输入

可读取引脚电平,内部连接下拉电阻,悬空时默认低电平

模拟输入

模拟输入

GPIO无效,引脚直接接入内部ADC

开漏输出

数字输出

可输出引脚电平,高电平为高阻态,低电平接VSS

推挽输出

数字输出

可输出引脚电平,高电平接VDD,低电平接VSS

复用开漏输出

数字输出

由片上外设控制,高电平为高阻态,低电平接VSS

复用推挽输出

数字输出

由片上外设控制,高电平接VDD,低电平接VSS

 二、GPIO基本结构

保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入对内部造成伤害。

上下拉电阻:上下拉电阻用于控制引脚默认电平,内部上拉电阻工作时,引脚默认为高电平;下拉电阻工作时,引脚默认为低电;如果都不工作,引脚的电平是不确定的,即为浮空模式。

施密特触发器:可以消除输入信号的干扰,当输入电压高于正向阈值电压,输出为高电平;当输入电压低于负向阈值电压,输出为低电平;在输入电压未达到另一阈值之前,电平输出保持不变。如下图所示,即使波动多次穿过阈值电压,输出信号也不会发生变化,只有在达到另一阈值时,输出信号才会进行翻转。

 P-MOS管和N-MOS管:P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭。开漏输出时,P-MOS管无效,N-MOS管截止时输出高阻态,导通时输出低电平;推挽输出时,P-MOS管和N-MOS管都有效,P-MOS管导通输出高电平,N-MOS管导通输出低电平。

三、工作模式

1.浮空输入模式:浮空输入模式下,上拉/下拉电阻断开,输出被禁止,输入经过施密特触发器直接接入输入数据寄存器,此时IO口输入电平是不确定的,完全取决于外部电路。

能够清晰的知道外部电路什么时候输入高电平,什么时候输出低电平,可以用于按键检测等场景。

 2.上拉输入模式:内部上拉电阻导通,输出被禁止,此时如果外部没有信号输入,引脚默认为高电平,内部上拉电阻阻值较大,所以只是“弱上拉”,不适合做电流型驱动。

常用于低电平触发的外部设备,如二极管、按键等。

3. 下拉输入模式:内部下拉电阻导通,输出被禁止,此时如果外部没有信号输入,引脚默认为低电平,内部下拉电阻阻值较大,不适合做电流型驱动。

常用于常用于高电平触发的外部设备,如二极管、按键等。

 4.模拟输入模式:内部上下拉电阻均断开,MOS管关闭,输入信号不经过施密特触发器,保留原始的电压信号,通过模拟通道进行输入。

常用于ADC、DAC等模拟信号处理。

 5.开漏输出模式:此时P-MOS管被控制在截止状态,IO口状态取决于N-MOS管,当输出数据寄存器①值为0时,经过取反输出逻辑1到N-MOS管使其导通,输出为低电平;当输出数据寄存器值为1时,N-MOS管截止,输出为高阻态。

注意此时施密特触发器是工作的,且上下拉电阻均断开,可以看成浮空输入模式,可以读取IO引脚状态。

 6.推挽输出模式:此时两个MOS管在同一时间只能由一个导通,若输出数据寄存器①的值为0,经过取反操作后,输出逻辑1到P-MOS管和N-MOS管的栅极,此时P-MOS管截止,N-MOS管导通,引脚输出低电平。若寄存器的值为1,则输出逻辑0到两个MOS管,此时P-MOS管导通,N-MOS管截止,输出为高电平。

该状态下施密特触发器也是打开的,可以读取IO口的电平状态。

7.复用功能输出:一个IO口可以是多个外设的功能引脚,当选择复用功能室,引脚的状态由对应的外设控制,而不是输出数据寄存器。开漏复用模式和推挽复用模式与前面同理。

四、寄存器介绍

 STM32F1通用GPIO口包含7个32位寄存器控制,包括:

2个32位端口配置寄存器(CRL和CRH)

2 个 32 位端口数据寄存器(IDR 和 ODR)

1 个 32 位端口置位/复位寄存器 (BSRR)

1 个 16 位端口复位寄存器(BRR)

1 个 32 位端口锁定寄存器 (LCKR)

我们常用的寄存器只有4个:CRL、CRH、IDR、ODR

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

这两个寄存器的作用是控制GPIO口的工作模式和工作速度,CRL控制每组IO端口(A~G)的低8位的模式,即PIN0~PIN7引脚,CRH控制每组IO端口的高8位的模式,即PIN8~PIN15引脚。

IO口工作模式配置表:

 GPIOx_CRL寄存器

 CRL寄存器控制PIN0~PIN7引脚的状态,每个IO口占用CRL的4个位,高两位为CNF,控制IO口工作模式,低两位为MODE,控制IO口的工作速度。

下面代码的意思是将PA0引脚设置为输入模式

GPIOx->CRL,这句话表示要操作GPIOx的低8位,就是Px0 ~ Px7;

CRL寄存器与0xFFFFFFF0按位与运算,即高28位不变,低4位清零,表示要控制PA0引脚;0xFFFFFF0F表示操作PA1引脚,余下同理。

GPIOA->CRL|=8<<0,意思是将1000左移0位(不移位),然后与CRL寄存器进行按位或运算,将第3位置1,第0~2位置0,即CNF0设置为10,MODE0设置为00,表示将PA0设置为输出模式。

GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;
//GPIOA->CRL=GPIOA->CRL & 0b1111 1111 1111 1111 1111 1111 1111 0000;
//GPIOA->CRL=GPIOA->CRL|(0b1000)<<0;

同理将PA1设置为推挽输出50MHz:

GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=3<<4;

 GPIOx_CRH寄存器

 CRH寄存器控制PIN8~PIN15引脚的状态,控制方式与CRL寄存器同理。

2.端口输入数据寄存器(IDR)

IDR寄存器用于读取IO口的电平状态,该寄存器为只读寄存器,低16位有效,对应16个IO口,对应位为1,表示IO口为高电平,对应位为0,表示IO口为低电平。

3.端口输出数据寄存器(ODR)

ODR寄存器用于控制GPIOx输出高电平或低电平,该寄存器低16位有效,分别对应每组GPIO口的16个引脚,如果对应某位写0,则表示该IO口输出低电平,如果写1,则表示该IO口输出高电平。

 4.端口置位/复位寄存器(BSRR)

BSRR寄存器只能写入,32位有效,对于低16位,对应位写1,相应IO口会输出高电平,对应位写0,则对IO口没有影响;高16位刚好相反,对应位写1会输出低电平,对应位写0没有影响。对于ODR寄存器,在设置电平时,需要将ODR寄存器的值读出,然后进行重新赋值,而使用BSRR寄存器直接对某个IO口进行设置即可。

 四、相关函数介绍

1.GPIO初始化

首先开启时钟,然后定义结构体成员,最后调用HAL_GPIO_Init()函数进行初始化,代码如下:

  void GPIO_init(void)
{  
    GPIO_InitTypeDef gpio_init_struct;
    __HAL_RCC_GPIOA_CLK_ENABLE;                             /* GPIOA时钟使能 */

    gpio_init_struct.Pin = GPIO_PIN_0;                      /* 引脚设置 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 模式设置 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上下拉设置 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 速度设置 */
    HAL_GPIO_Init(GPIOA, &gpio_init_struct);       /* 初始化GPIO */
}

2. HAL_GPIO_WritePin 函数

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);

 该函数用于设置引脚输出高电平或低电平,通过BSRR寄存器进行操作

形参1是端口号,选择范围:GPIOA~GPIOG

形参2是引脚号,选择范围:GPIO_PIN_0~GPIO_PIN_15

形参3是要设置的输出状态,GPIO_PIN_SET表示高电平,GPIO_PIN_RESET表示低电平

3. HAL_GPIO_TogglePin 函数

void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);

该函数用于设置引脚的电平翻转,也是通过BSRR寄存器进行操作

形参1是端口号,选择范围:GPIOA~GPIOG

形参2是引脚号,选择范围:GPIO_PIN_0~GPIO_PIN_15

文章为本人学习笔记,源于正点原子官方资料。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值