历史上的今天
返回首页

历史上的今天

今天是:2025年02月03日(星期一)

2021年02月03日 | STM32F429第六篇之stm32f4xx_hal_gpio

2021-02-03 来源:eefocus

前言

本文主要介绍HAL库中Stm32F429的GPIO用法。主要参考资料:

  • STM32F439xx HAL USER Manual

  • STM32F429数据手册

关于GPIO寄存器相关知识,可以参阅stm32F4xx中文参考手册,里面对于硬件底层以及寄存器有详细的介绍,本文不再详细展开。在使用HAL库的时候,即使不了解底层硬件和寄存器知识,同样可以完成项目的开发。此处,只需要了解HAL库驱动函数的使用方法即可。了解驱动函数的使用方法可以通过以下两种途径:

  • 阅读源程序和其中的注释

  • 阅读用户手册

用户手册在HAL库压缩包中自带,相对地址在:STM32Cube_FW_F4_V1.11.0DriversSTM32F4xx_HAL_Driver 。如下图所示:
在这里插入图片描述
可以知道,没有F429直接对应的用户手册,所以,我们可以选择比较相近的F439手册。

主要功能与使用方法

功能

HAL库的GPIO驱动模块。主要提供以下两种功能:

  • 初始化和去初始化功能。

  • IO操作功能。

使用方法

  1. 使能GPIO AHB时钟,使用函数: __HAL_RCC_GPIOx_CLK_ENABLE() 。

  2. 配置GPIO引脚功能,使用函数: HAL_GPIO_Init() 以及结构体 GPIO_InitTypeDef

    1. 通过结构体中成员 “mode” 配置IO模式。相关寄存器为(GPIOx_MODER)。

    2. 通过结构体中成员“pull”激活上拉电阻下拉电阻。相关寄存器为“ GPIOx_PUPDR ”。

    3. 通过结构体中成员“speed”改变引脚的速度。相关寄存器为“GPIOx_OSPEEDR

    4. 通过结构体中成员“alternate”改变引脚的复用功能。相关寄存器为“GPIOx_AFRLGPIOx_AFRH

  3. 在外部中断启用的情况下,需要使用 HAL_NVIC_SetPriority() 配置映射到EXTI行的NVIC IRQ优先级,并使用 HAL_NVIC_EnableIRQ() 启用它。

  4. 在输入模式情况下,使用 HAL_GPIO_ReadPin() 获取引脚电平状态。

  5. 在输出模式情况下,使用 HAL_GPIO_WritePin()/HAL_GPIO_TogglePin() 函数来改变引脚电平状态。

  6. 使用 HAL_GPIO_LockPin() 锁定引脚状态,锁定状态一直维持到下次启动之前。

注意:

  1. 结构体中mode 成员中的模拟模式,适用于该引脚用于ADC或者DAC。

  2. 结构体中“mode”成员除了与GPIOx_MODER 寄存器相关的数据,还有一些与外部中断模式有关的参数。

函数与结构体

函数

void  HAL_GPIO_Init (GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) 


根据参数GPIO_Init初始化GPIOx外设。


void  HAL_GPIO_DeInit (GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) 


去初始化,复位GPIO外设寄存器到他们初始的默认值。


GPIO_PinState  HAL_GPIO_ReadPin (GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)


读取特定的输入输入引脚。


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


置位或者清除选定的数据位。


