GPIO_SetBits函数解析

这篇具有很好参考价值的文章主要介绍了GPIO_SetBits函数解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、GPIO_SetBits的作用

GPIO_SetBits函数用于将某位引脚置1,使其输出高电平。

二、详细解析

1.函数原型

代码如下:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BSRR = GPIO_Pin;
}

1.1.解析 GPIO_TypeDef* GPIOx

代码如下:

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;

GPIO_TypeDef是一个结构体变量,变量类型时结构体。如同int变量的变量类型是整形变量。

GPIO_TypeDef* GPIOx 类似于 int* p; 表示一个结构体变量的地址,前面定义这个类型的结构体变量,给这个变量的各个成员赋予我们需要用到的值。最后通过它的地址找到这个结构体变量,用这个结构体变量成员的值初始化GPIOx 。

GPIO_TypeDef* GPIOx 类似于 int* p; p=&a; 所以p是一个地址值,那么GPIOx也表示一个地址值。GPIOx为GPIOA时就表示GPIOA的起始地址GPIOx为GPIOB时就表示GPIOA的起始地址。

由于GPIO_TypeDef结构体变量里的成员变量的地址是连续的。所以GPIOx指向谁,地址就从谁开始。


1.2 解析 assert_param(IS_GPIO_ALL_PERIPH(GPIOx))

assert_param函数的作用就是检测传递给函数的参数是否是有效的参数。其中assert_param的传入参数是一个宏。

#define IS_GPIO_ALL_PERIPH(PERIPH) ( ((PERIPH) == GPIOA) || \
                                     ((PERIPH) == GPIOB) || \
                                     ((PERIPH) == GPIOC) || \
                                     ((PERIPH) == GPIOD) || \
                                     ((PERIPH) == GPIOE) || \
                                     ((PERIPH) == GPIOF) || \
                                     ((PERIPH) == GPIOG) )

IS_GPIO_ALL_PERIPH(PERIPH) 中的 PERIPH 和 PERIPH) == GPIOA 的 PERIPH 一样,也就是说IS_GPIO_ALL_PERIPH(PERIPH)中的 PERIPH 只能为 GPIOA~G 这=中的其中一个。

1.3 解析 assert_param(IS_GPIO_PIN(GPIO_Pin))

#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))
1、 ((PIN) & (uint16_t)0x00) == 0x00 无论PIN为何值其相与的结果都为0x00;也就是这个等式恒成立成立;
2、 (PIN) !=(uint16_t)0x00) 如果PIN=0x00;就不成立;其他的PIN值都成立;
1&&2 表示两者都成立为真 否则为假;也就是PIN的值不能为0x00;
例如GPIO_SetBits(GPIOB,GPIO_Pin_5); 中的GPIO_Pin_5就不等于0x00,其值为0x20。且GPIO_Pin_0~GPIO_Pin_15的值都不为0x00

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

1.4 解析 GPIOx->BSRR = GPIO_Pin

typedef struct
{
  __IO uint32_t CRL;	/*GPIO 端口配置低寄存器 地址偏移: 0x00 */
  __IO uint32_t CRH;	/*GPIO 端口配置高寄存器 地址偏移: 0x04 */
  __IO uint32_t IDR;	/*GPIO 数据输入寄存器 地址偏移: 0x08 */
  __IO uint32_t ODR;	/*GPIO 数据输出寄存器 地址偏移: 0x0C */
  __IO uint32_t BSRR;	/*GPIO 位设置/清除寄存器 地址偏移: 0x10 */
  __IO uint32_t BRR;	/*GPIO 端口位清除寄存器 地址偏移: 0x14 */
  __IO uint32_t LCKR;	/*GPIO 端口配置锁定寄存器 地址偏移: 0x18 */
} GPIO_TypeDef;

