技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 357|回复: 0
收起左侧

【单片机】正确理解GPIO

[复制链接]

1010

主题

2246

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
200
威望
265 点
宅币
16897 个
贡献
33683 次
宅之契约
0 份
在线时间
1608 小时
注册时间
2014-1-26
发表于 2018-4-1 09:40:10 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
不少人刚学单片机入门的时候经常会遇到一些令人摸不着头脑(然而用搜索引擎一搜就知道答案)的疑问。

比如:
  • 为啥我的开发板的GPIO口连着一个LED灯,但这个LED灯是低电平亮灯、高电平熄灯?
  • 为啥我用GPIO口接了一个马达,但是我输出高电平并不能使马达转起来——看起来电流好弱?
  • 为啥GPIO口有Push Pull模式和Open Drain模式?它们分别是什么作用?
  • 为啥我把GPIO口的弱电流用三极管放大后,我用它驱动马达会导致我的单片机重启?
  • STM32F10x启动的时候我能不能一次性把所有的GPIO口都初始化了?为什么很多人都只初始化自己用得到的GPIO口?


虽然这些疑问都来源于物理学没学好(搜索引擎不会用)带来的问题,但你光是丢下一句“你物理不好,回去补物理去”(“自己
度、
歌去”)
是不能帮助他们解决这些问题的。

为啥我的开发板的GPIO口连着一个LED灯,但这个LED灯是低电平亮灯、高电平熄灯?


很简单——这个LED的正极接的是5V、3.3V电源(取决于板子),然后负极接的是你的GPIO口。

当你的GPIO口输出高电平的时候,它抵消了你的LED灯的正极的电压,于是就没有电流从LED灯中流过了。

而如果你的GPIO口输出的是低电平,相当于0V,也就是接地。此时你的LED灯的负极就没有电压了,它就亮起来了。

为啥我用GPIO口接了一个马达,但是我输出高电平并不能使马达转起来——看起来电流好弱?


GPIO口输出的电压和你的单片机输入的电源的电压是相同的,但电流则是减弱了的。这样的电流是无法驱动马达的,因为功率太低。

GPIO是用来控制其它机器的开关的,它本身不能作为其它机器的电源来使用。原因是:如果绝大多数的电流都走你的GPIO口出去了,你的单片机就会供电不足,导致运行不正常。

所以GPIO口的输出是接了个电阻的。这个电阻可以保证单片机的核心有足够的电压和电流来保证它的运算逻辑能正常运行。

你可以用一个三极管来放大你的GPIO口输出的信号,从而驱动外部机器。但不要忘了尽量保证有足够的电流和电压驱动你的单片机。

为啥GPIO口有Push Pull模式和Open Drain模式?它们分别是什么作用?


这个根据不同的单片机设计是有不同的解释的。具体要看单片机对应的手册。但常见的是像下面这样的情况:

Push Pull模式(推拉模式)的特性是:“拉高”的操作相当于这个GPIO口通过一个电阻连接了电源正极(之前所说的输出电压),而“拉低”则相当于这个GPIO口通过一个电阻连接了电源负极。

Open Drain模式(漏极开路)的特性是:“拉高”的操作相当于这个GPIO口啥也没连接(其实是连接了一个三极管,但这个三极管的基极没有输入信号),而“拉低”则和前面说的一样——这个GPIO口通过一个电阻连接了电源负极。

Open Drain模式通常用来维护一个由多个设备组成的总线,也就是串联多个设备的信号输出,并且通常也需要一个额外的电源。这样,当所有串联的设备中有一个设备需要输出信号了,它就会把自己的端口拉低,导致整个总线的电压降低。然后其它所有的设备的输入端就都能检测到电平的降低过程。相当于维护了一个逻辑与门。

相当于一个蓄水池,它上面有个水龙头在不停地放水进到蓄水池里,而连接的设备相当于蓄水池边的人,每个人控制着一个下水口。这个下水口就相当于Open Drain模式的GPIO口了。只要有一个人拉开了下水口的塞子,蓄水池里的水就被放掉了(下水口比水龙头的口大)。然后水池边所有人都知道蓄水池里没有水了。

通常被用于I2C总线和SPI总线的MISO线。在I2C通讯的时候,任何连接的设备拉低端口,都会被检测到。

为啥我把GPIO口的弱电流用三极管放大后,我还是无法用它驱动马达?


马达的电阻太低,导致绝大多数电流经过了马达,你的单片机缺乏足够的电压,不能维持运行。

你的马达依然需要一个电阻,用来提供足够的阻抗,保证有足够的电压和电流经过你的单片机。

看你的单片机的手册,来决定用多大的电阻合适。

STM32F10x启动的时候我能不能一次性把所有的GPIO口都初始化了?为什么很多人都只初始化自己用得到的GPIO口?


答案是:能。但你要保证,你必须在其它所有依赖的库初始化之前再初始化你的GPIO口。

而第二个问题(为什么很多人都只初始化自己用得到的GPIO口?)的回答是:其实也可以初始化全部的口。在STM32F10x启动的时候,这些口,默认都是GPIO_Mode_IN_FLOATING模式,也就是“啥也不接”。这个模式比其它各种模式都省电。设计单片机程序的时候,功耗是一个必须考虑的问题。

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-12-12 19:54 , Processed in 0.098646 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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