void  HAL_GPIO_TogglePin (GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 


反转特定的GPIO引脚。


HAL_StatusTypeDef  HAL_GPIO_LockPin (GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 


锁定GPIO引脚配置寄存器。


void  HAL_GPIO_EXTI_IRQHandler (uint16_t GPIO_Pin)


该函数处理EXIT中断请求。


__weak void  HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin) 


EXTI 线路检测回调。


参数与结构体

GPIO_TypeDef *GPIOx

在F429中,x可以取 (A-K) 。其具体定义为:


#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)

#define GPIOH               ((GPIO_TypeDef *) GPIOH_BASE)

#define GPIOI               ((GPIO_TypeDef *) GPIOI_BASE)

#define GPIOJ               ((GPIO_TypeDef *) GPIOJ_BASE)

#define GPIOK               ((GPIO_TypeDef *) GPIOK_BASE)


定义的详细解析,可以参考上一篇博客:。其本质是一个常量地址。


对应结构体定义为:


typedef struct

{

  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */

  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */

  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */

  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */

  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */

  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */

  __IO uint32_t BSRR;     /*!< GPIO port bit set/reset register,      Address offset: 0x18      */

  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */

  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */

} GPIO_TypeDef;


此结构体对应着F429的GPIO寄存器,可以通过操作该结构体的成员变量,直接操纵对应寄存器。至于每个结构体的详细含义,请参考< STM32F4XX参考手册 >,此处不再赘述。


uint16_t GPIO_Pin

确定端口的引脚位。此参数可以取GPIO_PIN_x,其中x的取值范围为[0,15]。具体的定义如下:


#define GPIO_PIN_0                 ((uint16_t)0x0001U)  /* Pin 0 selected    */

#define GPIO_PIN_1                 ((uint16_t)0x0002U)  /* Pin 1 selected    */

#define GPIO_PIN_2                 ((uint16_t)0x0004U)  /* Pin 2 selected    */

#define GPIO_PIN_3                 ((uint16_t)0x0008U)  /* Pin 3 selected    */

#define GPIO_PIN_4                 ((uint16_t)0x0010U)  /* Pin 4 selected    */

#define GPIO_PIN_5                 ((uint16_t)0x0020U)  /* Pin 5 selected    */

#define GPIO_PIN_6                 ((uint16_t)0x0040U)  /* Pin 6 selected    */

#define GPIO_PIN_7                 ((uint16_t)0x0080U)  /* Pin 7 selected    */

#define GPIO_PIN_8                 ((uint16_t)0x0100U)  /* Pin 8 selected    */

#define GPIO_PIN_9                 ((uint16_t)0x0200U)  /* Pin 9 selected    */

#define GPIO_PIN_10                ((uint16_t)0x0400U)  /* Pin 10 selected   */

#define GPIO_PIN_11                ((uint16_t)0x0800U)  /* Pin 11 selected   */

#define GPIO_PIN_12                ((uint16_t)0x1000U)  /* Pin 12 selected   */

#define GPIO_PIN_13                ((uint16_t)0x2000U)  /* Pin 13 selected   */

#define GPIO_PIN_14                ((uint16_t)0x4000U)  /* Pin 14 selected   */

#define GPIO_PIN_15                ((uint16_t)0x8000U)  /* Pin 15 selected   */

#define GPIO_PIN_All               ((uint16_t)0xFFFFU)  /* All pins selected */


#define GPIO_PIN_MASK              ((uint32_t)0x0000FFFFU) /* PIN mask for assert test */


GPIO_InitTypeDef *GPIO_Init

该参数对应GPIO功能初始化的所有参数,具体含义需要解析结构体成员,结构体的定义如下:


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 */


  uint32_t Alternate;  /*!< Peripheral to be connected to the selected pins. 

                            This parameter can be a value of @ref GPIO_Alternate_function_selection */

}GPIO_InitTypeDef;


该结构体有五个成员变量,都与GPIO初始化相关。


Pin

指定需要初始化的GPIO引脚。该参数可以取GPIO引脚定义的任意值。其定义值可以取节uint16_t GPIO_Pin中的定义部分任意值,此处不再列出。


Mode

指定特定引脚的模式选择。参数可以取:


#define  GPIO_MODE_INPUT                        ((uint32_t)0x00000000U)   /*!< Input Floating Mode                   */

#define  GPIO_MODE_OUTPUT_PP                    ((uint32_t)0x00000001U)   /*!< Output Push Pull Mode                 */

#define  GPIO_MODE_OUTPUT_OD                    ((uint32_t)0x00000011U)   /*!< Output Open Drain Mode                */

#define  GPIO_MODE_AF_PP                        ((uint32_t)0x00000002U)   /*!< Alternate Function Push Pull Mode     */

