STM32——GPIO
本文系统总结了STM32F1系列GPIO模块的学习要点,主要包括:1. GPIO基本特性与引脚分布;2. 8种工作模式(输入/输出/复用/模拟)及其特点;3. 关键寄存器配置(CRL/CRH、ODR、IDR等);4. HAL库驱动开发流程(时钟使能、初始化、读写操作);5. 实践案例:LED控制与按键扫描实现,包含硬件电路分析、软件消抖处理及状态检测方法。
总 :STM32——学习总纲
参考资料:
一、GPIO简介



1.1 GPIO 特点

1.2 GPIO 电气特性*
stm32芯片资料STM32F103ZET6(English)
![]()


1.3 GPIO 引脚分布

电源引脚:V开头![]()
晶振引脚:
复位引脚:![]()
下载引脚:通过 串口、JTAG、SWD下载有不同的下载IO
BOOT引脚:
GPIO引脚:p开口
![]()

二、IO端口基本结构


F1与F3、F7、H7的差异点在于上下拉电阻的位置。
F1的IO做为输入禁止使用上下拉电阻,这是由硬件决定的。


额外补充:


记忆:箭头方向就是电子流动方向。想要mos管导通,需要 gs 压差满足 箭头方向上的电子流通。
三、GPIO的八种模式(F1)
前置


3.1 输入浮空


特点:

3.2 输入上拉


特点:
弱上拉

3.3 输入下拉


特点:

3.4 模拟功能


特点:
输入只走模拟输入

3.5 开漏输出



寄存器介绍参考前置
特点:

开漏模式下,寄存器写0,NMOS管导通,此时IO口呈低电平↓
开漏模式下,寄存器写1,P、N mos管皆不导通,此时IO口为高阻态,F1系列想要输出高电平,需要外部的上拉电阻。
3.6 开漏复用


特点:
不由寄存器控制,由片上外设控制输出

3.7 推挽输出



寄存器介绍参考前置
特点:

可控制 P/N MOS管的反向导通,控制 IO 口输出高低电平。
3.8 推挽复用


特点:

不由寄存器控制,由片上外设控制输出
3.* F4/F7/H7 系列和 F1 系列的 GPIO 差异点

四、GPIO寄存器(F1)


“GPIOx_” 中的 ‘x’ 代表A~E组别,每个组有以下七个寄存器
4.1 端口配置 高、低 寄存器(Configuration Register Low/High)
此俩寄存器用于配置 IO 口的 工作模式和输出速度。
一组 IO 有16个,高、低寄存器每四个bit(CNFy、MODEy)配置一个IO,两个寄存器64bit,共配置16个IO。
当配置 bit 0b1000, 按配置是 上拉/下拉 输入模式,但不能确定上拉还是下拉,还需要ODR寄存器进行设置。

具体CR配置如下截图。
GPIOx_CRL

GPIOx_CRH

4.2 端口输出数据寄存器(Out Data Register)
GPIOx_ODR
16个 bit 对应16个IO。用于设置IO引脚输出时的高低电平。
还可通过此寄存器配置上拉/下拉输入配置。

4.3 端口输入数据寄存器(Input Data Register)
GPIOx_IDR
只读,读取对应 IO 的状态,用于判断引脚电平。
4.4 端口位设置/清除寄存器(Bit Set Reset Register)
GPIOx_BSRR
高16bit,写 1 清除ODR寄存器对应bit为0,写0无影响。
低16bit,写 1 清除ODR寄存器对应bit为1,写0无影响。
此寄存器用于控制 ODR寄存器

4.5 不建议使用的寄存器
GPIOx_BRR
GPIOx_LCKR
4.6 ODR 与 BSRR*
![]()
![]()

类似C中 volatile关键词,从原始地址获取值,以防缓存值与原始值不一致。
五、通用外设驱动模型(四步法)

六、GPIO配置步骤
GPIO配置 属于 通用外设驱动模型四步法的前三步。

![]()

![]()
相关库函数

源码分析
__HAL_RCC_GPIOA_CLK_ENABLE()
stm32f1xx_hal_rcc.h

![]()
![]()

使用宏定义控制寄存器IO端口A时钟使能。 APB2ENR |= (1 << 2)
HAL_GPIO_Init
通过结构体中的 @ref 查找HAL库定义好的宏参数,例如 @ref GPIO_pins_define 。


