【STM32进阶笔记】GPIO端口

news2025/7/15 16:08:54

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

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时如果没有多主机的需求还是建议初始化成推挽输出模式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1823560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为数据驱动的企业数字化转型之路

华为数据驱动的企业数字化转型之路 数据驱动的数字化转型是企业未来发展的关键。通过构建完善的数据治理体系&#xff0c;包括差异化的数据管理、面向业务的信息架构、数据底座建设和自助数据服务&#xff0c;企业可以提升数据的利用效率和决策能力。本文将根据华为数据治理相…

查看电子磁盘ssd空间信息并释放zfs空间@FreeBSD

发现问题 在某宝买了一块32G的ssd电子盘&#xff0c;但是在FreeBSD里面使用df看到的空间较少&#xff0c;只有15G&#xff0c;一度怀疑是发错货了。不过自己清楚的记得swap分区还分了4G&#xff0c;这样铁定是大于16G的&#xff0c;应该是32G没错。但是少掉的那部分空间跑哪里…

程序员要学会偷懒--excel转建表语句

如下需求&#xff1a;一个复杂的统战系统&#xff0c;用户信息字段总共有26个sheet&#xff0c;54张小表&#xff0c;没有什么复杂的业务逻辑&#xff0c;纯增删改查。字段目测在1000个以上。建表54张。领导交待了一句这周末完成&#xff0c;我&#xff1f;&#xff1f;&#x…

吴恩达2022机器学习专项课程C2W3:2.25 理解方差和偏差(诊断方差偏差正则化偏差方案搭建性能学习曲线)

目录 引言名词替代影响模型偏差和方差的因素1.多项式阶数2.正则化参数 判断是否有高偏差或高方差1.方法一&#xff1a;建立性能基准水平2.方法二&#xff1a;建立学习曲线 总结 引言 机器学习系统开发的典型流程是从一个想法开始&#xff0c;然后训练模型。初次训练的结果通常…

java:spring使用【@ImportResource】导入一个xml里面定义的bean

# 项目代码资源&#xff1a; 可能还在审核中&#xff0c;请等待。。。 https://download.csdn.net/download/chenhz2284/89434148 # 项目代码 【pom.xml】 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-start…

220v转3v用多大电阻

在设计一个电压转换电路&#xff0c;将220V交流&#xff08;AC&#xff09;电压转换为3V直流&#xff08;DC&#xff09;电压时&#xff0c;我们需要考虑几个关键因素&#xff0c;包括安全、效率和电路的稳定性。AH8651是一款DC-DC转换器&#xff0c;通常用于将较高的输入电压转…

测试 halcon measure_projection 算子

期望结果完全相同&#xff0c;但是下面的测试结果和halcon的差值如下: [0.132838, 0.231991, 0.265157, 0.296903, 0.0998573, 0.165907, 0.230686, 0.130266, 0.0977104, 0.197109, 0.198173, 0.197086, 0.190943, 0.177665, 0.163521, 0.146541, 0.161362, 0.166666, 0.2281…

【GIS矢量切片】tippecanoe在Windows和CentOS中的安装

组件安装记录 背景介绍Windows下安装1、下载工具2、存放安装包3、进入DOS终端4、在终端执行命令5、下载程序6、放置源码7、修改配置信息8、编译9、测试10、参数说明瓦片输出瓦片描述和权属信息输入文件和图层名输入文件的并行处理输入文件的投影缩放级别瓦片分辨率CentOS 7安装…

图像的几何变换之平移

文章目录 前言需求代码运行结果图 前言 图像的几何变换是一个再基础不过的知识点&#xff0c;包括等距变换&#xff0c;相似变换&#xff0c;仿射变换和投影变换。图像的几何变换是指对图像的位置&#xff0c;尺寸&#xff0c;大小&#xff0c;形状和投影进行变换&#xff0c;…

Character Region Awareness for Text Detection论文学习

