使用STM32 HAL库读取整个输入端口的数据

使用STM32 HAL库读取整个输入端口的数据

  • 问题描述
  • 先看一下HAL与标准库的区别
  • 问题的解决
  • 感悟

问题描述

ST推出的新的HAL库将逐步取代以往的标准库。我最近将以往使用标准库编写的工程改用HAL库重构,发现一个问题就是HAL库无法整体读取指定GPIOx的数据(也许是我没发现相应的库函数)。

先看一下HAL与标准库的区别

HAL库提供的GPIO操作函数

void  HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init);
void  HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin);
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);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

标准库提供的GPIO操作函数

void GPIO_DeInit(GPIO_TypeDef* GPIOx);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

很明显新的HAL库相对于旧的标准库少了许多函数。官方之所以会推出库函数的目的之一就是为了使用户不至于被繁琐的寄存器所困扰。少了这么多函数意味着有些功能我们就无法实现。

问题的解决

原始标准库工程里调用了GPIO_ReadInputData(GPIOE)读取GPIOE的16个端口的输入数据,但是使用HAL库就无法直接实现了。我查看了标准库的相应代码,发现它是这样写的:

/**
  * @brief  Reads the specified GPIO input data port.
  * @param  GPIOx: where x can be (A..I) to select the GPIO peripheral.
  * @retval GPIO input data port value.
  */
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  return ((uint16_t)GPIOx->IDR);
}

底层代码是直接调用 的IDR寄存器,那么在使用HAL库时要想直接实现整体读取指定GPIOx的数据,就只能使用(uint16_t)GPIOx->IDR了。

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

感悟

也许HAL库还不完善,当我们需要将标准库的工程迁移到HAL库时,发现没有相关的库函数可以替代,那么这个时候就应该看一下标准库的底层用寄存器实现的代码了。虽然库函数的名字会改变,但是对于同类芯片它的寄存器是一定的。

你可能感兴趣的:(小问题的解决)