#define  GPIO_MODE_AF_OD                        ((uint32_t)0x00000012U)   /*!< Alternate Function Open Drain Mode    */


#define  GPIO_MODE_ANALOG                       ((uint32_t)0x00000003U)   /*!< Analog Mode  */

    

#define  GPIO_MODE_IT_RISING                    ((uint32_t)0x10110000U)   /*!< External Interrupt Mode with Rising edge trigger detection          */

推荐阅读

史海拾趣

问答坊 | AI 解惑

NetFPGA千兆网络应用开发研讨会

如想参与本帖子讨论,请点以下链接:https://bbs.eeworld.com.cn/viewthread.php?tid=64508&extra=page%3D1&frombbs=1 尊敬的大学老师/业界同仁: 您好!     为了提高国内网络交换及信息安全的教学和科研水平,配合高校教学改革 ...…

查看全部问答>

不同电路中的电容器名称与作用详解

电容器是一种储能元件,具有“隔直通交,阴低频通高频”的特性,人们为了认识和鉴别不同电路中的电容器,根据其在线路中的作用而给它起了许多名称,了解这些名称和作用,对读图是垫脚有帮助的。下面介绍一些常用名称的含义。 1、滤波电容 它并接 ...…

查看全部问答>

关于S3C2410和GPRS的疑问

目前使用ARM9 S3C2410开发板在做实验 想请问下S3C2410芯片和GPRS模块的工作过程 两者之间是如何进行访问以及控制的 简单说就是想了解两者之间的关联和工作原理之类的,在线等解答,先谢谢了…

查看全部问答>

关于DS1302的问题,大家帮帮忙啊!!!

我是初学者,看DS1302的资料也很多了,也看了别人的程序,怎么自己动手就这么难呢~~~~ 还是希望有高人给我指点一下~~~这个账号新注册的,没有分啊~给不了大家分数了~~~ 下面是我的程序,我现在手上还没有足够的器材,我想先学会使用DS1302,所 ...…

查看全部问答>

IIC读写摄像头寄存器失败,为何?

小弟使用IIC读写摄像头OV5642寄存器,读写都失败,IIC驱动提示“ACK not received”。 从设备寄存器地址是datasheet上写的,应该不会错。 是何原因那? 附上一段代码: int  ModuleWriteBlock() {         int ...…

查看全部问答>

应急灯后期进展之三(MAX1640到底烧没烧?)

MAX1640到底烧没烧,现在我是说不清楚了。 一直以为是两个MOS管的问题。 昨晚我用指针表测量了一下,发现她们俩都很正常。 至少G D和G S之间是绝缘的,然后D S之间只有一个方向有阻值,那也是正常的,谁让它加装了一个保护二极管。 然后,对于5 ...…

查看全部问答>

香版主,请教STM32F10X的usb的windows驱动

                                      有个产品要做,想用上STM32F103系列的芯片,其中要用到USB接口和PC进行数据传输(b ...…

查看全部问答>

请教:用TI的TPS56xxx给DSP供电的问题

DSP和FPGA的板子,需要3.3V,1.8V和1.5V三种电源,为节约成本,决定不用PT69xx的电源芯片,请问高手,可以使用什么样的芯片呢,使用TPS56xxx系列的LDO,看Datasheet觉得好复杂,需要加MOS管在里面吗?谢谢…

查看全部问答>

240x SCI中断模式下的TXD有问题.......?????

程序在RealTimeMode下运行,可观察到: 1)IMR.4    = 1;                (INT5mask=1); 2)SCICNTL1 = 0x22;         (TX_ENA=1); 3)SCICNTL2 = 0xC1;     &nb ...…

查看全部问答>

【跟我一起学嵌入式LINUX】之应用程序的编写----编程基础

在看帖之前我想请你确保你手边可以有一个可以正常使用的LINUX系统,因为在看我帖子的时候如果有任何遇到不清楚的地方可以man一下,千万不要小瞧这个\'男人\'呀,有了它,几乎你可以放弃互联网来学习LINUX了。同时我还希望你至少可以使用LINUX操作 ...…

查看全部问答>