​1.首先将模型在Synth80k数据集上训练 Synth80k数据集是合成数据集&#xff0c;里面标注是使用单个字符的标注的&#xff0c;也就是这篇文章作者想要的标注的样子&#xff0c;但是大多数数据集是成堆标注的&#xff0c;也就是每行或者一堆字体被整体标注出来&#xff0c;作者…

AI对齐研究方法:建立一个足够对齐的人工智能系统,可以帮助我们解决所有其他对齐问题。 AI安全

与人类价值观保持一致&#xff0c;并遵循人类的意图。 找到一个无限可扩展的解决方案可能非常困难。相反&#xff0c;我们的目标是一种更务实的方法&#xff1a;建立和调整一个系统&#xff0c;该系统可以比人类更快、更好地调整研究进展。 使通用人工智能&#xff08;AGI&am…

2024年社会发展与城市规划国际会议(SDUP 2024)

2024年社会发展与城市规划国际会议&#xff08;SDUP 2024&#xff09; 2024 International Conference on Social Development and Urban Planning 【重要信息】 大会地点&#xff1a;杭州 大会官网&#xff1a;http://www.iacsdup.com 投稿邮箱&#xff1a;iacsdupsub-conf.co…

灾备建设中虚拟机细粒度恢复的含义及技术使用

灾备建设中为了考虑虚拟机恢复的效率与实际的用途&#xff0c;在恢复上出了普通的恢复虚拟机&#xff0c;也有其余的恢复功能&#xff0c;比如瞬时恢复&#xff0c;细粒度恢复等。这里谈的就是细粒度恢复。 首先细粒度恢复是什么&#xff0c;这个恢复可以恢复单个备份下来的文…

HCIA-Datacom H12-811 题库

LDP 邻居发现有不同的实现机制和规定&#xff0c;下面关于LDP 邻居发现的描述错误的是&#xff1a; A&#xff1a;LDP发现机制包括LDP基本发现机制和LDP扩展发现机制 B&#xff1a;LDP基本发现机制可以自动发现直连在同条链路上的LDP Peers C&#xff1a;LDP扩展发现机制够发现…

Golang:使用时会遇到的错误及解决方法详解

Go语言使用时常常会遇到的一些错误及解决方法&#xff0c;文中的示例代码讲解详细&#xff0c;感兴趣的小伙伴可以了解一下 1、go: go.mod file not found in current directory or any parent directory go mod init name 2、Failed to build the application: main.go:4:2:…

请求headers处理

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 有时在请求一个网页内容时&#xff0c;发现无论通过GET或者是POST以及其他请求方式&#xff0c;都会出现403错误。产生这种错误是由于该网页为了防止…

基于Pytorch框架的深度学习ConvNext神经网络宠物猫识别分类系统源码

第一步&#xff1a;准备数据 12种宠物猫类数据&#xff1a;self.class_indict ["阿比西尼猫", "豹猫", "伯曼猫", "孟买猫", "英国短毛猫", "埃及猫", "缅因猫", "波斯猫", "布偶猫&q…

ARM单片机使用CAN总线部署BootLoader

1.引言 1.1.单片机开发BootLoader意义 单片机开发BootLoader的原因主要与其在嵌入式系统中的关键作用有关。BootLoader是硬件启动的引导程序&#xff0c;它在操作系统内核或用户应用程序运行之前执行。以下是单片机开发BootLoader的主要原因&#xff1a; 初始化硬件设备&…

2024年春季学期《算法分析与设计》练习13

A:菱形图案 题目描述 KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的菱形图案。 输入 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;。 输出 针对每行输入&#xff0c;输出用“*”组成的菱形&#xff0c;…

Java 18新特性概览与解读

随着技术的不断进步&#xff0c;Java作为最流行的编程语言之一&#xff0c;也在持续地进行版本更新&#xff0c;为开发人员提供更强大、更高效的工具和特性。Java 18作为最新的稳定版本&#xff0c;引入了一系列引人注目的新特性和改进。以下是对Java 18中一些主要新特性的详细…