当前位置: 首页 > news >正文

【STM32进阶笔记】GPIO端口

  前段时间由于其他原因,专栏暂停更新了较长一段时间,现在恢复更新,争取继续为大家创造有价值的内容,期待大家的订阅关注,欢迎互相学习交流。

STM32速成笔记系列专栏中其实已经对GPIO的一些必要知识进行了介绍,但是如果我们想要深入了解GPIO的一些寄存器知识和各种输入输出模式,还需要继续深入学习,本文就让我们一起来深入学习GPIO的相关内容。

文章封面

PS:笔者能力有限,文章如有错漏之处,还请各位不吝赐教,感谢大家的支持!

文章目录

  • 一、GPIO简介
  • 二、GPIO寄存器
    • 2.1 端口配置寄存器低/高
    • 2.2 端口输出寄存器
    • 2.3 端口设置/清除寄存器
    • 2.4 端口清除寄存器
  • 三、硬件分析
    • 3.1 推挽输出
    • 3.2 开漏输出
  • 四、程序分析

一、GPIO简介

每个GPI/O端口有两个32位配置寄存器(GPIOX CRL,GPIOx CRH),两个32位数据寄存器(GPIOX IDR和GPIOx ODR),一个32位置位1复位寄存器(GPIOx BSRR),一个16位复位寄存器(GPIOx BRR)和一个32位锁定寄存器(GPIOx LCKR)。根据数据手册中列出的每个!/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成多种模式。

每个I/O端口位可以自由编程,然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOX BSRR和GPIOX BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问:这样,在读和更改访问之间产生IRQ时不会发生危险。

上面一段文字是STM32中文参考手册中对于GPIO功能的描述,这有一个关键就是I/O寄存器必须按照32位来操作,我们在看一些程序工程时可能会看到如下的宏定义

// SDA方向
#define MPU_SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define MPU_SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

这里也是严格按照32位来操作了GPIO,关于上面两句具体是什么作用,是怎么实现的,我们下面随着学习的深入会一步一步来分析。

我们知道I/O有多种输入输出模式,在STM32中文参考手册的GPIO功能描述部分给出了各种模式的配置方法

输入输出配置方法

复位期间和刚复位后,复用功能未开启,I/O端口被配置成浮空输入模式,复位后JTAG引脚会被配置成对应的输入输出模式。

在使用时需要注意们尽量不要使用这些引脚,具体是哪些引脚以及如果必须使用这几个引脚改怎么办,在STM32速成笔记专栏中有介绍,这里就不再赘述了。

当作为输出配置时,写到输出数据寄存器上的值(GPIOx_ODR)输出到相应的I/O引脚,输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。

二、GPIO寄存器

我们这里介绍几个关键的GPIO寄存器

2.1 端口配置寄存器低/高

每一个GPIOx都有16个引脚0~15,每一个GPIO引脚的输入输出配置需要4bit,一个寄存器是32bit,所以想要能配置16个引脚的输入输出模式需要两个GPIO配置寄存器,所以在STM32参考手册中有高低之分,低控制0到7,高控制8到15,我们只附一个GPIO配置寄存器低的图,高的是类似的。
GPIO配置寄存器低

我们看到这里介绍的时候只给出了“上拉/下拉式输入模式”并没有说明怎么配置是上拉输入,怎么配置是下拉输入,这时我们可以结合上面的表格17来参考。

另外笔者在看的时候注意到“输入模式”后面写着“复位后的状态”,导致笔者以为如果想从输出模式配置成输入模式需要复位操作,后来明白这里的意思应该是引脚复位后的默认状态应该是浮空输入模式。

2.2 端口输出寄存器

结合GPIO配置寄存器和上面的表格,加入我们想要配置一个GPIO的某各引脚为上拉输入模式,我们需要配置它的CNFy[1:0]为10,配置它的MODEy[1:0]为00,还需要再配置ODR寄存器来确定是上拉输入模式而不是下拉,我们来看一下端口数据输出寄存器(GPIOx_ODR寄存器)的描述。

端口数据输出寄存器

2.3 端口设置/清除寄存器

我们想要配置成上拉输入模式,需要将GPIOx_ODR对应位设置成1,从上面对于ODR寄存器描述来看,我们可以借助GPIOx_BSRR寄存器来单独操作ODR寄存器的值,STM32参考手册中对于段端口位设置/清除寄存器(GPIOx_BSRR)的描述如下。

