带你了解STM32:GPIO通用输入输出口

发布于:2025-09-14 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

3.1 GPIO简介

3.2 GPIO基本结构

3.3 GPIO位结构

输入部分:

二极管的保护作用:

施密特触发器:

片上外设端口

输出部分:

MOS管

3.4 GPIO模式

3.4.1 浮空/上拉/下拉输入

3.4.2 模拟输入

3.4.3 开漏/推挽输出

3.4.4 复用开漏/推挽输出

3.5 LED和蜂鸣器简介

3.5.1 LED和蜂鸣器的硬件电路

参考资料

3.6 面包板(供电区要通过跳线和中间区域连接)

3.7 LED代码

第一步:开启时钟,初始化时钟

第二步:将Delay函数加入工程,添加组,然后,魔术棒添加文件路径

第三步:写代码点亮LED

第四步:按图接线,如果要反接开漏模式,正接推挽模式,LED长线为正

3.8 LED流水灯代码

第一步:按图接线,将LED流水灯,连接到面包板上

第二步:复制LED闪烁代码,然后,改名文件夹

第三步:修改LED闪烁代码,实现LED流水灯

LED闪烁代码

LED流水灯代码

3.9 蜂鸣器代码

第一步:按图连接蜂鸣器到,面包板上,图一画圈按照图二画圈部分来接线

第二步:复制LED闪烁代码,修改实现蜂鸣器代码

LED闪烁

蜂鸣器代码

3.10 按键简介

3.11 传感器模块简介

上下拉电阻思维理解AO端模拟电压输出(与图形结合)

3.11.1 硬件电路

3.11.2 参考资料

3.12 按键控制LED代码

第一步:按图接线到面包板

第二步:复制新建工程代码

第三步:打开文件夹,新建一个文件夹,命名为Hardware,用于模块化编程,存放硬件驱动,然后在工程新建一个组和添加文件路径

第四步:模块化代码

LED.c

LED.h(防止重复定义的条件编译,最后一行必须是空的)

Key.c

Key.h

main.c

3.13 光敏传感器控制蜂鸣器代码

第一步:按图接线到面包板

第二步:复制按键控制LED代码

第三步:模块化代码

Buzzer.c(与LED.c的代码基本一致,复制粘贴后只需要修改其中的端口、引脚即可)

Buzzer.h

LightSensor.c

LightSensor.h

main.c

3.15 总结GPIO的使用方法(以LED代码模块为例)

1.初始化时钟

2.定义结构体,赋值结构体

3.将指定的GPIO外设初始化

3.16 GPIO库函数

RCC开启GPIO时钟的库函数

GPIO初始化库函数

3.15上述的完整代码


3.1 GPIO简介

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

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

引脚电平:0V~3.3V,部分引脚可容忍5V

输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等

输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

3.2 GPIO基本结构

3.3 GPIO位结构

输入部分:

I/O引脚,接了两个保护二极管,这个是对输入电压进行限幅,上面二极管:接VDD,3.3V,下面二极管:接VSS,0V,电压在0~3.3V之间二极管不会导通

二极管的保护作用:

如果输入电压比3.3V还要高,那上方这个二极管就会导通,输入电压产生的电流就会直接接入VDD而不会流入内部电路,这样就会避免过高的电压对内部这些电路产生伤害

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

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

(弱)上拉输入模式:上面导通,下面断开,默认高电平模式

(弱)下拉输入模式:下面导通,上面断开,默认低电平模式

浮空输入模式:两个都断开,不确定电平高低

上拉和下拉的作用,为了给输入提供一个默认的输入电平

施密特触发器:

对输入电压进行整形,执行逻辑:输入电压大于某一阈值,输出就会瞬间升为高电平,输入电压小于某一阈值,输出就会瞬间降为低电平

通过施密特触发器整形波形,可以直接写入输入数据寄存器,这时用程序读取输入数据寄存器对应的某一位的数据,就能知道端口的输入

片上外设端口

模拟输入:连接到ADC上,因为ADC需要接收模拟量,所以在施密特触发器前面

复用功能输入:连接到其他需要读取端口的外设上,比如:串口的输入引脚;这根线接收的数字量,所以在施密特触发器后面

输出部分:

输出部分可以由输出数据寄存器活片上外设控制,两种控制方式通过数据选择器接到了输出部分;选择输出寄存器控制,就普通I/O口输出,写这个数据寄存器的某一位就可以操作对应的某个端口