/**
* @brief GPIO Init structure definition
*/
typedef struct
{
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIO_mode_define */
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
This parameter can be a value of @ref GPIO_pull_define */
uint32_t Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;
/**
* @brief General Purpose I/O
*/
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
/**
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
* @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
* the configuration information for the specified GPIO peripheral.
* @retval None
*/
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
寄存器基地址:
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *)GPIOE_BASE)
#define GPIOF ((GPIO_TypeDef *)GPIOF_BASE)
#define GPIOG ((GPIO_TypeDef *)GPIOG_BASE)
/** @defgroup GPIO_pins_define GPIO pins define
* @{
*/
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
/** @defgroup GPIO_mode_define GPIO mode define
* @brief GPIO Configuration Mode
* Elements values convention: 0xX0yz00YZ
* - X : GPIO mode or EXTI Mode
* - y : External IT or Event trigger detection
* - z : IO configuration on External IT or Event
* - Y : Output type (Push Pull or Open Drain)
* - Z : IO Direction mode (Input, Output, Alternate or Analog)
* @{
*/
#define GPIO_MODE_INPUT 0x00000000u /*!< Input Floating Mode */
#define GPIO_MODE_OUTPUT_PP 0x00000001u /*!< Output Push Pull Mode */
#define GPIO_MODE_OUTPUT_OD 0x00000011u /*!< Output Open Drain Mode */
#define GPIO_MODE_AF_PP 0x00000002u /*!< Alternate Function Push Pull Mode */
#define GPIO_MODE_AF_OD 0x00000012u /*!< Alternate Function Open Drain Mode */
#define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT /*!< Alternate Function Input Mode */
#define GPIO_MODE_ANALOG 0x00000003u /*!< Analog Mode */
#define GPIO_MODE_IT_RISING 0x10110000u /*!< External Interrupt Mode with Rising edge trigger detection */
#define GPIO_MODE_IT_FALLING 0x10210000u /*!< External Interrupt Mode with Falling edge trigger detection */
#define GPIO_MODE_IT_RISING_FALLING 0x10310000u /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
#define GPIO_MODE_EVT_RISING 0x10120000u /*!< External Event Mode with Rising edge trigger detection */
#define GPIO_MODE_EVT_FALLING 0x10220000u /*!< External Event Mode with Falling edge trigger detection */
#define GPIO_MODE_EVT_RISING_FALLING 0x10320000u /*!< External Event Mode with Rising/Falling edge trigger detection */
/** @defgroup GPIO_pull_define GPIO pull define
* @brief GPIO Pull-Up or Pull-Down Activation
* @{
*/
#define GPIO_NOPULL 0x00000000u /*!< No Pull-up or Pull-down activation */
#define GPIO_PULLUP 0x00000001u /*!< Pull-up activation */
#define GPIO_PULLDOWN 0x00000002u /*!< Pull-down activation */
/** @defgroup GPIO_speed_define GPIO speed define
* @brief GPIO Output Maximum frequency
* @{
*/
#define GPIO_SPEED_FREQ_LOW (GPIO_CRL_MODE0_1) /*!< 2MHz Low speed */
#define GPIO_SPEED_FREQ_MEDIUM (GPIO_CRL_MODE0_0) /*!< 10MHz Medium speed */
#define GPIO_SPEED_FREQ_HIGH (GPIO_CRL_MODE0) /*!< 50MHz High speed */
HAL_GPIO_WritePin
/**
* @brief Sets or clears the selected data port bit.
*
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between
* the read and the modify access.
*
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
* @param GPIO_Pin: specifies the port bit to be written.
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
* @param PinState: specifies the value to be written to the selected bit.
* This parameter can be one of the GPIO_PinState enum values:
* @arg GPIO_PIN_RESET: to clear the port pin
* @arg GPIO_PIN_SET: to set the port pin
* @retval None
*/
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
/**
* @brief GPIO Bit SET and Bit RESET enumeration
*/
typedef enum
{
GPIO_PIN_RESET = 0u,
GPIO_PIN_SET
} GPIO_PinState;
HAL_GPIO_TogglePin
/**
* @brief Toggles the specified GPIO pin
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
* @param GPIO_Pin: Specifies the pins to be toggled.
* @retval None
*/
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_GPIO_ReadPin
/**
* @brief Reads the specified input port pin.
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
* @param GPIO_Pin: specifies the port bit to read.
* This parameter can be GPIO_PIN_x where x can be (0..15).
* @retval The input port pin value.
*/
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
七、编程实战
7.1 点亮一个LED && LED亮灭控制
LED 链接原理图

此原理图可用推挽输出,开漏输出控制,开漏输出是能输出低电平,以及一个高阻态特性,在此情景中符合发光二极管控制原理。
7.1.1 工程新建
1.新建BSP板级支持包文件夹


![]()
2.代码编写
#ifndef _LED_H
#define _LED_H
#include "./SYSTEM/sys/sys.h"
void led_init(void);
#endif
#include "./BSP/LED/led.h"
void led_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
gpio_init_struct.Pin = GPIO_PIN_5;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_Init(GPIOB, &gpio_init_struct); /* PB5 pullpush low */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
int main(void)
{
HAL_Init(); /* ³õʼ»¯HAL¿â */
sys_stm32_clock_init(RCC_PLL_MUL9); /* ÉèÖÃʱÖÓ,72M */
delay_init(72); /* ³õʼ»¯ÑÓʱº¯Êý */
led_init(); /* ³õʼ»¯LED */
while(1)
{
/*write pin control*/
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET); /* LED1 Ãð */
delay_ms(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
delay_ms(500);
/*Toggle pin control*/
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
delay_ms(200);
}
}
7.2 通过KEY来控制LED亮灭
按键通常会有抖动,需要 软件去抖获取 KEY 的状态,一般是5~10ms。

按键原理图

PA0配置输入下拉,PE2.3.4配置输入上拉。获取两种状态。
#ifndef __KEY_H
#define __KEY_H
#include "./SYSTEM/sys/sys.h"
void key_init(void);
uint8_t key_scan(void);
#endif
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
/* °´¼ü³õʼ»¯º¯Êý */
void key_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOE_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_2;
gpio_init_struct.Mode = GPIO_MODE_INPUT;
gpio_init_struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
}
/* °´¼üɨÃ躯Êý */
uint8_t key_scan(void)
{
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == 0)
{
delay_ms(10); /* Ïû¶¶ */
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == 0)
{
while(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == 0); /* µÈ´ý°´¼üËÉ¿ª */
return 1; /* °´¼ü°´ÏÂÁË */
}
}
return 0; /* °´¼üûÓа´Ï */
}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
int main(void)
{
HAL_Init(); /* ³õʼ»¯HAL¿â */
sys_stm32_clock_init(RCC_PLL_MUL9); /* ÉèÖÃʱÖÓ, 72Mhz */
delay_init(72); /* ÑÓʱ³õʼ»¯ */
led_init(); /* LED³õʼ»¯ */
key_init(); /* KEY³õʼ»¯ */
while(1)
{
if(key_scan())
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
else
{
delay_ms(10);
}
}
}
更多推荐




所有评论(0)