端口位设置/清除寄存器
根据寄存器描述,我们只需要将对应端口的BS位设置成1即可完成上拉输入模式的配置。

2.4 端口清除寄存器

除了可以通过上面的GPIOx_BSRR来清除对应的ODR位之外,还提供了一个端口清楚寄存器(GPIOx_BRR)来单独清除,和上面的GPIOx_BSRR的清除方法是一样的,这里就不再做赘述了。

此外还有一个端口配置锁定寄存器(GPIOx_LCKR)这里也不做介绍了。

三、硬件分析

下面我们来简单分析一下端口配置成不同模式时的硬件电路,从而更深的理解他们的区别,这里之分析推挽式输出与开漏输出。在STM32中文参考手册中给出了输出的配置图并且针对推挽式输出和开漏输出给出了一些描述

输出配置

  • 开漏模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将端口置于高阻状态(PMOS从不被激活)。
  • 推挽模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-MOS。

如果只是从表面上来理解的话,推挽式输出是具有实际输出能力的,也就是说推挽式输出的高电平可以真正的驱动负载,而开漏输出无法输出真正的高电平,也就是说开漏输出的高电平是无法驱动负载的。

针对其中的细节电路已经有很多博主作了介绍,由于笔者对于硬件不擅长,所以就不露怯了,指从表面上来分析一下推挽输出与开漏输出的区别。

我们单独把上图的输出驱动器部分摘出来看一下

输出驱动器

3.1 推挽输出

我们先分析一下推挽式输出

  • 当P-MOS打开,N-MOS关闭时,输出高电平,电流会流出去,这就叫“推”
    推
  • 当P-MOS关闭,N-MMOS打开时,输出低电平,电流会流进来,这就叫“挽”
    挽

3.2 开漏输出

下面我们再来看一下开漏输出,端口配置为开漏输出时,P-MOS一直处于关闭状态,当N-MOS打开时,输出高电平,当N-MOS关闭时,处于一个高阻态/浮空。我们既然已经有了推挽输出,而且开漏输出还需要一个上拉电阻才能输出高电平,那为什么还需要开漏输出呢?下面我们就介绍一下开漏输出的用处。

首先第一个,根据STM32中文参考手册中的描述,在开漏模式时,对输入数据寄存器的读访问可得到I/O状态,也就是说,如果我们把引脚初始化为开漏输出模式,我们需要读取引脚输入时就不需要再把引脚配置成输入模式了。但是在推挽式模式时,对输出数据寄存器的读访问得到最后一次写的值,所以如果引脚配置的是推挽输出,那么需要读取引脚数据时需要重新初始化成输入模式。开漏输出的这个特点对于在进行IIC通信或者其他共用数据线的总线通信中十分友好,不需要重新初始化SDA引脚为输入模式也可以读取引脚数据。

第二个,开漏输出可以用来匹配电平,比如我们有一个单片机的引脚输出是5V,但是我们的目标器件电压是3.3V,此时我们可以初始化引脚为开漏输出,外部接一个3.3V上拉电阻,这样的话当我们的GPIO处于高阻态时输出端就会被上拉电阻拉到3.3V,同理反过来也是一样的,也就是说STM32的引脚配置成开漏输出外部接一个5V上拉电阻就能实现5V输出,STM官方社区也给出了这个说明,但是笔者没有尝试过,所以大家请谨慎尝试。

第三呢就是可以支持几个设备同时挂接到同一条线上,比如我们使用IIC通信,有多个主设备时如果我们设置成推挽输出,可能会导致主设备之间产生短路。

最后就是开漏输出能够实现线与操作,什么是线与?线与简单理解就是当一根总线上的设备输出全部为高电平时,总线处于高电平状态,一旦有一个设备的输出是低电平,总线处于低电平状态。比如在IIC总线的仲裁机制就是通过线与逻辑实现的,我们知道当主机要开启IIC通信时需要先发送一个起始信号,也就是在SCL为高时,将SDA拉高,再拉低,但是当IIC总线上有多个主设备时,就需要有一个仲裁机制来判断谁先占用总线,谁后占用总线。当主设备将SDA拉高后,需要检查SDA的电平如果此时SDA电平为高,说明主设备可以占用总线,如果此时SDA电平为低,说明总线已经被其他设备占用。

