1.GPIO简介
1.输出
GPIO(通用输出输入口)(general purpose input output)
可配置为8种输出输出模式
- 输出模式下可以控制端口输出高低电平,用以驱动LED,控制蜂鸣器,模拟通信协议输出时序。
- 输入模式可以读取端口高低电平或者电压,读取按键输入,外接模块电平信号输入、ADC电压采集,模拟通信协议接受数据等。(最常用捕获按键)
- 引脚 电平:0v~3.3v,部分引脚可容忍5v(引脚带FT的都是看容忍5v电压的)
2.GPIO基本结构
-
所有GPIO均挂载在APB2外设总线上,其中GPIO外设的名称是按照GPIOA,GPIOB,GPIOC等来命名。
-
每个GPIO外设共有16个引脚,编号0-15.例如GPIOA的引脚称为PA0,GPIOB的引脚称为PB0等,不同名称对应片上不同引脚!!(stm32为32位的单片机,所以这个端口只有低16位用到,高16位没有用到)
-
GPIO内部主要是寄存器和驱动器,完成对电平的输入输出读取等操作。每一位对应一个引脚。Stm32,所以内部寄存器都是32位的,低16位对应有端口,高16位没有对应有端口。驱动器用来增强信号驱动能力。寄存器用来负责记录信息。
3.GPIO位结构
整体分为2个部分,输出部分和输出部分,上半部分位输入,下半部分为输出
1.输入部分
- VDD接3.3v,VSS接0v。 如果输入电压大于3.3v那么,上方保护二极管就会导通,该电流就会流入VDD而不流入电路;下部同理
-
接着电流就到了开关部分,这部分接了一个上拉电阻和下拉电阻,上拉电阻VDD,下拉电阻VSS,可通过程序配置
- 如果上面导通,下面断开,就是上拉输入模式 ,默认为高电平的输入模式, (可以理解为引脚为高电平,外部接地,这样按键按下,便能使引脚电平变化(按键输入更常用上拉配置,因为它可以在未按下时保持高电平,按下时变为低电平))
- 如果下面导通,上面断开,就是下拉输入模式 ,默认为低电平的输入模式
- 如果两个都断开,就是 浮空输入 (极易受外接干扰) (//使用浮空输入的时间,当外部输入信号功率很小,内部上拉电阻可能会影响到这个输入信号)
本质上是给输入提供一个默认的输入电平 ,上拉电阻和下拉电阻的阻值比较大,属于弱上拉和弱下拉,尽量不影响正常的输出操作
- 施密特触发器
- 作用:对输入电压进行整形 将信号确定为高电平或者低电平):大于某阈值,升为高,低于下限输出低,模拟输入不需要整形,所以就直接输出了,
- 之后可以直接写入输入数据寄存器了,我们再读取某一位就可以知道电平了
- 上面还有两路
- 模拟电路输入:因为ADC需要模拟量所以这根线皆在了施密特触发器前面(模拟量就是连续变化的,不需要整形)
- 复用功能输入:连接到其他需要读取端口的外设上面,比如串口的输入引脚
2.输出部分
- .数字部分由输出数据寄存器或片上外设控制,两种控制方式通过数据选择器接到输出控制部分。如果选择通过输出数据寄存器进行控制,就是普通的IO口输出,写这个数据寄存器的某一位就可以操作对应的某个端口。
- 左边的位设置/清除寄存器,用来单独操作输出数据寄存器的某一位(因为输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写),如果要对某一位进行置1操作,在位设置寄存器的对应位写1即可,剩下写0,内部电路自动将输出数据寄存器中对应位置为1,写0位保持不变;如果想对某一位进行清0的操作,就在位清零寄存器的对应位写1即可。
- 输出控制后,接着就到了两个MOS管,可选择推完,开漏,关闭三种模式
- 推挽输出(强推输出模式):P-MOS和N-MOS均有效,数据寄存器位1时,上管导通,下管断开,直接接到VDD,也即输出高电平;数据寄存器位0时,下管导通,上管断开,直接接到VSS,也即输出低电平。这种模式下高低电平均有较强的驱动能力。stm32对IO口有绝对统治权
- 开漏输出:P-MOS无效,N-MOS有效数据寄存器位1时,下管断开,直接接到VDD,这时,输出相当于断开也即高祖模式;数据寄存器位0时,下管导通,直接接到VSS,也即输出低电平。这种模式下,只有低电平有驱动能力,高电平没。可以作为通讯协议的驱动方式,比如:IIC通讯。在多机通讯的情况下可以避免多个设备的干扰
4.GPIO模式
GPIO速度可以限制输出引脚的最大反转速度,为了低功耗和稳定性,一般都是50MHZ
5.GPIO驱动LED闪烁
- 第一步,使用rcc开启GPIO时钟
- 第二步,使用GPIO_Init()函数初始化GPIO
- 第三步,使用输出或输入函数控制GPIo口
HAL库配置
1.LED点亮
- LED点亮,配置为GPIO推挽模式,推挽输出不需要设置上下拉
2.按键
- 注意:
-
1.每次按下按键需要单次触发!
-
2.需要有松手检测!
-
3.不阻塞程序!不要有Delay,更不能有while等待弹起,因为如果一直按着不送,cpu就会一直被占用。
-
4.最好有长按功能。
-
直接记忆即可--三行按键法
#define KB1 GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB2 GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB3 GPIO_ReadPin(GPIOB,GPIO_PIN_3)
#define KB4 GPIO_ReadPin(GPIOB,GPIO_PIN_4)
#define KEYPORT KB1|KB2<<1|KB3<<2|KB4<<3|0xf0 //1111 1111当按键1按下1111 1110
u8 trig; //one key
u8 cont; //long key
void Key_Read(void)
{
u8 ReadData=KEYPORT^0xff; //异或,不同则为1,相同则为0,//0000 0001
trig=ReadData&(KEYPORT^cont);//0000 0001&(0000 0001^0000 0000)=0000 0001
cont=ReadData;//0000 0001
}