STM32—GPIO的学习
一、什么是GPIO?
General Purpose Input Output,即通用输入输出端口,简称GPIO
作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出
二、GPIO简介
2.1 GPIO特点
1,不同型号,IO口数量可能不一样,可通过选型手册快速查询
2,快速翻转,每次翻转最快只需要两个时钟周期(F1最高速度可以到50Mhz)
3,每个IO口都可以做中断
4,支持8种工作模式
2.2 GPIO电气特性
1,STM32工作电压范围为2 V ≤ VDD ≤ 3.6 V
2,GPIO识别电压范围为COMS端口:-0.3V ≤ VIL ≤ 1.164V
1.833V ≤ VIH ≤ 3.6V
注:处于中间的电压为不确定的可能是0也可能是1
3,GPIO输出电流,单个IO,最大25mA
2.3 GPIO引脚分布
STM32引脚类型:
电源引脚、晶振引脚、复位引脚、
下载引脚、BOOT引脚、GPIO引脚
三、IO端口基本结构介绍
3.1 F1的IO结构图
3.2 F4/F7/H7的IO结构图
注:这两个图的不同点在于上下拉电阻的位置不同。F1的位于输入驱动器内,F4/F7/H7的位于输入驱动器外
四、GPIO的八种模式分析
4.1 输入浮空
①上拉电阻关闭
②下拉电阻关闭
③施密特触发器打开
④双MOS管不导通
特点:空闲时,IO状态不确定,由外部环境决定
4.2 输入上拉
①上拉电阻打开
②下拉电阻关闭
③施密特触发器打开
④双MOS管不导通
特点:空闲时,IO呈现高电平
4.3 输入下拉
①上拉电阻关闭
②下拉电阻打开
③施密特触发器打开
④双MOS管不导通
特点:空闲时,IO呈现低电平
4.4 模拟功能
①上拉电阻关闭
②下拉电阻关闭
③施密特触发器关闭
④双MOS管不导通
特点:专门用于模拟信号输入或输出,如:ADC和DAC
4.5 开漏输出
①上拉电阻关闭
②下拉电阻关闭
③施密特触发器打开
④ P-MOS管始终不导通
⑤往ODR对应位写0,
N-MOS管导通,
写1则N-MOS管不导通
特点:不能输出高电平, 必须有外部(或内部)上拉才能输出高电平
4.6 开漏式复用功能
①上拉电阻关闭
②下拉电阻关闭
③施密特触发器打开
④ P-MOS管始终不导通
特点:
1、不能输出高电平,必须有外部(或内部)上拉才能输出高电平
2、由其他外设控制输出
4.7 推挽输出
①上拉电阻关闭
②下拉电阻关闭
③施密特触发器打开
④往ODR对应位写0, N-MOS管导通,写1则P-MOS管导通
特点:可输出高低电平,驱动能力强
4.8 推挽式复用功能
①上拉电阻关闭
②下拉电阻关闭
③施密特触发器打开
特点:
1、可输出高低电平, 驱动能力强
2、由其他外设控制输出
F4/F7/H7系列和F1系列的GPIO差异点
1,F1在输出模式,禁止使用内部上下拉。F4/F7/H7在输出模式,可以使用内部上下拉
2,不同系列IO翻转速度可能不同
五、GPIO寄存器介绍
六、GPIO配置步骤
注:要熟练掌握
相关HAL库函数简介
七、点亮LED
7.1 跑马灯
//LED.h
#ifndef __LED_H
#define __LED_H
#include "./SYSTEM/sys/sys.h"
//GPIO相关配置
#define LED0_GPIO_PORT GPIOB
#define LED0_GPIO_PIN GPIO_PIN_5
#define LED0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE();}while(0)
#define LED1_GPIO_PORT GPIOE
#define LED1_GPIO_PIN GPIO_PIN_5
#define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE();}while(0)
//LED0的配置
#define LED0(x) do{ x ? \
HAL_GPIO_WritePin(LED0_GPIO_PORT,LED0_GPIO_PIN,GPIO_PIN_SET):\
HAL_GPIO_WritePin(LED0_GPIO_PORT,LED0_GPIO_PIN,GPIO_PIN_RESET);\
}while(0)
#define LED1(x) do{ x ? \
HAL_GPIO_WritePin(LED1_GPIO_PORT,LED1_GPIO_PIN,GPIO_PIN_SET):\
HAL_GPIO_WritePin(LED1_GPIO_PORT,LED1_GPIO_PIN,GPIO_PIN_RESET);\
}while(0)
#define LED0_TOGGLE() do{HAL_GPIO_TogglePin(LED0_GPIO_PORT,LED0_GPIO_PIN);}while(1)
#define LED1_TOGGLE() do{HAL_GPIO_TogglePin(LED1_GPIO_PORT,LED1_GPIO_PIN);}while(1)
void led_init(void);
#endif
//LED.c
#include "./BSP/LED/led.h"
void led_init(void)
{
//创建结构体
GPIO_InitTypeDef gpio_led_init_5;
//初始化使能
LED0_GPIO_CLK_ENABLE();
LED1_GPIO_CLK_ENABLE();
//初始化
gpio_led_init_5.Pin = LED0_GPIO_PIN ;
gpio_led_init_5.Mode = GPIO_MODE_OUTPUT_PP;
gpio_led_init_5.Speed = GPIO_SPEED_FREQ_HIGH ;
//设置工作模式
HAL_GPIO_Init(LED0_GPIO_PORT, &gpio_led_init_5);
gpio_led_init_5.Pin = LED1_GPIO_PIN ;
HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_led_init_5);
LED0(1);
LED1(1);
}
7.2 按键控制LED
key.c
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
void key_init(void)
{
//创建结构体
GPIO_InitTypeDef gpio_key_init;
//初始化使能
__HAL_RCC_GPIOE_CLK_ENABLE();
//初始化
gpio_key_init.Pin = GPIO_PIN_3 ;
gpio_key_init.Mode = GPIO_MODE_INPUT;
gpio_key_init.Pull = GPIO_PULLUP;
//设置工作模式
HAL_GPIO_Init(GPIOE, &gpio_key_init);
}
//扫描函数
uint8_t key_scan(void)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3) == 0)
{
//消抖
delay_ms(10);
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3) == 0)
{
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3) == 0);
return 1;
}
}
return 0;
}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
int main(void)
{
HAL_Init();
sys_stm32_clock_init(RCC_PLL_MUL9);
delay_init(72);
led_init();
key_init();
while(1)
{
if(key_scan())
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
else
{
delay_ms(10);
}
}
}