四、程序分析

最后我们说回来最开始介绍的两行代码

// SDA方向
#define MPU_SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define MPU_SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

对照上面的表格与寄存器我们可以知道,第一行是将SDA配置成了下拉输入模式,第二行是将SDA配置成了通用推挽输出模式,对应的引脚是PB7。

我们从这个配置来说,可以推测他在初始化IIC引脚是配置的是推挽输出模式,所以需要不断地切换SDA引脚的输入输出状态,不是很友好,而且当总线上需要有多个主设备时会造成短路,所以建议后续IIC引脚还是初始化成开漏输出模式。

笔者测试了一下使用STM32F103C8T6将引脚初始化为开漏输出模式后将引脚电平拉高,用万用表测试引脚输出电平,发现是低电平,也就是说如果想在初始化时初始化为开漏输出,必须要保证引脚外面要接一个上拉电阻,否则无法正常进行IIC通信,所以说在使用软件模拟IIC时如果没有多主机的需求还是建议初始化成推挽输出模式。

相关文章:

【STM32进阶笔记】GPIO端口

前段时间由于其他原因&#xff0c;专栏暂停更新了较长一段时间&#xff0c;现在恢复更新&#xff0c;争取继续为大家创造有价值的内容&#xff0c;期待大家的订阅关注&#xff0c;欢迎互相学习交流。 在STM32速成笔记系列专栏中其实已经对GPIO的一些必要知识进行了介绍&#xf…...

探索HTML5 Geolocation:精准定位网页的新纪元

在互联网技术日新月异的今天&#xff0c;地理定位已经成为众多Web应用不可或缺的一部分&#xff0c;而HTML5 Geolocation API正是这一领域的关键技术。本文将深入剖析HTML5 Geolocation API的工作原理、使用方法&#xff0c;并通过实战代码示例&#xff0c;带你领略其在现代网页…...

C++程序打开EXCEL2010失败,提示:远程过程调用失败

前两天将Foxit福昕PDF阅览器升级到了最新版本&#xff0c;导致了这个问题&#xff0c;参照这篇文章才知道是升级了福昕阅读器引起的&#xff1a; c#调用excel报错(异常来自HRESULT:0X80010105(RPC_SERVERFAULT)) 这个问题折腾了很久才搞定&#xff0c;网上的很多办法都不靠谱…...

错题记录(小测)

单选 错题1 错题2 错题3 代码题 反转链表 链表的回文结构...

ChromeOS 逐渐靠近安卓

ChromeOS 逐渐 “安卓化” 谷歌在博客中透露&#xff0c;将在ChromeOS底层更广泛地使用和Android相同的技术栈。一个具体的例子是&#xff0c;ChromeOS现在已经开始使用Android的蓝牙协议栈&#xff0c;取代了之前使用的自己的协议栈。这次改变不仅提高了蓝牙配对速度&#xf…...

vector模拟实现

目录 vector介绍 vector示意图 关于vector扩容的问题 vector框架 构造函数 析构函数 vector有关空间容量函数 insert和erase pop_back和push_back 其它构造函数 拷贝构造 迭代器区间构造 运算符重载 关于迭代器失效问题【重点】 有关insert发生迭代器失效 有关…...

RV32F\RV32D指令集

RV32F\RV32D指令集 F扩展1、浮点控制状态寄存器2、指令类型F扩展 F扩展增加了32个浮点寄存器f0-f31,每个32位宽,以及一个浮点控制和状态寄存器fcsr,其中包含浮点单元的工作模式和异常状态。FLEN=32表示F单精度浮点扩展,大多数浮点指令对浮点寄存器中的值进行操作。浮点加载…...

安卓VirtualDisplay虚拟屏幕如何实现没有内容显示mirror内容(aosp14版本)

背景&#xff1a; 上一篇blog已经对mirror模式显示镜像屏幕内容进行了详细讲解&#xff1a; 安卓VirtualDisplay虚拟屏幕如何实现没有内容显示mirror屏幕内容 不过这个分析版本是基于aosp13&#xff0c;在这个发布后&#xff0c;有学员在aosp14上进行验证&#xff0c;发现还…...

YOLOv10在RK3588上的测试(进行中...)

