STM32标准库中的GPIO_Pin_N与GPIO_PinSourceN话题

最近做项目遇到这个问题,上网看到这篇文章,感觉很好,是人家的实际项目中总结出来的,转载过来,用以学习交流。一开始我也是分不清这两个参数的定义,总是以为是一样的,没注意他们的区别,以至于在按键消抖上面,总是不能很好的消抖,按下按键屏幕老是闪一下。原因就是我把该写GPIO_Pin_N的写成了GPIO_PinSourceN,其实这点和keil官方的MDK有关系,手写代码的时候,编辑器首先提示的是GPIO_PinSourceN,我就直接确定了。没想到是错误的。

下面是原文:(链接:http://www.51hei.com/bbs/dpj-40992-1.html)

某日,有个工程师电话跟我交流,他在使用STM32F042芯片开发产品,用到其中的硬件I2C。利用ST官方提供的标准固件库开发应用软件。他说发现I2C功能基本不受控,尤其令他奇怪的是,I2C即使关闭了,却发现I2C脚上还有脉冲出现。

他问我是否STM32F0芯片在I2C这里做了什么特别的调整,因为他之前用过STM32F1系列的芯片。我心想,再怎么调整也不应该调整出这个效果啊,我首先怀疑他代码是否哪里有问题,尤其I2C及相关GPIO的配置。建议其做与I2C有关的初始化配置代码的检查确认。

后来,他通过QQ留言反馈给我,说找到原因了。原因就是将有关PA9,PA10的复用功能配置语句做了调整就OK。显然,这里PA9,PA10是被复用为I2C通信脚。

STM32标准库中的GPIO_Pin_N与GPIO_PinSourceN话题_第1张图片


调整前的代码
GPIO_PinAFConfig(GPIOA,GPIO_Pin_9,GPIO_AF_4);
GPIO_PinAFConfig(GPIOA,GPIO_Pin_10,GPIO_AF_4);

调整后的代码
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_4);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_4);


不难看出,该工程师调整的就是上面红色参数部分。一个是GPIO_Pin_N,一个是GPIO_PinSourceN,其实这2个参数是不一样的。

GPIO_Pin_n可以理解为某端口脚在整个端口的位置。比方某GPIO口的第6管脚位置编码GPIO_Pin_6 被定义为 ((uint16_t)0x0040) ,对相应GPIO管脚做基本属性配置时会用到,如配置输入输出模式、模拟输入模式的选择等。有兴趣的话,可以点击GPIO_Init( )进去看看。

GPIO_PinSourceN一般是在对某GPIO口相应pin脚的复用功能进行选择配置才会用到。它是根据端口各脚位的位置按顺序从0开始依次递增编号,可以理解为该管脚在该端口的序号。比方某GPIO口的第6号复用功能脚的序号GPIO_PinSource6 被定义为 ((uint8_t)0x06) 。有兴趣的话,也可以打开GPIO_PinAFConfig( )函数看看。显然,GPIO_PinSource6跟上面的GPIO_Pin_6的值相差甚远。


下面是ST官方库代码中有关GPIO_Pin_N的定义:

#define GPIO_Pin_0 ((uint16_t)0x0001)

#define GPIO_Pin_1 ((uint16_t)0x0002)

#define GPIO_Pin_2 ((uint16_t)0x0004)

#define GPIO_Pin_3 ((uint16_t)0x0008)

#define GPIO_Pin_4 ((uint16_t)0x0010)

#define GPIO_Pin_5 ((uint16_t)0x0020)

#define GPIO_Pin_6 ((uint16_t)0x0040)

#define GPIO_Pin_7 ((uint16_t)0x0080)

#define GPIO_Pin_8 ((uint16_t)0x0100)

#define GPIO_Pin_9 ((uint16_t)0x0200)

#define GPIO_Pin_10 ((uint16_t)0x0400)

。。。。。。

#define GPIO_Pin_15 ((uint16_t)0x8000)

#define GPIO_Pin_All ((uint16_t)0xFFFF)

下面是有关GPIO_PinSourceN的定义:

#define GPIO_PinSource0 ((uint8_t)0x00)

#define GPIO_PinSource1 ((uint8_t)0x01)

#define GPIO_PinSource2 ((uint8_t)0x02)

#define GPIO_PinSource3 ((uint8_t)0x03)

#define GPIO_PinSource4 ((uint8_t)0x04)

#define GPIO_PinSource5 ((uint8_t)0x05)

#define GPIO_PinSource6 ((uint8_t)0x06)

#define GPIO_PinSource7 ((uint8_t)0x07)

#define GPIO_PinSource8 ((uint8_t)0x08)

#define GPIO_PinSource9 ((uint8_t)0x09)

#define GPIO_PinSource10 ((uint8_t)0x0A)

。。。。。。

#define GPIO_PinSource15 ((uint8_t)0x0F)


小结:上面的问题只有基于STM32官方固件库开发时才会碰到。说实在的,这两个参数的确容易让人误解成一个东西或者弄混淆,尤其刚接触的人。经常有人在这个地方遇到麻烦,之前我在一篇文章中提到过。这里再特意提醒下。

不过ST官方后来推出的STM32CUBE库在这个地方的代码写法做了调整,不再定义GPIO_PinSourceN。当然,因为管脚配置导致异常的问题时有发生,建议使用ST官方推出的STM32CUBE配置环境及CUBE参考固件库着手开发,这样会省不少事。


你可能感兴趣的:(stm32)