位设置/清除寄存器这个可以用来单独操作输出数据寄存器的某一位,而不影响其他位,因为输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以想单独控制其中某一个端口而不影响其他端口的话,需要一些独特的方式

第一种方法:先读出这个寄存器,然后按位与按位或的方式更改某一位,最后再将更改后的数据写回去,这种方式效率不高,操作麻烦

第二种方法:就是用到位设置/清除寄存器,如果要对某一位进行置1的操作,在位设置寄存器的对应位写1,,不需要的操作写0,自动将输出数据寄存器对应位置1,而剩下写0的位则保持不变,这样就保证了只操作其中某一位而不影响其他位,并且这是一步到位的操作,如果,想对输出数据寄存器某一位进行清0的操作,在位清除寄存器的对应位写1

MOS管

上面是P-MOS,下面是N-MOS,这个MOS管是一种电子开关,信号来控制开关的导通和关闭,开关负责将I/O口接到VDD或者VSS,可以选择推挽、开漏、关闭三种模式

推挽输出模式(强推输出模式):P-MOS和N-MOS均有效;数据寄存器为1时,上管导通,下管断开,输出直接接到VDD,输出高电平;数据寄存器为0时,下管导通,上管断开,输出直接接到VSS,输出低电平

开漏输出模式(只有低电平有驱动能力,高电平没有驱动能力,通信协议的驱动方式(避免各个设备的相互干扰),还可输出5V的电平信号):P-MOS是无效,N-MOS有效;数据寄存器为1时,下管断开,这时输出想当于断开,也就是高阻模式;数据寄存器为0时,下管导通,输出直接接到VSS,也就是输出低电平

关闭输出模式,P-MOS和N-MOS均无效,也就是输出关闭,端口的电平由外部信号控制

3.4 GPIO模式

通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式

3.4.1 浮空/上拉/下拉输入

输入模式下,输出驱动器是断开的,端口只能输入不能输出,在上拉电阻和下拉电阻进行操作,使其加入浮空/上拉/下拉输入,在施密特触发器进行波形整形后,连接到输入数据寄存器

3.4.2 模拟输入

模拟输入下,引脚直接接入片上外设,也就是ADC,将引脚配置为模拟输入就行

3.4.3 开漏/推挽输出

P-MOS无效,就是开漏输出,P-MOS和N-MOS有效,推挽输出,在输出模式下,输入模式是有效的,因为一个端口只能有一个输出,但可以有多个输入

3.4.4 复用开漏/推挽输出

只由片上外设控制

3.5 LED和蜂鸣器简介

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

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

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

3.5.1 LED和蜂鸣器的硬件电路

第一张图是低电平驱动的电路,LED正极接3.3V,负极通过一个限流电阻接到PA0上,当PA0输出低电平时,LED两端就会产生电压差,就会形成正向导通的电流,LED就会点亮,当PA0输出高电平时,没有电压差,LED就熄灭;第二张图,高电平驱动电路,PA0高电平亮,PA0低电平灭

要看I/O口高低电平的驱动能力如何,决定选择哪种方式驱动,GPIO在推挽输出模式下,高低电平均有比较强的驱动能力,这两种都可以,如果高电平驱动能力弱,不能使用第二种连接方法

第一张图是PNP三极管(PNP的三极管最好接上边)的驱动电路,三极管的左边是基极,带箭头的是发射极,剩下的是集电极,基极给低电平,三极管导通,通过3.3V和GND,就可以给蜂鸣器提供驱动电流,反之;第二张是NPN三极管(NPN的三极管最好接下边)的驱动电路,三极管的左边是基极,带箭头的是发射极,剩下的是集电极,基极给高电平导通,低电平断开

参考资料

3.6 面包板(供电区要通过跳线和中间区域连接)

3.7 LED代码

第一步:开启时钟,初始化时钟

第二步:将Delay函数加入工程,添加组,然后,魔术棒添加文件路径

第三步:写代码点亮LED

第四步:按图接线,如果要反接开漏模式,正接推挽模式,LED长线为正

3.8 LED流水灯代码

第一步:按图接线,将LED流水灯,连接到面包板上

第二步:复制LED闪烁代码,然后,改名文件夹

第三步:修改LED闪烁代码,实现LED流水灯

LED闪烁代码

LED流水灯代码