1.代码源 国内镜像站在gitcode。这个镜像站也基本上包含了github上常用项目的镜像。然后它的主发布源在这里&#xff1a; GitCode - 全球开发者的开源社区,开源代码托管平台 yolov10是清华主导做的... 然后&#xff0c;在维护列表里看到了这个&#xff1a; 2024年05月31日&am…...

git的ssh安装,windows通过rsa生成密钥认证问题解决

1 windows下载 官网下载可能出现下载太慢的情况&#xff0c;Git官网下载地址为&#xff1a;官网&#xff0c;推荐官网下载&#xff0c;如无法下载&#xff0c;可移步至CSDN&#xff0c;csdn下载地址&#xff1a;https://download.csdn.net/download/m0_46309087/12428308 2 Gi…...

果园预售系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;果树管理&#xff0c;果园管理&#xff0c;果园预约管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论坛&#xff0c;公告&a…...

学了这篇面试经,轻松收割网络安全的offer

网络安全面试库 吉祥学安全知识星球&#x1f517;除了包含技术干货&#xff1a;Java代码审计、web安全、应急响应等&#xff0c;还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 0x1 应届生面试指南 网络安全面…...

双向转发检测BFD(学习笔记)

定义 双向转发检测BFD&#xff08;Bidirectional Forwarding Detection&#xff09;是一种全网统一的检测机制&#xff0c;用于快速检测、监控网络中链路或者IP路由的转发连通状况 BFD检测机制 BFD的检测机制是两个系统建立BFD会话&#xff0c;并沿它们之间的路径周期性发送B…...

Spring Boot:Java 应用开发高效之道

Spring Boot 是一种革命性的框架&#xff0c;旨在简化 Java 应用的创建和部署过程。通过自动化配置和简化项目搭建流程&#xff0c;Spring Boot 大大加速了开发周期&#xff0c;让 Java 应用开发变得更加高效和便捷。 核心优势&#xff1a; 快速启动和简化配置&#xff1a;Spr…...

WebSocket 入门教程

什么是 WebSocket&#xff1f; WebSocket 是一种通信协议&#xff0c;它在单个 TCP 连接上提供全双工通信。与传统的 HTTP 不同&#xff0c;WebSocket 允许服务器主动向客户端推送数据&#xff0c;而不仅仅是客户端请求数据。这使得 WebSocket 非常适用于需要低延迟和实时通信…...

C++中extern “C“的用法

目的 extern "C"是经常用到的东西&#xff0c;面试题目也经常出现&#xff0c;然则&#xff0c;实际用时&#xff0c;还是经常遗忘&#xff0c;因此&#xff0c;深入的了解一下&#xff0c;以增强记忆。 extern "C"指令非常有用&#xff0c;因为C和C的近亲…...

常见机器学习的原理及优略势

有监督 一、线性回归&#xff08;Linear Regression) 1. 算法原理 线性回归&#xff08;Linear Regression&#xff09;是一种基本的回归算法&#xff0c;它通过拟合一个线性模型来预测连续型目标变量。线性回归模型的基本形式是&#xff1a;y w1 * x1 w2 * x2 … wn * …...

李诞-2021.8脱口秀工作手册-1-工作的本质是交易;脱口秀是一份和生活分不开的工作,你的全部人生都理应要为你的创作提供养分,为它服务。

1 首先&#xff0c;这是一份工作&#xff0c;工作的本质是交易。 我们在用自己的时间和才能&#xff0c;通过一家公司&#xff0c;与市场交换金钱。 根据诺贝尔经济学奖得主科斯的著名理论&#xff0c;公司会产生的原因&#xff0c;就是人们自己直接与市场交易成本太高&…...

生命在于学习——Python人工智能原理(3.3)

三、深度学习 4、激活函数 激活函数的主要作用是对神经元获得的输入进行非线性变换&#xff0c;以此反映神经元的非线性特性。常见的激活函数有线性激活函数、符号激活函数、Sigmod激活函数、双曲正切激活函数、高斯激活函数、ReLU激活函数。 &#xff08;1&#xff09;线性…...

【C++11】智能指针问题

文章目录 RAII一、auto_ptr二、unique_ptr三、shared_ptrshared_ptr的循环引用问题 四、weak_ptr总结 RAII RAII就是将资源交给一个对象管理&#xff0c;这个对象能进行正常的管理和释放资源。 一、auto_ptr auto_ptr的问题是&#xff1a;在拷贝构造和赋值重载时&#xff0c…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...