BSRR寄存器被定义在 GPIO_TypeDef 结构体里,GPIOx->BSRR 这一步已经给出了IO口的具体地址,由于BSRR寄存器是32位的,详情在下图。
GPIO_SetBits函数解析
由上图可以知道,BSRR寄存器高16位写1->清0,低16位写1->置1,由 #define GPIO_Pin_5 ((uint16_t)0x0020),0x0020化为二进制数是 0000 0000 0010 0000,是低16位(全32位的二进制数为:0000 0000 0000 0000 0000 0000 0010 0000),所以将0x20赋值给BSRR寄存器的话,就是在BSRR寄存器内的第 6(5+1)个位 置1。

对 GPIOx->BSRR = GPIO_Pin 另一个通俗点的理解(和上面的理解有相似之处)就是:
GPIOx->BSRR的意思就是告诉我们,置1或者置0,需要在BSRR寄存器里面设置,但是具体怎么设置呢?
GPIO_Pin 就是具体的设置方法了。因为BSRR寄存器是32位的(里面有32个位置可以置1或者置0),而 GPIO_Pin_5 的置为 0x0020,0x0020化为二进制数是 0000 0000 0010 0000,是低16位(全32位的二进制数为:0000 0000 0000 0000 0000 0000 0010 0000),所以将0x20赋值给BSRR寄存器的话,就是在BSRR寄存器内的第 6(5+1)个位 置1。

GPIOx->BSRR = GPIO_Pin 还有一个理解。在使用例子 GPIO_SetBits(GPIOB,GPIO_Pin_5) 中,GPIOx->BSRR 的 GPIOx 为GPIOB,而:

#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)

#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)

#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)

#define PERIPH_BASE           ((uint32_t)0x40000000)

所以,GPIOB的基地址是 0x40000000 + 0x10000 + 0x0C00 = 0x40010C00。整个GPIOB的地址范围是一段内存地址,。下面寄存器的地址分别为: 0x00 、 0x04 、 0x08 、 0x0C 、 0x10 、 0x14 、 0x18,每个相差 0x04 - 0x00 = 4 个内存单元,所以最大的地址为0x18 + 4 = 0x1C,所以 GPIOB 他的地址范围大小是0x00 ~ 0x1C (0x40010C00 ~ 0x40010C1C) 。文章来源地址https://www.toymoban.com/news/detail-421266.html

typedef struct
{
  __IO uint32_t CRL;	/*GPIO 端口配置低寄存器 地址偏移: 0x00 */
  __IO uint32_t CRH;	/*GPIO 端口配置高寄存器 地址偏移: 0x04 */
  __IO uint32_t IDR;	/*GPIO 数据输入寄存器 地址偏移: 0x08 */
  __IO uint32_t ODR;	/*GPIO 数据输出寄存器 地址偏移: 0x0C */
  __IO uint32_t BSRR;	/*GPIO 位设置/清除寄存器 地址偏移: 0x10 */
  __IO uint32_t BRR;	/*GPIO 端口位清除寄存器 地址偏移: 0x14 */
  __IO uint32_t LCKR;	/*GPIO 端口配置锁定寄存器 地址偏移: 0x18 */
} GPIO_TypeDef;

