STM32标准库中的GPIO_Pin_N与GPIO_PinSourceN话题

发布者:BlissfulSpirit最新更新时间:2018-06-26 来源: eefocus关键字:STM32  标准库 手机看文章 扫描二维码
随时随地手机看文章

最近做项目遇到这个问题,上网看到这篇文章,感觉很好,是人家的实际项目中总结出来的,转载过来,用以学习交流。一开始我也是分不清这两个参数的定义,总是以为是一样的,没注意他们的区别,以至于在按键消抖上面,总是不能很好的消抖,按下按键屏幕老是闪一下。原因就是我把该写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通信脚。



调整前的代码
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  标准库 引用地址:STM32标准库中的GPIO_Pin_N与GPIO_PinSourceN话题

上一篇:趣谈STM32的ADC与DMA
下一篇:STM32之呼吸灯实验

推荐阅读最新更新时间:2024-03-16 16:06

STM32 IAP 在线更新程序问题
搞了一天才发现 在MDK设置选项中有个 linker 选项卡 , 需要在Project- Options- Linker中将Use Memory Layout from Target Dialog前面的复选框勾上 一切就正常了 Use Memory Layout from Target Dialog这个选项有个“分散加载文件”的概念。 下边的三段话是我从网上摘抄的(MDK程序下载到flash--分散加载文件scatter),大概了解了一下,以后如果会用到这方面的知识再来深入研究。 前边三个分散加载文件是从别的地方拷过来的,用在自己的程序中可能会有问题,因为如果不修改它的话就固定了加载地址和运行地址,如果程序简单又比较
[单片机]
STM32的i2c容易出的问题 和l3g4200d例程
调试了一晚上,终于一点点把stm32可怕的i2c消灭了,这里分享一下遇到的问题。 最严重的一次卡住居然是在这句话上 /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 执行到第二句就怎么也过不去了,后来才很气愤的发现这是stm32的硬件bug,把fsmc关掉才能使用i2c1的非重影射引脚,关掉以后一切正常。害得我干瞪了两个小时屏幕。 第二次被卡住是在 I2C_Send7bitAdd
[单片机]
STM32 ADC转换时间
STM32F103XX的ADC的采样时钟最快14MHz,最快采样率1MHz。 ADC时钟: 这个ADC时钟是从哪来的呢。我们看下面这个STM32的时钟结构图: 我们大多使用STM32的最快PCLK2系统时钟72MHz。 ADCCLK的时钟由72MHz的6分频能瞒住14MHz以下的要求 为12MHz。 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12,ADC最大时间不能超过14M ADC转换时间: 有如下公式: TCONV = 采样时间+ 12.5 个周期 其中12.5个周期是采集12位AD时间是固定的,另外一个采样时间可以取下面几个参数由SMPx 寄存器控制,每个通道可以单独配置
[单片机]
<font color='red'>STM32</font> ADC转换时间
STM32-嵌入式学习笔记02-中断应用概述
本节目标: 通过DMA,无需中断,接收不定时长的串口数据 描述: 当在串口多数据传输下,CPU会产生多次中断来接收串口数据,这样会大大地降低CPU效率,同时又需要CPU去做其它更重要的事情,我们应该如何来优化? 比如四轴飞行器,当在不停地获取姿态控制方向时,又要去接收串口数据. 答:使用DMA,无需CPU中断便能实现接收串口数据 1.DMA介绍 DMA,全称为: Direct Memory Access,即直接存储器访问, DMA 传输方式无需 CPU 直接 控制传输,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。 2在main()中调用串口配置函数,初始化串口后,然后使能U
[单片机]
STM32-嵌入式学习笔记02-中断应用概述
单片机STM32的引脚模式设置运用理解
单片机STM32的引脚有多种方式可以选择。 如果你是用直接写寄存器来配置的话,那么,看上手册,给“配置寄存器”对应的位写0或者1就可以达到目的。如下图: 如果是用库函数来配置的话,就需要知道下面这个结构体中的变量代表的意义。 库函数,选择好GPIO_Mode之后,就要使用GPIO_Init()函数来配置,你可以打开这个配置函数,实际上也是在对“配置寄存器”进行写操作。 先解释一下这个结构体中的各个变量的意思: GPIO_Mode_AIN:模拟输入模式 GPIO_Mode_IN_FLOATING:浮空输入模式 GPIO_Mode_IPD:下拉输入模式 GPIO_Mode_IPU:上拉输入模式 GPIO_Mode_Out
[单片机]
单片机<font color='red'>STM32</font>的引脚模式设置运用理解
STM32生态系统 密码学原理的应用-TLS
密码学原理的典型应用:TLS TLS:即传输层安全 基于密码学原理的通信协议 实现服务器和设备之间的认证通信和数据加密 TLS握手协议 通信双方的相互确认 协商会话密钥 TLS握手 v1.2 (RFC 5246) CA证书:包含的是CA的公钥,用来核实该CA颁发给别人的证书的真实性 服务器/IoT设备的证书:包含了自己的公钥 通过公钥加密的消息,只能私钥拥有者可以解密 可以签证由对应私钥签名的消息的完整可靠性 服务器/IoT设备的私钥:用来为自己发送的消息签名 至此,通过“挑战-应答”机制,IoT设备端已经确认是和真正的目标服务器在通信 服务器的证书是有效的(CA保证,通过CA公钥验证成功) 对
[单片机]
<font color='red'>STM32</font>生态系统 密码学原理的应用-TLS
STM32 软件模拟SPI时序驱动NRF24L01
其实stm32本身的硬件SPI也很好用,但是还是想用软件来模拟一下PSI的时序。 SPI 是一种高速的,全双工,同步串行的通信总线。SPI通信方式相当于是一个环形结构,由CSN、MISO、MOSI、SCLK四线组成,主要是在SCLK时钟线的驱动下,进行数据转换。 接下来直接上程序配置: 使用32模拟SPI时序的IO口配置,应该注意的是MISO应该选择模拟输入方式GPIO_Mode_IN_FLOATING。 以下是我的初始化部分: /*用于软件模拟SPI IO口宏定义区*/#define SPI_CS_PORT GPIOB#define SPI_CS_PIN GPIO_Pin_11#define SPI_CS_LOW
[单片机]
<font color='red'>STM32</font> 软件模拟SPI时序驱动NRF24L01
基于STM32的三相多功能电能表解决方案
   背景   电能表作为电能计量的基本设备,受到国家电力部门的长期重视,电能表生产企业更是不遗余力地寻求设计与开发性能俱佳且成本更低的解决方案。目前国内的电能表设计已经走过了由8位MCU向通用DSP甚至专用DSP的变革,通用DSP的应用方案的劣势在于DSP的专业应用和嵌入程度不够深的问题,成本偏高;而专用DSP功能相对固定,这样给电能表设计和生产厂家带来功能差异化空间不足的困难。基于ARM的方案也已经出现,但是适合应用的ARM7 TDMI在性能上不尽人意,同时外设资源不足;而更高端的ARM9系统的复杂程度很高,成本也较高。选择一颗合适且低成本的微处理器日益成为电能表行业的关键所在,直到意法半导体公司(STMicroelect
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved