江协科技/江科大-STM32入门教程-3.GPIO结构、GPIO输出

目录

GPIO简介

GPIO的基本结构

GPIO位结构(每一位的具体电路结构)

GPIO工作模式(8种)

参考手册

LED和蜂鸣器介绍

LED和蜂鸣器的硬件电路

面包板的使用方法

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_stm32江协大 csdn-CSDN博客文章浏览阅读3.4k次,点赞47次,收藏143次。江协科技/江科大-STM32标准库开发-各章节详细笔记-传送门至各个章节笔记。基本上课程讲的每句都详细记录,方便回顾。_stm32江协大 csdnhttps://blog.csdn.net/m0_61712829/article/details/132434192?spm=1001.2014.3001.5501

GPIO模块分为GPIO输出和GPIO输入,本文章是主要讲解GPIO输出部分以及一些目录展示的其余内容。后面文章也会提供三个程序学习。第一个是LED闪烁,第二个是LED流水灯,第三个是蜂鸣器。


GPIO简介

GPIO(General Purpose Input Output)通用输入输出口。

可配置为8种输入输出模式。

引脚电平:0V~3.3V,部分引脚可容忍5V。(0v就是低电平是数据0,3.3v是高电平是数据1。容忍5v意思是可以在这个端口输入5v的点电压,也认为是高电平,但是对于输出而言,最大就只能输出3.3v,因为供电就只有3.3v,具体哪些端口能容忍5v,可以参考一下stm32的引脚定义,带FT的就是可以容忍5v,不带FT的就只能接入3.3v电压)

输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等。(后面文章显示的LED和蜂鸣器的程序现象,就使用到了GPIO的输出模式。另外在其他的应用场景,只要是可以用高低电平来进行控制地方都可以用GPIO来完成;如果控制的是功率比较大的设备,只需要再加入驱动电路即可;此外,还可以用GPIO来模拟通信协议,比如I2CC、spi或某个芯片特定协议,我们都可以用GPIO的输出模式来模拟其中的输出时序部分)

输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等。(输入模式最常见的就是读取按键了,用来捕获我们的案件按下事件;另外,也可以读取带有数字输出的一些模块,比如,光敏电阻模块、热敏电阻模块等;如果这个模块输出的是模拟量,那GPIO还可以配置成模拟输入模式,再配合内部的ADC外设,就能读取端口的模拟电压了;除此之外,模拟通信协议时,接收线上的通信数据,也是靠GPIO的输入来完成的)


GPIO的基本结构

如下,为GPIO的整体构造,其中左边的是APB2外设总线;在stm32中所有的GPIO都是挂载在APB2外设总线上的,其中GPIO外设的名称都是按照GPIOA、GPIOB等等这样来命名的,每个GPIO外设,总共有16个引脚,编号是从0到15,GPIO的第0号引脚,我们一般把它称为PA0,接着第一号就是PA1..PA15以此来命名;

在每个GPIO模块内,组要包含了寄存器和驱动器,寄存器就是一段特殊的存储器,内核可以通过APB2总线对寄存器进行读写,这样就可以完成输出电平和读取电平的功能了,寄存器的每一位对应一个引脚,其中,输出寄存器写1,对应的引脚就会输出高电平,写0就会输出低电平,输入寄存器读取为1,就证明对应的端口目前是高电平,读取为0,就是低电平;

因为STM32是32位单片机,所以STM32内部的寄存器都是32位的,但这个端口只有16位,所以这个寄存器只有低16位对应的有端口,高16位是没有用的;

驱动器是用来增加信号的驱动能力,寄存器只负责存储数据,如果要进行点灯这样的操作,还是需要驱动器来负责增大驱动能力。

如下,这些就是GPIO的整体基本结构了。


GPIO位结构(每一位的具体电路结构)

如下图为,stm32参考手册中的GPIO位结构的电路图。

左边三个就是寄存器,中间部分是驱动器,右边是某一个IO口的引脚,如下三个红圈里的内容。

 整体结构可以分为两个部分,上面是输入部分,下面是输出部分。

一、首先,输入部分

1.首先是这个IO引脚,这里接了两个保护二极管,这个是对输入电压进行限幅的,上面二极管接VDD,3.3V,下面二极管接VSS,0V;如果输入电压比3.3v还要高,那上方这个二极管就会导通,输入电压产生的电流就会直接流入VDD而不会流入内部电路,这样就可以避免过高的电压对内部电路产生伤害。

如果输入电压比0v还要低,这个电压是相对与VSS的电压,所以是可以有负电压的,那这时下方这个二极管就会导通,电流会从VSS直接流出来,电流会从VSS直接流出去,而不会从内部电路汲取电流,也是可以保护内部电路的。

 如果输入电压在0-3.3v之间,那两个保护二极管均不会导通,这时二极管对电路没有影响,这就是保护二极管的用途

2.上拉和下拉电阻

上拉和下拉的作用:是为了给输入提供一个默认的输入电平,因为对应一个数字的端口,输入不是高电平就是低电平;如果输入引脚哈都不接,这时输入就会处于一个浮空状态,引脚的输入电平极易受外界干扰而改变;为了避免引脚悬空导致的输入数据不稳定,我们就需要在这里加上上拉或下拉电阻

上拉电阻至VDD,下拉电阻至VSS,这个开关是可以通过程序进行配置的。

上面导通、下面断开,就是上拉输入模式;上面断开、下面导通,就是下拉输入模式;上面断开、下面断开,就是浮空输入模式。

如果接入上拉电阻,当引脚悬空时,还有上拉电阻来保证引脚的高电平,所以上拉输入是默认为高电平的输入模式,下拉也是同理。

上拉电阻和下拉电阻的阻值都是比较大的,是一种弱上拉和弱下拉 ,目的是尽量不影响正常的输入操作。

 3.TTL肖特基触发器

实际上这个应该是斯密特触发器(应该是一个翻译错误)。如下:

 施密特触发器的作用:是对输入电压进行整形

它的执行逻辑是:如果输入电压大于某一阈值,输出就会瞬间升为高电平,如果输入电压小于某一阈值,输出就会瞬间降为低电平。

例子:因为这个引脚的波形是外界输入的(IO口输入),虽然是数字信号,实际情况可能会产生各种失真,比如,如下波形夹杂了波动的高低变化的电平信号(下图,红色线),如果没有施密特触发器,那很有可能因为干扰而导致误判,如果有了施密特触发器,那比如定一个阈值上限和下限(下图中绿色线),高于上限输出高,低于下限输出低,如下图蓝色为施密特信号,图中的第一个蓝色圈虽然由于波动再次低于上限了,但是对于施密特触发器来说,只有高于上限或者低于下限,输出才会变化,所以此时低于上限的情况,输出并不会变化,而是继续维持高电平,然后直到下次低于下限时,才会转为低电平,第二个蓝色圈信号即使在下限附近来回横跳,因为没有跳到上限上面去,所以输出仍然是稳定的,直到下一次高于上限,输出才会变成高电平,如下蓝色线就是施密特触发器的输出信号了,可以看到,相比较输入信号,经过整形的信号就很完美。在这里使用了两个比较阈值来进行判断,中间留有一定的变化范围(上下绿色阈值线),可以有效的避免因信号波动造成的输出抖动现象。

施密特前(右)是模拟量,后(左)是01组成的数字量

 接下来,经过施密特触发器整形的波形就可以直接写入输入数据寄存器了,我们再用程序读取输入数据寄存器对应某一位的数据,就可以知道端口的输入电平了;

最后,上面还有两路线路,是连接到片上外设的一些端口;其中一个是模拟输入,这个可以连接到ADC上,因为ADC需要接受模拟量,所以这根线是接到施密特触发器前面的,另一个是复用功能输入,这个是连接到其他需要读取端口的外设上的(比如,串口的输入引脚等),这根线接受的是数字量,所以在施密特触发器后面。

 二、输出部分

1.输出部分由输出数据寄存器或片上外设控制,两种控制方式通过这个数据选择器接到输出控制部分;如果选择通过输出数据寄存器进行控制,就是普通的IO口输出,写这个输出数据寄存器的某一位就可以操作对应的某个端口了。

2.左边还有个叫做位设置/清除寄存器,这个可以用来单独操作输出寄存器的某一位,而不影响其它位,因为这个输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以如果想单独控制其中的某一个端口而不影响其它端口的话,就需要一些特殊的操作方式(第一种方式是,先读出这个寄存器,然后用按位与和按位或的方式更改某一位,最后再将更改后的数据写回去,在c语音中就是&=和|=的操作,这种方法比较麻烦,效率不高,对于IO口的操作而言不太合适;第二种方式是,通过设置这个位设置和位清除寄存器,如果我们要对某一位进行置1的操作,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样它内部就会有电路,自动将输出数据寄存器中对应位置为1,而剩下写0的位则保持不变,这样就保证了只操作其中某一位而不影响其他位,并且这是一步到位的操作;如果想对吗一位进行清0操作,就在位清除寄存器的对应位写1即可,这样内部电路就会把这一位清0了。第三种方式,就是读写stm32中的“位带”区域,在stm32中,专门分配的有一段地址区域,这段地址映射了RAM和外设寄存器所有的位,读写这段地址中的数据,就相当于读写所映射位置的某一位,这就是位带的操作方式。)库函数使用的是读写位设置和位清除寄存器的方法。

左边图为,数据选择器

 3.输出控制之后就接到了两个MOS管

上面是P-MOS,下面是N-MOS,这个MOS管就是一种电子开关,我们的信号来来控制开关的导通和关闭,开关负责将IO口接到VDD或者VSS,在这里可以选择推挽、开漏或关闭三种输出方式

3.1 在推挽输出模式下,P-MOS和N-MOS均有效,这种模式下,高低电平均有较强的驱动能,所以推挽输出模式也可以叫强推输出模式,在推挽输出模式下,stm32对IO口具有绝对的控制权,高低电平都由stm32说的算。

数据寄存器为1时。上管导通,下管断开,输出直接接到VDD,就是输出高电平。

 数据寄存器为0时。上管断开,下管导通,输出直接接到VSS,就是输出低电平。

 3.2 在开漏输出模式下,这个P-MOS是无效的,只有N-MOS在工作;

这种模式下,只有低电平有驱动能力,高电平是没有驱动能力的

这个模式的用处在于可以作为通信协议的驱动方式,比如IIC通信的引脚,就是使用开漏模式。在多机通信的情况下,这个模式可以避免各个设备的相互干扰;

另外,开漏模式还可以用于输出5v的电平信号,比如在IO口外接一个上拉电阻到5v的电源,当输出低电平时,由内部的N-MOS直接接VSS,当输出高电平时,由外部的上拉电阻拉高至5v,这样就可输出5v的电平信号,用于兼容一些5v电平的设备,以上就是开漏输出的主要用途。

数据寄存器为1时。下管断开,这时输出相当于断开,也就是高阻模式

 

 数据寄存器为0时。下管导通,输出直接接到VSS,也就是输出低电平

 

 3.3 关闭状态输出方式

这个是当引脚配置为输入模式的时候,这两个MOS管都无效,也就是输出关闭,端口的电平由外部信号来控制。


GPIO工作模式(8种)

通过配置GPIO的端口配置寄存器,上面的位结构的电路就会根据我们的配置进行改变(比如,开关的通断、N-MOS和P-MOS是否有效、数据选择器的选择等),端口可以配置成以下8种模式:

模式名称

性质

特征

浮空输入

数字输入

可读取引脚电平,若引脚悬空,则电平不确定

上拉输入

数字输入

可读取引脚电平,内部连接上拉电阻,悬空时默认高电平

下拉输入

数字输入

可读取引脚电平,内部连接下拉电阻,悬空时默认低电平

模拟输入

模拟输入

GPIO无效,引脚直接接入内部ADC

开漏输出

数字输出

可输出引脚电平,高电平为高阻态,低电平接VSS

推挽输出

数字输出

可输出引脚电平,高电平接VDD,低电平接VSS

复用开漏输出

数字输出

由片上外设控制,高电平为高阻态,低电平接VSS

复用推挽输出

数字输出

由片上外设控制,高电平接VDD,低电平接VSS

1.首先是前三个,浮空输入、上拉输入、下拉输入

这三个模式的电路结构基本是一样的,区别就是上拉电阻和下拉电阻的连接,它们都属于数字的输入口,特征就是,都可以读取端口的高低电平;当使用浮空输入时,端口一定要接上一个连续的驱动源,不能出现悬空状态。

这三种模式的电路结构如下,可以看到,在输入模式下,输出驱动器是断开的,端口只能输入而不能输出;上面这两个电阻可以选择位上拉工作、下拉工作或者都不工作,对应的就是上拉输入、下拉输入和浮空输入,然后输入通过施密特触发器进行波形整形后,连接到输入数据寄存器,另外这个输入保护这里写的是VDD或VDD_FT(这就是3.3v端口和容忍5v端口(它的上面保护二极管要做一下处理,要不然直接接VDD3.3v的话,外部再接入5v电压就会导致上边二极管开启,并且产生比较大的电流,这个是不太妥当的)的区别)

 2. 模拟输入

这个模拟输入,可以说是ADC模数转换器的专属配置了,模拟输入的结构如下。

这里输出是断开的,输入的施密特触发器也是关闭的无效状态,所以整个GPIO大部分都是无效的,只有下图的红色线有效,也就是从引脚直接接入片上外设,也就是ADC,所以当我们使用ADC的时候,将引脚配置位模拟输入就行了,其他时候吗,一般用不到模拟输入。

 3.开漏输出和推挽输出

这两个电路结构也基本一样,数字输出,可以用于输出高低电平,区别就是开漏输出的高电平呈现的是高阻态,没有驱动能力,而推挽输出的高低电平都是具有驱动能力的,这两种模式的电路结构如下:

输出是由输出数据寄存器控制的,这个P-MOS无效就是开漏输出,如果P-MOS和N-MOS都有效,就是推挽输出;另外,在输出模式下,输入模式也是有效的(在上面电路,在输入模式下,输出无效;因为,一个端口只能有一个输出,但可以有多个输入,所以当配置成输出模式时,内部也可以顺便输入一下)。

 4.复用开漏输出和复用推挽输出

这两模式和普通的开漏输出和推挽输出差不多,只不过是复用的输出,引脚电平是由片上外设控制的,模式结构如下:

通用的输出是没有连接的,引脚的控制权转移到了片上外设,由片上外设控制,在输入部分,片上外设也可以读取引脚的电平,同时普通的输入也是有效的,顺便接收一下电平信号。

 在GPIO的8种模式下,除了模拟输入这个模式会关闭数字的输入功能,在其它的7个模式中,所有的输入都是有效的。不全之处,可参考手册查阅。


参考手册

 当使用片上外设的引脚时,可以参考这个表里给的配置

 可以看一下GPIO寄存器描述

首先是GPIO配置寄存器,每一个端口的模式由4位进行配置,16个端口就需要64位,所以这里的配置寄存器有两个,一个是端口配置低寄存器,一个是端口配置高寄存器,可以看介绍进行配置。

GPIO的输出速度可以限制输出引脚的最大翻转速度,这个设计出来,是为了低功耗和稳定性的,我们一般要求不高时一般配置成50MHz就可以了。

 

 如下为,端口输入数据寄存器。

就是上面GPIO位结构的输入数据寄存器,里面的低16位对应16个引脚,高16位没有使用

如下为,端口输出数据寄存器,也就是上面GPIO位结构的输出数据寄存器,同样,低16位对应16个引脚,高16位没有使用

 如下为,端口位设置/清除寄存器,也就是上面GPIO位结构的那部分寄存器,这个寄存器的低16位是进行位设置的,高16位是进行位清除的。写1就是设置或者清除,写0就是不产生影响。

 

 如下为,端口位清除寄存器,低16位是进行位清除的。

这个是为方便操作设置的,如果只想单一的进行设置或者位清除,位设置用上面寄存器,位清除用下面这个寄存器,因为在设置和清除时,使用的都是低16位的数据,这样就方便一些;如果想对多个端口同时进行位设置和位清除,那就使用第一个寄存器就行了,这样可以保证位设置和位清除的同步性,当然你要对信号的同步性要求不高的话,先位设置再位清除也是没问题的

 

 如下为,端口配置锁定寄存器。

这个可以对端口的配置进行锁定,防止意外更改,使用方法看介绍,这个我们暂时用的不多

 目前,有关stm32内部的GPIO外设,我们就讲完了

接下来,我们看一下stm32外部的设备和电路。


LED和蜂鸣器介绍

LED:发光二极管,正向通电点亮,反向通电不亮

有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定

无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音

LED电路符号如下,左边是正级,右边是负极

如下为LED实物图,如果引脚没有剪过,长脚为正极,短脚为负极 。通过LED内部也可以看正负极,较小的一半是正极,较大的一半是负极

 有源蜂鸣器内部电路如下左图,这里用了一个三极管开关进行驱动,我们将VCC和GND分别接上正负极的供电,然后中间引脚2接低电平,蜂鸣器就会响,接高电平,蜂鸣器就关闭,

LED和蜂鸣器的硬件电路

1.如下两个图是使用stm32的GPIO口驱动LED的电路。

这里的限流电阻一般都是要接的,一方面它可以防止LED因为电流过大而烧毁,另一方面它可以调整LED的亮度,如果你觉得LED太亮可以适当的增大限流电阻的阻值。