3.9 蜂鸣器代码

第一步:按图连接蜂鸣器到,面包板上,图一画圈按照图二画圈部分来接线

第二步:复制LED闪烁代码,修改实现蜂鸣器代码

LED闪烁

蜂鸣器代码

3.10 按键简介

按键:常见的输入设备,按下导通,松手断开

按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动

按键的抖动,对于高速运行的单片机来说,5~10ms是很漫长的,所以要消抖(在按键按下和松开时,都加一个延迟函数),否则就会出现,按一次按键单片机出现反映了多次的现象

3.11 传感器模块简介

传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出

上下拉电阻思维理解AO端模拟电压输出(与图形结合)

当这个N1阻值变小时,下拉作用就会增强,中间的AO端的电压就会拉低(极端情况下,N1阻值为0,AO输出被完全下拉,输出为0V);当N1阻值变大,下拉作用就会减弱,中间的引脚由于R1的上拉作用,电压就会升高(极端情况下,N1阻值无穷大,相当于断路,输出电压被R1拉高至VCC)

AO端模拟电压二值化输出,就是数字输出(与图结合)

电压比较器,当同向输入端电压大于反向输入端的电压时,输出就会瞬间升高为最大值(VCC);反之,输出瞬间降为最小值(GND)

3.11.1 硬件电路

按键的四种接法,图一图二是下接按键的方式(一般使用这种),图三图四是上接按键的方式

图一:随便选取一个GPIO口,比如PA0,然后通过K1接地,按键按下时,PA0被直接下拉到GND,此时读取PA0口的电平就是低电平,当按键松手时PA0被悬空(电压不确定),所以这种接法下,必须要求PA0是上拉输入模式,这样按下按键,引脚低电平,松手,引脚高电平

图二:相比图一多了一个上拉电阻,PA0可以使浮空输入或者上拉输入,这样按下按键,引脚低电平,松手,引脚高电平

图三:K1接到3.3V,必须要求PA0接到下拉输入模式,这样按键按下时高电平,松手是低电平

图四:相比于图三,多了一个下拉电阻,这样按键按下时高电平,松手是低电平

传感器模块电路

3.11.2 参考资料

3.12 按键控制LED代码

第一步:按图接线到面包板

第二步:复制新建工程代码

第三步:打开文件夹,新建一个文件夹,命名为Hardware,用于模块化编程,存放硬件驱动,然后在工程新建一个组和添加文件路径

第四步:模块化代码

LED.c

LED.h(防止重复定义的条件编译,最后一行必须是空的)

Key.c

Key.h

main.c

3.13 光敏传感器控制蜂鸣器代码

第一步:按图接线到面包板

第二步:复制按键控制LED代码

第三步:模块化代码

Buzzer.c(与LED.c的代码基本一致,复制粘贴后只需要修改其中的端口、引脚即可)

Buzzer.h

LightSensor.c

LightSensor.h

main.c

3.15 总结GPIO的使用方法(以LED代码模块为例)

1.初始化时钟

2.定义结构体,赋值结构体

GPIO_Mode,选择8种输入输出模式

GPIO_Pin选择引脚,可以用按位或(|)的方式同时选中多个引脚

GPIO_Speed选择输出速度,要求不高直接50MHz即可

3.将指定的GPIO外设初始化

3.16 GPIO库函数

RCC开启GPIO时钟的库函数

GPIO初始化库函数

void GPIO_DeInit 调用这个函数之后,所指定的GPIO外设就会被复位

void GPIO_AFIODeInit 调用这个函数之后,可以复位AFIO外设

void GPIO_Init 这个函数作用是用结构体的参数来初始化GPIO口,需要先定义一个结构体变量,然后再给结构体赋值,最后调用这个函数,这个函数就会自动读取结构体的值,然后自动把外设的各个参数配置好,一般初始化外设都是使用这个Init函数完成

void GPIO_StructInit 这个函数可以把结构体变量赋一个默认值

uint8_t GPIO_ReadInputDataBit、uint16_t GPIO_ReadInputData、uint8_t GPIO_ReadOutputDataBit、uint16_t GPIO_ReadOutputData这四个是GPIO读取函数

void GPIO_SetBits、void GPIO_ResetBits、void GPIO_WriteBit、void GPIO_Write这四个是GPIO写入函数

3.15上述的完整代码


网站公告

今日签到

点亮在社区的每一天
去签到