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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

帕金森运动小贴士,壁纸里的健康密码

&#x1f31f; 在这个快节奏的时代&#xff0c;我们越来越关注身体的健康。今天&#xff0c;我想和大家分享一份特别的小贴士&#xff0c;它藏在一张精致的小红书壁纸里&#xff0c;是关于帕金森病的运动建议。帕金森病是一种常见的神经系统疾病&#xff0c;适当的运动对于缓解…

课设--学生成绩管理系统(二)

欢迎来到 Papicatch的博客 目录 &#x1f40b;引言 &#x1f988;编写目的 &#x1f988;项目说明 &#x1f40b;产品介绍 &#x1f988;产品概要说明 &#x1f988;产品用户定位 &#x1f988;产品中的角色 &#x1f40b; 产品总体业务流程图 &#x1f40b; 产品功…

基于springboot的城市垃圾分类管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的城市垃圾分类管理系统,…

深入浅出 Qt 中 QListView 的设计思想,并掌握大规模、高性能列表的实现方法

在大规模列表控件的显示需求中&#xff0c;必须解决2个问题才能获得较好的性能&#xff1a; 第一就是数据存在哪里&#xff0c; 避免出现数据的副本。第二就是如何展示Item&#xff0c;如何复用或避免创建大量的Item控件。 在QListView体系里&#xff0c;QAbstractListModel解…

SwaggerSpy:一款针对SwaggerHub的自动化OSINT安全工具

关于SwaggerSpy SwaggerSpy是一款针对SwaggerHub的自动化公开资源情报&#xff08;OSINT&#xff09;安全工具&#xff0c;该工具专为网络安全研究人员设计&#xff0c;旨在简化广大红队研究人员从SwaggerHub上收集已归档API信息的过程&#xff0c;而这些OSINT信息可以为安全人…

Spring IoC【控制反转】DI【依赖注入】

文章目录 控制反转&#xff08;IoC&#xff09;依赖注入&#xff08;DI&#xff09;IoC原理及解耦IoC 容器的两种实现BeanFactoryApplicationContext IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&…

18.9k star!一个高性能的嵌入式分析型数据库,主要用于数据分析和数据处理任务

大家好&#xff0c;今天给大家分享的是一个开源的面向列的关系数据库管理系统(RDBMS)。 DuckDB是一个嵌入式的分析型数据库&#xff0c;它提供了高性能的数据分析和数据处理能力。DuckDB的设计目标是为数据科学家、分析师和数据工程师提供一个快速、灵活且易于使用的数据分析工…

idea 配置文件中文乱码

再进行springboot项目开发时发现新建的配置文件中文注释乱码&#xff0c;如下: 处理办法: 1、打开idea&#xff0c;在 File 中找到 Settings,如下图 2、搜索 encodings 找到 File Encodings&#xff0c;如下图 3、将上图中圈上的地方全部改为 UTF-8 编码最后点击 Apply 应用即…

RabbitMQ学习总结

目录 一:介绍 二:应用场景 三:工作原理 组成部分说明 消息发布接收流程 四:下载安装 五:环境搭建 创建Maven工程 生产者 消费者 六:工作模式 Work queues Publish/subscribe 生产者 消费者 Routing 生产者 ​消费者 思考 Topics 生产者 匹配规则…

[FFmpeg学习]windows环境sdl播放音频试验

参考资料&#xff1a; FFmpeg和SDL2播放mp4_sdl 播放mp4 声音-CSDN博客 SimplePlayer/SimplePlayer.c at master David1840/SimplePlayer GitHub 在前面的学习中&#xff0c;通过获得的AVFrame进行了播放画面&#xff0c; [FFmpeg学习]初级的SDL播放mp4测试-CSDN博客 播放…

数据中心布线管理:预标记线缆与移动扫描技术的融合

随着信息技术的飞速发展&#xff0c;数据中心布线管理面临着前所未有的挑战。传统的布线管理方式已无法满足现代数据中心高效、准确和可靠的需求。在这样一个背景下&#xff0c;预标记线缆与移动扫描技术的结合&#xff0c;为数据中心布线管理带来了革命性的解决方案。 布线管理…

opencv安装笔记 各种平台

目录 python安装opencv-python c 麒麟arm系统安装和用法 python安装opencv-python pypi上搜索 Search results PyPI 现在安装是一个版本&#xff0c;大于3.6都可以安装 c 麒麟arm系统安装和用法 参考&#xff1a; ffmpeg rknn麒麟系统 安装 opencv_ffmpeg4 解码示例-CSDN…

C#下WinForm多语种切换

这是应一个网友要求写的&#xff0c;希望对你有所帮助。本文将介绍如何在一个WinForm应用程序中实现多语种切换。通过一个简单的示例&#xff0c;你将了解到如何使用资源文件管理不同语言的文本&#xff0c;并通过用户界面实现语言切换。 创建WinForm项目 打开Visual Studio&a…

【一步一步了解Java系列】:认识String类

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 个人主页&#xff1a;Gu Gu Study专栏&#xff1a;一步一步了解Java 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1a;小闭…

【Netty】nio阻塞非阻塞Selector

阻塞VS非阻塞 阻塞 阻塞模式下&#xff0c;相关方法都会导致线程暂停。 ServerSocketChannel.accept() 会在没有建立连接的时候让线程暂停 SocketChannel.read()会在没有数据的时候让线程暂停。 阻塞的表现就是线程暂停了&#xff0c;暂停期间不会占用CPU&#xff0c;但线程…

ANSYS EMC解决方案与经典案例

EMC问题非常复杂&#xff0c;各行各业都会涉及&#xff0c;例如航空、航天、船舶、汽车、火车、高科技、物联网、消费电子。要考虑EMC的对象很多&#xff0c;包含整个系统、设备、PCB、线缆、电源、芯片封装。而且技术领域覆盖广&#xff0c;涉及高频问题、低频问题&#xff1b…

Databricks超10亿美元收购Tabular;Zilliz 推出 Milvus Lite ; 腾讯云支持Redis 7.0

重要更新 1. Databricks超10亿美元收购Tabular&#xff0c;Databricks将增强 Delta Lake 和 Iceberg 社区合作&#xff0c;以实现 Lakehouse 底层格式的开放与兼容([1] [2])。 2. Zilliz 推出 Milvus Lite 轻量级向量数据库&#xff0c;支持本地运行&#xff1b;Milvus Lite 复…

统计信号处理基础 习题解答10-16

题目&#xff1a; 对于例10.1&#xff0c;证明由观察数据得到的信息是&#xff1a; 解答&#xff1a; 基于习题10-15的结论&#xff0c;&#xff0c;那么&#xff1a; 而根据习题10-15的结论&#xff1a; 此条件概率也是高斯分布&#xff0c;即&#xff1a; 根据相同的计算&a…

win10能用微信、QQ,不能打开网页

今天上班&#xff0c;打开电脑&#xff0c;突然遇到一个问题&#xff0c;发现QQ、微信可以登录&#xff0c;但是任何网页都打不开&#xff0c;尝试了重启电脑和路由器都不行&#xff0c;最终解决了电脑可以访问网页的问题&#xff0c;步骤如下&#xff1a; 1、打开电脑的网络设…

Parallels Desktop 19 for mac破解版安装激活使用指南

Parallels Desktop 19 for Mac 乃是一款适配于 Mac 的虚拟化软件。它能让您在 Mac 计算机上同时运行多个操作系统。您可借此创建虚拟机&#xff0c;并于其中装设不同的操作系统&#xff0c;如 Windows、Linux 或 macOS。使用 Parallels Desktop 19 mac 版时&#xff0c;您可在 …