到了这里,关于GPIO_SetBits函数解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32-GPIO解析

            (一)定义: GPIO是MCU对外进行数据交互的通用IO接口,在MCU内部其可配置与其它片上外设或MCU内核(CPU)连接完成引脚上电压信号的读写。 GPIO端口在MCU上分为多个组来共同完成IO引脚读写(如GPIOA...),并且每个GPIO组掌控的IO引脚可以单独配置         (二)框图分析

    2024年02月19日
    浏览(20)
  • MSP432库函数学习笔记-GPIO

    简述MSP432Pxx-GPIO库的各函数 1,GPIO模式设置,PxDIR寄存器 2,GPIO复用功能配置,PxSEL寄存器 3,GPIO输出电平设置,PxOUT寄存器 4,GPIO输入模式下上/下拉电阻选择,PxREN寄存器 5,GPIO输入读取模式设置,PxIN寄存器 6,GPIO中断模块设置 1,中断使能寄存器PxIE 2,获取选择I/O口上的中

    2024年02月16日
    浏览(47)
  • 基于HAL库的GPIO端口三个基础函数HAL_GPIO_Init()、HAL_GPIO_ReadPin()和HAL_GPIO_WritePin()

    HAL_GPIO_Init() 是 STMicroelectronics 为其 STM32 微控制器系列提供的 HAL(硬件抽象层)库中的一个函数。 HAL_GPIO_Init() 函数的目的是初始化 STM32 微控制器的 GPIO(通用输入/输出)引脚。 GPIO 引脚可配置为输入或输出引脚,并可用于连接各种组件,如传感器、显示器和其他设备。 HAL

    2023年04月23日
    浏览(17)
  • STM32 学习2 库函数控制GPIO输出

    GPIO是STM32微控制器上的一组引脚,可配置为输入或输出模式,用于与外部设备进行数字信号交换。每个GPIO引脚都有一个唯一的编号,通常称为引脚名称或引脚号码。 STM32系列微控制器通常具有多个GPIO引脚,数量取决于具体型号。 GPIO模块是STM32微控制器中非常重要的功能之一

    2024年02月21日
    浏览(24)
  • STM32:GPIO_ResetBits函数用法解释

    GPIO_ResetBits函数是用于将指定引脚设置为低状态的函数,可以使用以下步骤进行使用: 首先需要初始化GPIO引脚,这可以通过GPIO_Init函数完成。在调用GPIO_Init函数时,需要传递一个GPIO_InitTypeDef类型的结构体,以配置引脚的模式、速度和上下拉电阻等参数。 在GPIO初始化完成后,

    2024年02月09日
    浏览(35)
  • MSP430F5529库函数GPIO学习

    导入MSP430Ware,查看例程;数据手册以及原理图获取 建议不是很了解寄存器的看完我的MSP430F5529学习笔记  目录 GPIO_setAsOutputPin() 函数声明 作用 参数 selectedPort selectedPins 修改的寄存器 使用 与GPIO_setAsOutputPin()参数一致的函数  GPIO_setOutputHighOnPin() GPIO_setOutputLowOnPin()

    2024年02月15日
    浏览(55)
  • RK3588 设备树pinctrl gpio子系统解析,解决GPIO无法正确拉高拉低的问题,RK3588设备树详解

    firefly的官方说明文档RK3588gpio系统说明 其中,bank是所属的组,Core-3588J 有 5 组 GPIO bank:GPIO0-GPIO4,每组又以 A0-A7, B0-B7, C0-C7, D0-D7 作为编号区分。 首先,对于firefly的rk3588j的开发板,其设备树有几个比较重要的文件, 分别是 /kernel/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi ; /ker

    2024年02月06日
    浏览(28)
  • 【Linux驱动开发】012 gpio子系统API函数

    设置好设备树以后, 在驱动程序中就可以使用 gpio 子系统提供的 API 函数来操作指定的 GPIO, gpio 子系统向驱动开发人员屏蔽了具体的读写寄存器过程。这就是驱动分层与分离的好处,大家各司其职,做好自己的本职工作即可。 gpio 子系统提供的常用的 API 函数有下面几个:

    2023年04月18日
    浏览(35)
  • stm32 hal库 GPIO初始化函数MX_GPIO_Init()梳理分析、初步细致学习(二)

    目录 一、GPIO外设时钟初始化 二、配置GPIO 2.1 配置 GPIO_InitTypeDef结构体成员变量  2.2 把参数写到对应寄存器 2.2.1 io口的配置 2.2.2 外部中断的配置 三、相关知识分析 3.1 hal_gpio其他函数简单分析 3.1.1 HAL_GPIO_DeInit(); 3.1.2  HAL_GPIO_ReadPin(); 3.1.3  HAL_GPIO_WritePin(); 3.1.4  HAL_GPIO_Togg

    2024年02月04日
    浏览(42)
  • 第四讲—讲解GPIO_Write函数以及相关例程

    之前讲解了初学GPIO的几个函数,下面介绍又一个函数,此函数对所有端口进行操作 GPIO_Write函数,与上一篇里边讲解的其他函数相比,最大的特点是它可以对多个端口进行赋值操作。 先看函数定义: 第一个参数与之前一样,因为是对多个端口操作,我们以GPIOA的所有端口为例

    2024年02月16日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包