Cortex-M0芯片GPIO详解

本文以STM32F051K8U6为例,主要介绍GPIO寄存器特点及应用,以及CubeMX的配置和HAL库函数的使用。

GPIO接口简介

通用输入输出接口GPIO是嵌入式系统、单片机开发过程中最常用的接口,用户可以通过编程灵活的对接口进行控制,实现对电路板上LED、数码管、按键等常用设备控制驱动,也可以作为串口的数据收发管脚,或AD的接口等复用功能使用。因此其作用和功能是非常重要的。

SoC芯片上的单个引脚可以通过配置GPIO寄存器以实现多种不同的功能,这就是多路复用。下图是芯片上GPIOA这一组端口上的引脚复用功能示意。

STM32F051-GPIO常用寄存器

 4个32位配置寄存器 
        GPIOx_MODER,  GPIOx_OTYPER,  GPIOx_OSPEEDR     GPIOx_PUPDR
 2个32位数据寄存器
      GPIOx_IDR 、GPIOx_ODR 
1 个32 位置位 / 复位寄存器
      GPIOx_BSRR
2 个 32 位复用功能配置寄存器 
     GPIOx_AFRH 、GPIOx_AFRL
注:每一组GPIO端口都有一套上述的寄存器去配置它自己的功能

MODER

GPIO 端口模式寄存器 (GPIOx_MODER) (x = A..D,F),主要用于指定GPIO端口的工作模式。

MODER是32位寄存器,其中每两位对应一个引脚。对于每个GPIOx上的引脚y,存在位[2y+1:2y](y = 0...15),即MODERy[1:0],用于配置I/O口的工作模式,模式代码如下:
        00:输入模式(复位状态)
        01:通用输出模式
        10:复用功能模式
        11:模拟模式

OTYPER

GPIO 端口输出类型寄存器 (GPIOx_OTYPER) (x = A..D,F),主要用于指定GPIO端口的输出类型。

OTYPER是32位寄存器,其中31:16为保留位,15:0为有效位,每一位二进制位对应一个引脚。对于每个GPIO上的引脚y,存在位[y](y = 0...15),即OTy,用于配置引脚的输出类型,类型代码如下:
        0:推挽输出(复位状态)
        1:开漏输出

如下图所示,若将输出类型设置为推挽输出模式,则不需要外接上(下)拉电阻,直接使用输出驱动器内部的互补信号输出高低电平,且在这两种电平下都有一定的驱动能力;若将输出类型设置为开漏输出模式,则是从MOSFET的漏极输出的电路,要得到真正的高电平状态需要加上拉电阻才行,否则引脚的高电平状态为高阻态。

OSPEEDR

GPIO 口输出速度寄存器 (GPIOx_OSPEEDR) (x = A..D,F),主要用于配置I/O口的输出速度。

OSPEEDR是32位寄存器,其中每两位对应一个引脚。对于每个GPIOx上的引脚y,存在位[2y+1:2y](y = 0...15),即OSPEEDRy[1:0],用于配置引脚的输出速度,代码如下: 
        x0:低速 2MHz
        01:中速 10MHz
        11:高速 50MHz
速度越高,输出效果越好,但能耗相应的也越高,因此在配置过程中根据具体应用需要选择合适的速度进行配置即可。

PUPDR

GPIO 口上拉 / 下拉寄存器 (GPIOx_PUPDR) (x = A..D,F),用于配置引脚的上拉或下拉电阻。

PUPDR是32位寄存器,其中每两位对应一个引脚。对于每个GPIOx上的引脚y,存在位[2y+1:2y](y = 0...15),即PUPDRy[1:0],用于配置引脚的上拉或下拉电阻,代码如下: 
        00:无上拉或下拉
        01:上拉
        10:下拉
        11:保留

IDR

GPIO 端口输入数据寄存器 (GPIOx_IDR) (x = A..D,F),用于读取GPIO引脚的输入数据。

IDR是32位寄存器,其中31:16为保留位,15:0为有效位,每一位二进制位对应一个引脚。对于每个GPIO上的引脚y,存在位[y](y = 0...15),即IDRy(只读),用于读取GPIO引脚的输入数据。

ODR

GPIO 端口输入数据寄存器 (GPIOx_ODR) (x = A..D,F),用于写入GPIO引脚的输输出数据。

ODR是32位寄存器,其中31:16为保留位,15:0为有效位,每一位二进制位对应一个引脚。对于每个GPIO上的引脚y,存在位[y](y = 0...15),即ODRy,用于写入GPIO引脚的输出数据。

BSRR

GPIO 端口置位 / 复位寄存器 (GPIOx_BSRR) (x = A..D,F),用于对GPIO端口进行置位/复位操作。

ODR是32位寄存器,其中31:16为端口x的复位位,15:0端口x的置位位,每一位二进制位对应一个引脚。
位31:16 BRy:对端口x的第y位进行复位操作(y = 0...15)。
                        这些位只写,读的时候返回0x0000。
                        写0:对相应的ODRy位无影响
                        写1:复位相应的ODRy位
位15:0   BSy:对端口x的第y位进行置位操作(y = 0...15)。
                        这些位只写,读的时候返回0x0000。
                        写0:对相应的ODRy位无影响
                        写1:置位相应的ODRy位
注:BRy和BSy同时写1时,BSy优先。

AFRL/AFRH

GPIO 复用功能低位寄存器 (GPIOx_AFRL) (x = A..B),以及GPIO 复用功能高位寄存器 (GPIOx_AFRH) (x = A..B),用于配置GPIO端口的复用功能。

位31:0  AFRLy:端口x引脚y的复用功能选择(y = 0...7),每四位对应一个引脚,代码如下:
            0000:AF0
            0001:AF1
            0010:AF2
            0011:AF3
            0100:AF4
            0101:AF5
            0110:AF6
            0111:AF7
其他代码保留。

位31:0  AFRHy:端口x引脚y的复用功能选择(y = 8...15),每四位对应一个引脚,代码如下:
            0000:AF0
            0001:AF1
            0010:AF2
            0011:AF3
            0100:AF4
            0101:AF5
            0110:AF6
            0111:AF7
其他代码保留。

STM32F051-GPIO输入输出配置实例(寄存器版)

由下图可知,开发板上的LED2~4分别对应GPIOB的第0号、第1号、第2号引脚,且当引脚为高电平时LED灯熄灭,引脚为低电平时LED灯点亮。

对GPIOB端口的第0号、第1号、第2号引脚进行初始化,代码如下:

    RCC->AHBENR |= 1<<18; //开启AHB外部时钟
    GPIOB->MODER |= (1<<0)|(1<<2)|(1<<4); //将GPIOB端口的第0号、第1号、第2号引脚配置为输出模式
    GPIOB->OTYPER = 0x0; //所有引脚配置为推挽输出
    GPIOB->OSPEEDR = 0x0; //引脚速度设置为低速

对GPIOB端口的BSRR置位/复位寄存器进行操作,使第0号、第1号、第2号引脚输出一个周期为1s的方波信号,同时LED以1s为周期闪烁,代码如下:

while (1)
{
      GPIOB->BSRR = (1<<16)|(1<<17)|(1<<18); // 点亮LED
      HAL_Delay(500); // 延时500ms
      GPIOB->BSRR = (1<<0)|(1<<1)|(1<<2); // 熄灭LED
      HAL_Delay(500); // 延时500ms
}

 由下图可知,开发板上的五向按键对应GPIOA的第8号引脚。

 对GPIOA端口的第8号引脚进行初始化,代码如下:

    GPIOA->MODER &= ~(0x3<<16); //将GPIOA端口的第8号引脚配置为输入模式
    GPIOA->OTYPER = 0x0; //所有引脚配置为推挽输出
    GPIOA->OSPEEDR = 0x0; //引脚速度设置为低速

当GPIOA端口的第8号引脚为高电平时,说明有按键按下,此时可以控制某LED电平翻转。

while (1)
{
      while(GPIOA->IDR & (1<<8))
      {
          if(GPIOB->ODR & (1<<0))
              GPIOB->BSRR = (1<<16);
          else
              GPIOB->BSRR = (1<<0);
          HAL_Delay(100);
      }
}

STM32F051-GPIO输入输出配置实例(HAL库函数版)

使用HAL库函数可以避免在配置寄存器的过程中出错,从而导致查错困难。首先使用CubeMX对HAL库进行初始化,如下图所示:

然后导出CubeMX自动生成的MDK工程,则可以在工程内看到GPIO初始化代码如下:

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB0 PB1 PB2 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

 此时,在main函数中,只需要调用如下函数就能对GPIO引脚进行操作:

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET); // 复位PB0, PB1, PB2 即点亮LED
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_SET); //  置位PB0, PB1, PB2 即熄灭LED
GPIO_PinState PA8_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8); // 读取PA8状态,返回值为GPIO_PIN_SET(按键按下)/GPIO_PIN_RESET(按键放开)

至此,GPIO的输入输出操作总结完毕。

注:本文仅由作者用于总结和记录学习ARM系列软件和Linux驱动开发的过程,未经允许请勿擅自转载,如有侵权请联系作者删除。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cortex-M0 是 ARM 公司推出的一款低功耗、低成本的 32 位微控制器处理器。Cortex-M0 例程是针对该处理器的代码示例集合,用于展示 Cortex-M0 的特点和使用方法。 Cortex-M0 例程通常涵盖了从基础的 GPIO 控制,到中断处理、定时器、串口通信等多个方面的功能代码。通过这些例程,开发者可以学习如何使用 Cortex-M0 处理器来实现各种任务。 在 Cortex-M0 例程中,首先需要配置和初始化相关硬件模块,如 GPIO 控制器、定时器等。然后,可以根据需求编写相应的代码来实现期望的功能。例如,如果想要通过 GPIO 控制 LED 的闪烁,可以设置引脚方向为输出,然后在循环中将引脚电平高低交替控制。如果想要实现定时器中断功能,可以设置定时器的周期和中断使能位,然后编写相应的中断服务函数来执行需要的操作。 Cortex-M0 例程不仅提供了硬件操作的代码示例,还提供了一些开发工具和环境的配置说明,以及对代码编译、下载和调试等方面的介绍。这些例程可以帮助开发者快速上手 Cortex-M0 处理器,并加深对其特性和应用的理解。 总之,Cortex-M0 例程是用于展示 Cortex-M0 处理器特点和使用方法的代码示例集合,可以帮助开发者学习和应用 Cortex-M0 处理器来实现各种功能。通过这些例程,开发者可以更加熟悉 Cortex-M0 的开发流程和操作方法,从而提高开发效率和代码质量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值