一、基础认识

GPIO全名为General Purpose Input Output,即通用输入输出。有时候简称为“IO口”。通用,说明它是常见的。输入输出,就是说既能当输入口使用,又能当输出口使用。端口,就是元器件上的一个引脚。

输入模式和输出模式是GPIO的基本特性,当然GPIO还有其它模式可选。

(一) IO耐压问题

STM32是一款3.3V电压的芯片,IO输出是3.3V,但IO大部分都是可以容忍5V电压输入。一般在芯片手册的“引脚定义”章节可以查看到有FT标识表示该IO可以容忍5V电压输入。

二、在标准库中GPIO的模式

(一)模式汇总

输入模式:

l  浮空输入(GPIO_Mode_IN_FLOATING):引脚电平是真实的外部连接器件电压,电平有不确定性

l  上拉输入 (GPIO_Mode_IPU):默认通过电阻上拉到VCC,不接外部器件时可以读出高电平

l  下拉输入 (GPIO_Mode_IPD):默认通过电阻下拉到GND,不接外部器件时可以读出低电平

l  模拟输入 (GPIO_Mode_AIN):将外部信号直接传输到数模转换通道上

输出模式:

l  开漏输出(GPIO_Mode_Out_OD):只能输出低电平,高电平由电阻上拉决定

l  开漏复用功能(GPIO_Mode_AF_OD):用于外设功能使用

l  推挽式输出(GPIO_Mode_Out_PP):可以输出强高和强低,通常使用该功能控制LED

l  推挽式复用功能(GPIO_Mode_AF_PP):用于外设功能使用

GPIO的基本结构:

TTL肖特基触发器其实可以理解为用肖特基管构成的施密特触发器,作用简单说就是将相对缓慢变化的模拟信号变成矩形(方波)信号,便于后面读取。这里有一个阈值电压的概念,比如从低到高达到多少才会导通,从高到底多少才会关闭。

(二)   浮空输入(GPIO_Mode_IN_FLOATING)

浮空就是逻辑器件与引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构和外部引脚所接的器件决定电平状态。一般实际运用时,引脚不建议悬空,易受干扰。通俗讲就是浮空就是浮在空中,就相当于此端口在默认情况下什么都不接,呈高阻态,这种设置在数据传输时用的比较多。浮空最大的特点就是电压的不确定性,它可能是0V,页可能是VCC,还可能是介于两者之间的某个值(最有可能) 浮空一般用来做ADC输入用,这样可以减少上下拉电阻对结果的影响。

(三)  上拉输入 (GPIO_Mode_IPU)

上拉就是把点位拉高,比如拉到Vcc。上拉就是将不确定的信号通过一个电阻嵌位在高电平。电阻同时起到限流的作用。弱强只是上拉电阻的阻值不同,没有什么严格区分。

电阻通常为30-50KΩ

(四) 下拉输入 (GPIO_Mode_IPD)

下拉就是把点位拉低,比如拉到GND。下拉就是将不确定的信号通过一个电阻嵌位在低电平。电阻同时起到限流的作用。弱强只是下拉电阻的阻值不同,没有什么严格区分

(五) 模拟输入 (GPIO_Mode_AIN)

模拟输入是指传统方式的输入,数字输入是输入PCM数字信号,即0,1的二进制数字信号,通过数模转换,转换成模拟信号,经前级放大进入功率放大器,功率放大器还是模拟的

(六)  开漏输出(GPIO_Mode_Out_OD)

IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能。

只能输出强低电平。

(七)开漏复用功能(GPIO_Mode_AF_OD)

用于外设使用

(八)推挽式输出(GPIO_Mode_Out_PP)

IO输出0-接GND, IO输出1 -接VCC。这是使用最多的了。控制LED基本都是使用这种模式。

可以输出强高低电平,连接外部数字器件

(九)推挽式复用功能(GPIO_Mode_AF_PP)

用于外设使用

三、配置输入输出IO

(一)输入

(1).   GPIO Pull-up/Pull-down:

IO上下拉配置

l  No pull-up and no pull-down,浮空输入,配置为不上拉和下拉

l  Pull-up,上拉输入

l  Pull-down,下拉输入

(二)输出

(1).   GPIO output level

l  Low:IO初始化默认输出低电平

l  High:IO初始化默认输出高电平

(2).   GPIO mode

l  Output Open Drain,开漏输出,可以输出低电平

l  Output Push Pull,推挽输出,可以输出低电平和高电平

(3).   GPIO Pull-up/Pull-down:

IO上下拉配置

l  No pull-up and no pull-down,浮空输入,配置为不上拉和下拉

l  Pull-up,上拉输入

l  Pull-down,下拉输入

(4).   Maximum output speed

l  Low,GPIO速度为低速,通常为2MHZ

l  Medium,GPIO速度为中速,通常为10MHZ

l  High,GPIO速度为高速,通常为50MHZ

四、 输出编程

