野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 9040|回复: 6

宏定义GPIO_Pin的类型问题

[复制链接]
发表于 2017-11-10 10:39:33 | 显示全部楼层 |阅读模式
最近新上手stm32f407,学习GPIO过程中,我在看官方库的时候遇到关于GPIO_Pin数据类型的小问题,网上也搜不到,请教一下大家
先上代码,下面是官方固件库stm32f4xx_gpio.h的原代码
  1. typedef struct
  2. {
  3.   uint32_t GPIO_Pin;              /*!< Specifies the GPIO pins to be configured.
  4. This parameter can be any value of @ref GPIO_pins_define */

  5.   GPIOMode_TypeDef GPIO_Mode;     /*!< Specifies the operating mode for the selected pins.
  6.                                        This parameter can be a value of @ref GPIOMode_TypeDef */

  7.   GPIOSpeed_TypeDef GPIO_Speed;   /*!< Specifies the speed for the selected pins.
  8.                                        This parameter can be a value of @ref GPIOSpeed_TypeDef */

  9.   GPIOOType_TypeDef GPIO_OType;   /*!< Specifies the operating output type for the selected pins.
  10.                                        This parameter can be a value of @ref GPIOOType_TypeDef */

  11.   GPIOPuPd_TypeDef GPIO_PuPd;     /*!< Specifies the operating Pull-up/Pull down for the selected pins.
  12.                                        This parameter can be a value of @ref GPIOPuPd_TypeDef */
  13. }GPIO_InitTypeDef;

  14. /* Exported constants --------------------------------------------------------*/

  15. /** @defgroup GPIO_Exported_Constants
  16.   * @{
  17.   */

  18. /** @defgroup GPIO_pins_define
  19.   * @{
  20.   */
  21. #define GPIO_Pin_0                 ((uint16_t)0x0001)  /* Pin 0 selected */
  22. #define GPIO_Pin_1                 ((uint16_t)0x0002)  /* Pin 1 selected */
  23. #define GPIO_Pin_2                 ((uint16_t)0x0004)  /* Pin 2 selected */
  24. #define GPIO_Pin_3                 ((uint16_t)0x0008)  /* Pin 3 selected */
  25. #define GPIO_Pin_4                 ((uint16_t)0x0010)  /* Pin 4 selected */
  26. #define GPIO_Pin_5                 ((uint16_t)0x0020)  /* Pin 5 selected */
  27. #define GPIO_Pin_6                 ((uint16_t)0x0040)  /* Pin 6 selected */
  28. #define GPIO_Pin_7                 ((uint16_t)0x0080)  /* Pin 7 selected */
  29. #define GPIO_Pin_8                 ((uint16_t)0x0100)  /* Pin 8 selected */
  30. #define GPIO_Pin_9                 ((uint16_t)0x0200)  /* Pin 9 selected */
  31. #define GPIO_Pin_10                ((uint16_t)0x0400)  /* Pin 10 selected */
  32. #define GPIO_Pin_11                ((uint16_t)0x0800)  /* Pin 11 selected */
  33. #define GPIO_Pin_12                ((uint16_t)0x1000)  /* Pin 12 selected */
  34. #define GPIO_Pin_13                ((uint16_t)0x2000)  /* Pin 13 selected */
  35. #define GPIO_Pin_14                ((uint16_t)0x4000)  /* Pin 14 selected */
  36. #define GPIO_Pin_15                ((uint16_t)0x8000)  /* Pin 15 selected */
  37. #define GPIO_Pin_All               ((uint16_t)0xFFFF)  /* All pins selected */
复制代码
上述部分的结构体GPIO_InitTypeDef中第一行,uint32_t GPIO_Pin,GPIO_Pin 被定义为uint32,而紧接着结构体后面的引脚定义中可以看出GPIO_Pin是16位的,如“#define GPIO_Pin_0 ((uint16_t)0x0001)”,所以这里不太理解,结构体中为什么要定义成uint32,求高手解惑
回复

使用道具 举报

发表于 2017-11-10 11:18:48 | 显示全部楼层
因为寄存器是32位的,就顺手这样写了吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-10 14:23:57 | 显示全部楼层
要努力不要命 发表于 2017-11-10 11:18
因为寄存器是32位的,就顺手这样写了吧

寄存器是32位没错,但我觉得这里GPIO_Pin并貌似不是寄存器,而是用来操作I/O,给I/O赋值用的,一组I/O 16个引脚,所以用一个16位的值来定义引脚,一一对应,对应第n位是1表示第n个引脚,所以还是不明白为什么用32位,虽然32位也不会有错,难道是因为32位单片机按32操作比较高效?
回复 支持 反对

使用道具 举报

发表于 2017-11-10 14:27:49 | 显示全部楼层
拖延症晚期 发表于 2017-11-10 14:23
寄存器是32位没错,但我觉得这里GPIO_Pin并貌似不是寄存器,而是用来操作I/O,给I/O赋值用的,一组I/O 16 ...

用一个32位的变量来装16位的数,而且实际运算的时候也只是低16位有效,估计顺手写成32的了吧。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-10 14:31:33 | 显示全部楼层
明白了,谢谢2楼还有火哥
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-10 15:10:15 | 显示全部楼层
本帖最后由 拖延症晚期 于 2017-11-10 15:25 编辑

谢谢两位解惑,我自己再补充一点吧,刚刚又仔细看了中文参考手册,stm32f4xx_gpio.c中有下面的函数
  1. void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  2. {
  3.   __IO uint32_t tmp = 0x00010000;

  4.   /* Check the parameters */
  5.   assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  6.   assert_param(IS_GPIO_PIN(GPIO_Pin));

  7.   tmp |= GPIO_Pin;
  8.   /* Set LCKK bit */
  9.   GPIOx->LCKR = tmp;
  10.   /* Reset LCKK bit */
  11.   GPIOx->LCKR =  GPIO_Pin;
  12.   /* Set LCKK bit */
  13.   GPIOx->LCKR = tmp;
  14.   /* Read LCKK bit*/
  15.   tmp = GPIOx->LCKR;
  16.   /* Read LCKK bit*/
  17.   tmp = GPIOx->LCKR;
  18. }
复制代码

使用GPIO_Pin给LCKR赋值时先把它赋给一个临时变量 tmp,而该变量是32位,查了一下参考手册,如下

可以看到该寄存器只允许32位操作,所以我想在 GPIO_InitTypeDef 中吧GPIO_Pin定义为32位可能是因为有这一类需要32位的操作吧,这样比较方便,不需要再重新转换为32位,而对于需要16位的操作,定义为32位也不会有影响,取低16位有效位即可
所以用uint16_t或uint32_t应该是习惯问题

以上,只是个人见解




1.jpg
回复 支持 反对

使用道具 举报

发表于 2017-11-10 15:38:35 | 显示全部楼层
拖延症晚期 发表于 2017-11-10 15:10
谢谢两位解惑,我自己再补充一点吧,刚刚又仔细看了中文参考手册,stm32f4xx_gpio.c中有下面的函数

使用 ...

你理解的对         
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 07:44 , Processed in 0.031871 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表