STM32新手教程(也适合提高)

第二章 GPIO(HAL版本)


前言

GPIO口的控制可以说一切实际功能的基石,从本文开始着重讲解实际工程使用


提示:以下是本篇文章正文内容,下面案例可供参考

一、实际开发GPIO口准备工作

        现在STM32开发有CubeMX来快速配置外设,但是我本人在实际开发中是很少用到STM32CubeMX,它不是不好用,为啥不用呢?其一是ST的芯片太贵了、其二呢HAL库太大了对比固件库会慢一点、其三国内容易断货。

        在做一个完整的工程时,会用到大量的外设,例如:定时器生成PWM、USART、SPI、IIC等等,在考虑经济性下,一般工程中MCU的管脚都是会用的七七八八,在工程开始的时候,我们就得先把在工程中会用到的外设的管脚全部都定好。话不多说上图。

管脚功能图

        我们先看Pin name可以看到我们管脚,IO的Type呢一般都不用去理他,我们看到I/O level这里标注了FT说明这个管脚时兼容5V的,我们再往后面也看到Alternate functions(备用功能)项,这里分为了两类,一个是默认功能,一个是复用功能。假如我们需要使用ADC12的通道10,这时候我们通过上表可以看到PC0的默认功能就是ADC_IN10,以此类推,我所见过ARM单片机说明书基本都是这样的。这时候就会有人不信了,好我们再上雅特力的管脚图。

AT32管脚图

二、GPIO口HAL库配置

1.HAL库配置

假设我们现在需要使用PC0来做电源指示灯的拉高。

IO口选择

        我们左键点击PA1后会提示这个我们按照这个提示选择GPIO_Output,说一个题外话在工程中GPIO_Input和GPIO_Output是用的最多的,在后续的文章中会详细的解说。言归正传选好后会提示如下图。

我们点击PC0,会提示如下图。

这里有四个参数一个是初始化电平(GPIO output level)、GPIO口模式(GPIO mode)、GSIO Pull-up(上下拉)、还有一个输出速度。最后的User Label是管脚用户定义最后生成代码。

2.HAL库版本初始化GPIO

代码如下(示例):

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
//初始化电平,GPIO_PIN_RESET初始化为低电平,GPIO_PIN_SET为高电平
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//设置为推挽输出
  GPIO_InitStruct.Pull = GPIO_NOPULL;//浮空状态
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//低速IO口
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

这里可以着重看HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);这句话,这句是我们使用最多的,拉高拉低IO口都是这个函数,我们来看看这个函数原型。

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
  /* Check the parameters */
  /*assert_param为断言机制*/
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));

  if (PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
  }
}

除去断言机制,后只剩下一个if条件语句

  if (PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
  }

我们可以看到GPIOx(x代表端口)BSRR为寄存器。说明了我们修改BSRR寄存器就可以改变IO口电平,假如我们要拉高PB0。代码是这样的BPIOB->BSRR = GPIO_Pin。

有的人又要说这个GPIO_Pin到底是啥,我们一起来看看。

typedef enum
{
  GPIO_PIN_RESET = 0u,
  GPIO_PIN_SET
} GPIO_PinState;

这个就是IO状态的枚举,这里有一句GPIO_PIN_RESET = 0u,这里的0u中的u代表无符号。

        有的人就要问了为啥要说这个函数原型,因为我们调用函数时需要时间的,这里的调用是指进入函数到执行函数都是需要时间的,如果我们直接操作寄存器回避调用完整的函数要快。

        我们举个例子,你要进入房间,如果房间门是关上的,那你是不是得开门,这个开门的动作是不是需要时间。如果我们的房门是开着的,是不是会快一些

三、总结

我们在实际情况下使用HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);是最多的,例如我们的电源指示灯,我们的模拟PWM等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅哥的小迷弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值