测试有GPIOA1和GPIOA2设置为输出测试

(一)CubeMx设置

(二) 初始化函数

宏定义

#define DONG_OUT_1_Pin GPIO_PIN_1
#define DONG_OUT_1_GPIO_Port GPIOA
#define DONG_OUT_2_Pin GPIO_PIN_2
#define DONG_OUT_2_GPIO_Port GPIOA

初始化函数是自动生成的

void MX_GPIO_Init(void)
{ GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟 /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//设置上电电平为低 /*Configure GPIO pins : PAPin PAPin */
GPIO_InitStruct.Pin = DONG_OUT_1_Pin|DONG_OUT_2_Pin;//两个GPIO_PIN
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL;//浮空,不上拉也不下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//低速
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); }

(三)输出相关函数

设置或清除选定的数据端口位

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

参数:

GPIOx :其中x可以(A..G取决于所使用的设备)来选择GPIO外设

GPIO_Pin :指定要写入的端口位。此参数可以是GPIO_PIN_x之一,其中x可以是( 0..15 )。

PinState :指定要写入选定位的值。此参数可以是GPIO_PinState枚举值之一:

l  GPIO_PIN_RESET:清除端口Pin,低电平

l  GPIO_PIN_SET:设置端口Pin,高电平

例子:

HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//两个设置为低电平
HAL_Delay(1000);//1s
HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin, GPIO_PIN_SET);//单独设置为高电平
HAL_GPIO_WritePin(GPIOA,DONG_OUT_2_Pin, GPIO_PIN_SET);//单独设置为高电平
HAL_Delay(1000);//1s

切换指定的GPIO pin

void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

参数:

GPIOx :其中x可以(A..G取决于所使用的设备)来选择GPIO外设

GPIO_Pin :指定要写入的端口位。此参数可以是GPIO_PIN_x之一,其中x可以是(0..15 )。

例子:

HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin);//两个输出电平取反
HAL_Delay(1000);//1s
HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin);//单独输出电平取反
HAL_GPIO_TogglePin(GPIOA,DONG_OUT_2_Pin);//单独输出电平取反
HAL_Delay(1000);//1s

五、输入编程(轮询检测)

(一)CubeMX设置

(二)初始化函数

宏定义

#define DONG_IN_1_Pin GPIO_PIN_3
#define DONG_IN_1_GPIO_Port GPIOA

初始化部分

GPIO_InitTypeDef GPIO_InitStruct = {0};//初始化结构体
__HAL_RCC_GPIOA_CLK_ENABLE();//GPIO时钟开启
GPIO_InitStruct.Pin = DONG_IN_1_Pin;//引脚
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//输入模式
GPIO_InitStruct.Pull = GPIO_PULLUP;//上拉
HAL_GPIO_Init(DONG_IN_1_GPIO_Port, &GPIO_InitStruct);

(三)输入相关函数

读取指定的输入端口引脚

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

参数:

GPIOx :其中x可以(A..G取决于所使用的设备)来选择GPIO外设

GPIO_Pin :指定要写入的端口位。此参数可以是GPIO_PIN_x之一,其中x可以是(0..15 )

返回:

typedef enum
{
GPIO_PIN_RESET = 0u,//低电平
GPIO_PIN_SET//高电平
} GPIO_PinState;

例子:

GPIO_PinState res=HAL_GPIO_ReadPin(DONG_IN_1_GPIO_Port,DONG_IN_1_Pin);//读取电平
if(res==GPIO_PIN_RESET){
HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_SET);//两个设置为高电平
}else{
HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//两个设置为低电平
}

六、输入编程(中断检测)

(一)CubeMX设置

GPIO mode:

l  上升沿触发检测的外部中断模式(External Interrupt Mode with Rising edge trigger detection)

l  下降沿触发检测的外部中断模式(External Interrupt Mode with Falling edge trigger detectiort)

l  上升/下降沿触发检测的外部中断模式(External Interrupt Mode with Risinq/Falling edge trigger detection)

l  上升沿触发检测的外部事件模式(External Event Mode with Rising edge trigger detection)

l  下降沿触发检测的外部事件模式(External Event Mode with Falling edge trigger detection)

l  上升/下降沿触发检测的外部事件模式(External Event Mode with Rising/Falling edge trigger detectiont)

中断和事件的区别:

l  中断是当IO达到中断条件后会向CPU产生中断请求

l  事件是事先设置好的任务,当单片机达到要求将通过硬件的方式处理事先设置好的任务,而不向CPU请求中断,比如DMA、AD转换等

(二)初始化函数

宏定义

#define KEY1_Pin GPIO_PIN_3
#define KEY1_GPIO_Port GPIOA
#define KEY1_EXTI_IRQn EXTI3_IRQn

初始化部分

__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = KEY1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);

(三)中断输入相关函数

中断回调函数

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

参数:

GPIO_Pin :指定连接EXTI线的引脚

例子:

