STM32 GPIO输入输出(基于HAL库)
一、基础认识
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库)的更多相关文章
- STM32串口接收中断——基于HAL库
写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...
- Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)
说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...
- 基于HAL库的STM32的DSP库详解(附FFT应用)
1 . 建立工程,生成代码时选择包含所有库. 2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardw ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- STM32 IIC双机通信—— HAL库硬件IIC版
参考传送门 关于IIC的原理这里我就不多说了,网上有很多很好的解析,如果要看我个人对IIC的理解的话,可以点击查看,这里主要讲一下怎样利用STM32CubeMx实现IIC的通讯,经过个人实践,感觉HA ...
- STM32F072从零配置工程-基于HAL库的串口UART中断配置
先上一个采用串口直接传输的Demo: 此处的思路是完全采用HAL库来实现的,核心是运用HAL_UART_Transmit_IT和HAL_UART_Receive_IT两个函数来实现的,可以作为一个De ...
- STM32系统时钟RCC(基于HAL库)
基础认识 为什么要有时钟: 时钟就是单片机的心脏,其每跳动一次,整个单片机的电路就会同步动作一次.时钟的速率决定了两次动作的间隔时间.速率越快,单片机在单位时间内所执行的动作将越多.时钟是单片机运行的 ...
- 【stm32】基于hal库使用野火指南者esp8266 WIFI模块进行TCP传输
UART.c #include "stm32f1xx_it.h" #include "LED.h" #include "UART.h" #i ...
随机推荐
- 07 . 前端工程化(ES6模块化和webpack打包)
模块化规范 传统开发模式主要问题 /* 1. 命名冲突 2. 文件依赖 */ 通过模块化解决上述问题 /* 模块化就是把单独的一个功能封装在一个模块(文件)中,模块之间相互隔离, 但是可以通过特定的接 ...
- 精尽 MyBatis 源码分析 - 基础支持层
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- python中的unittest库
1.unittest框架是python自动化测试的入门框架,它是python自带的一个模块 包含以下几个子模块 测试用例:TestCase 测试集:TestSuite 加载用例:TestLoader ...
- leetcode 108 和leetcode 109 II
//感想:没啥上篇写完了 //思路:对于这道题109来说,就是数组变成了链表,其他没有变,我觉得非常不解,因为我想到的依旧是找中点,用快慢指针来找, 找到以后将链表分成两半,继续递归的去找,我就觉得这 ...
- iOS UITextFeild获取高亮部分的长度
获取原因: 中英文混输时,会遇到长度统计不准的问题. 获取方法: NSString *toBeString = textField.text; NSString *lang = [[UITextInp ...
- AgileConfig-轻量级配置中心 1.1.0 发布,支持应用间配置继承
AgileConfig轻量级配置中心自第一个版本发布不知不觉已经半年了.在并未进行什么推广的情况下收到了250个star,对我有很大的鼓舞,并且也有不少同学试用,并且给出了宝贵的意见,非常感谢他们.其 ...
- Clickhouse 入门
clickhouse 简介 ck是一个列式存储的数据库,其针对的场景是OLAP.OLAP的特点是: 数据不经常写,即便写也是批量写.不像OLTP是一条一条写 大多数是读请求 查询并发较少,不适合放置先 ...
- win10 下安装 ubuntu 子系统的完全指北
最近在搞 C++ 相关的东西,因为在 Linux 下开发会比较流畅舒适,而公司配的电脑都是 windows 的,之前都是在 vmware 中安装个 ubuntu 虚拟机,但这种有时候比有点卡顿.所以今 ...
- 等待多线程完成的CountDownLatch(带示例)
开始磨刀霍霍向多线程了,这期是 CountDownLatch 的一个小示例. 定义:CountDownLatch 允许一个或多个线程等待其他线程完成操作. 应用需求举例:假设有4个线程,A.B.C.D ...
- JZOJ2020年8月12日提高组反思
JZOJ2020年8月12日提高组反思 真·难亿一点点 T1 题目长并附带伤害-- 暴力搜 对于字符串,我选择\(Pascal\) T2 概率问题,再见 T3 样例没懂,再见 T4 有史以来见过的条件 ...