针对选择电平驱动哪个方式:就得看IO口高低电平的驱动能力如何了,上面讲到,GPIO的推挽输出模式下,高低电平均有较强的驱动能力,所以两种方式都可以;在单片机的电路里,一般倾向使用第一种,低电平驱动的方式,因为很多单片机或者芯片,都使用了高电平弱驱动,低电平强驱动的规则,这样可以一定程度上避免高低电平打架,所以使用高电平驱动能力弱那就不能使用第二种连接方式了。

下图是低电平驱动的电路,LED正极接3.3v,负极通过一个限流电阻接到PA0上,当PA0输出低电平时,LED两端就会产生电压差,就会形成正向导通的电流,这样LED就会点亮了;当PA0输出高电平时,因为LED两端都是3.3v的电压,不会形成电流,所以高电平LED就会熄灭。

下图是高电平驱动的电路。LED负极接到GND,正极通过一个限流电阻接到PA0上,这时就是高电平点亮,低电平熄灭。

 

 2.下面为蜂鸣器电路

这里使用了三极管开关的驱动方案,三极管开关是最简单的驱动电路了,对于功率稍微大一点的 ,直接用IO口驱动会导致STM32负担过重,这时可以用一个三极管驱动电路来完成驱动任务

需要注意,PNP的三极管最好接在上边,NPN的三极管最好接到下边,这是因为三极管的通断是需要在发射极和基极产生一定的开启电压的,如果将负载接在发射极这边,可能会导致三极管不能开启。

下图为PNP三极管的驱动电路,三极管的左边是基极,带箭头的是发射极,剩下的是集电极。左边的基极给低电平,三极管就会导通,再通过3.3V和GND就可以给 蜂鸣器提供驱动电流了。基极给高电平,三极管截止,蜂鸣器没有电流。

 下图为NPN三极管的驱动电路,同样,左边是基极,带箭头的是发射极,剩下的是集电极;它的驱动逻辑和上面的是相反的,基极给高电平导通,低电平断开。


面包板的使用方法

当我们把原件的引脚插到面包板的孔里时,它内部的金属爪就会抓住引脚;

金属爪的排列规律是:中间的金属爪是竖着放的,上下四排是连在一个的四个整体的金属爪。那就对应这个面包板的孔的连接关系。竖着的五个孔内部是连接在一起的,如下,这样我们元件插在一纵排的不同孔位时,内部的金素爪就实现了线路的连接。

 上下四排孔整体是连在一起的,这四排是用于供电的,标有正负极;如果我们需要供电,就从上下的孔位中,用跳线印出来即可。另外,再说明一下,这个供电的引脚,有的面包板并不是一整排都是连接的(如果中间是断开的,用跳线再连接起来)

 演示:若用面包板实现电源点亮一个LED等的电路

首先,把上面两排的供电引脚接上电源的正负极,然后用跳线将正极引下来到一个孔(5孔其1)里,然后在纵向下面的孔,横着插一个限流电阻到右边的孔,横着插一个LED到右边的孔,然后再用跳线把右边引到负极。这样就可以了。

 

面包板正面如下:

面包板背面(金属爪)

金属爪示意图

  • 35
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
GPIO输入输出有多种模式,包括: 1. 模拟输入模式(GPIO_Mode_AIN):用于接收模拟信号的输入。 2. 浮空输入模式(GPIO_Mode_IN_FLOATING):输入不连接到任何电源或地,可以通过外部电路来控制输入。 3. 下拉输入模式(GPIO_Mode_IPD):输入连接到地,通过外部电路上拉电阻来控制输入。 4. 上拉输入模式(GPIO_Mode_IPU):输入连接到电源,通过外部电路下拉电阻来控制输入。 5. 开漏输出模式(GPIO_Mode_Out_OD):输出为开漏结构,可以通过外部电路连接到其他设备。 6. 推挽输出模式(GPIO_Mode_Out_PP):输出为推挽结构,可以提供较高的输出电流。 7. 复用开漏输出模式(GPIO_Mode_AF_OD):输出为开漏结构,并且与其他功能模块共享引脚。 8. 复用推挽输出模式(GPIO_Mode_AF_PP):输出为推挽结构,并且与其他功能模块共享引脚。 这些模式可以根据具体的应用需求选择,例如需要输入模拟信号时可以选择模拟输入模式,需要输出信号给其他设备时可以选择开漏输出或推挽输出模式。同时,每个GPIO口还可以通过编程来设置其模式。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [GPIO输入输出模式原理(八种工作方式附电路图详解)](https://blog.csdn.net/zhuguanlin121/article/details/118489092)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿齐Archie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值