//GPIO中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
//判断进入中断的GPIOs
if(KEY1_Pin==GPIO_Pin){
HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin);//单独输出电平取反
HAL_GPIO_TogglePin(GPIOA,DONG_OUT_2_Pin);//单独输出电平取反
}
}

其它

关于按键防抖的问题:

l  软件防抖可以检测到电平延时一段时间再确认电平,延时时间一般为10-20ms

l  硬件防抖可以在按键上并联一个电容,一般为0.1uf


参考:

https://blog.csdn.net/baidu_37366055/article/details/80060962

STM32 GPIO输入输出(基于HAL库)的更多相关文章

  1. STM32串口接收中断——基于HAL库

    写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...

  2. Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  3. 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)

    说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...

  4. 基于HAL库的STM32的DSP库详解(附FFT应用)

    1 . 建立工程,生成代码时选择包含所有库.   2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardw ...

  5. STM32基于HAL库通过DMA读写SDIO

    通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...

  6. STM32 IIC双机通信—— HAL库硬件IIC版

    参考传送门 关于IIC的原理这里我就不多说了,网上有很多很好的解析,如果要看我个人对IIC的理解的话,可以点击查看,这里主要讲一下怎样利用STM32CubeMx实现IIC的通讯,经过个人实践,感觉HA ...

  7. STM32F072从零配置工程-基于HAL库的串口UART中断配置

    先上一个采用串口直接传输的Demo: 此处的思路是完全采用HAL库来实现的,核心是运用HAL_UART_Transmit_IT和HAL_UART_Receive_IT两个函数来实现的,可以作为一个De ...

  8. STM32系统时钟RCC(基于HAL库)

    基础认识 为什么要有时钟: 时钟就是单片机的心脏,其每跳动一次,整个单片机的电路就会同步动作一次.时钟的速率决定了两次动作的间隔时间.速率越快,单片机在单位时间内所执行的动作将越多.时钟是单片机运行的 ...

  9. 【stm32】基于hal库使用野火指南者esp8266 WIFI模块进行TCP传输

    UART.c #include "stm32f1xx_it.h" #include "LED.h" #include "UART.h" #i ...

随机推荐

  1. 学习一下 Spring Security

    一.Spring Security 1.什么是 Spring Security? (1)基本认识 Spring Security 是基于 Spring 框架,用于解决 Web 应用安全性的 一种方案, ...

  2. mysql之sql语句逻辑执行顺序

    1. (1)from先执行,from执行后就会将所有表(多个表时和单表所有的表)数据加载到内存中了 (2)ON执行,得到连接表用的连接条件. (3)JOIN执行,根据ON的连接条件,将from加载的所 ...

  3. Springboot 完整搭建快速入门,必看!

    前言 手把手教你Springboot微服务项目搭建快速入门,通过本文学习Springboot的搭建快速入门,掌握微服务大致的配置服务,后续将会继续将核心组件引入到项目中,欢迎关注,点赞,转发. Spr ...

  4. mysql主备切换canal出现的问题解析

    通过配置VIP,在进行主备切换时,出现的报错信息: 1.当主备节点当前binlog文件名称相同时,原主节点的position小于主备切换后的position,出现如下报错: 2020-07-02 15 ...

  5. [PHP安全特性学习]is_numeric()函数安全漏洞

    简介 PHP函数的安全特性-is_numerice() 函数 简介 PHP is_numeric() 函数 is_numeric() 函数用于检测变量是否为数字或数字字符串. 语法: bool is_ ...

  6. 交换机通过Loopback Detection检测(设备所在网络环路)

    组网图形  Loopback Detection简介 见上篇文章(详情见),不再赘述. 组网需求 如图1所示,某小型企业采用二层组网,所属VLAN为100.由于人员流动性大,网络拓扑变动频繁,变动往往 ...

  7. 使用Camtasia制作冰雪奇缘视频

    冰雪奇缘的精良制作,以及场景的华丽,让很多女孩子都很喜欢.对于其中美丽的冰雪场景,我们还可以使用Camtasia(Windows系统)教程录制软件来做冰雪奇缘视频. Camtasia教程录制软件是一款 ...

  8. 从维基百科等网站复制数据和公式到MathType里编辑

    在我们写论文的时候,经常会需要用一些实际案例以及数据,而这些数据和案例有很大一部分可以直接在网络上找到.但是有时候也会发现我们想要的内容和公式,从网页上复制粘贴后太模糊,不适合打印和投影.就需要我们将 ...

  9. iOS UITextFeild获取高亮部分的长度

    获取原因: 中英文混输时,会遇到长度统计不准的问题. 获取方法: NSString *toBeString = textField.text; NSString *lang = [[UITextInp ...

  10. 聊聊 ClassLoader 是如何查找资源的

    ClassLoader作用 classloader这个写业务代码的童鞋们,应该很少用到,但是写框架的应该很熟悉.这个类负责Java底层的类的加载和查找,简单滴说Java 的所有类都是由它负责将clas ...