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

STM32-GPIO编程

一、GPIO

1.1 基本概念

GPIO(General-purpose input/output)通用输入输出接口

--GP 通用

--I input输入

--o output输出

通用输入输出接口GPIO是嵌入式系统、单片机开发过程中最常用的接口,用户可以通过编程灵活的对接口进行控制,实现对电路板上LED、数码管、按键等常用设备控制驱动,也可以作为串口的数据收发管脚,或AD的接口等复用功能使用。其作用和功能是非常重要的。

1.2实际应用

input 输入-数据采集 按键、光照(光敏传感器)、ADC、各种传感器

output 输出 - 设备控制 LED灯、数码管、继电器(小控大)

二、功能描述

1、IO结构框图

保护二极管:(1)电压过大,有保护作用;(2)反向电动势。

上拉电阻:上拉电阻是一种用于数字电路中的电阻元件,它的作用是将信号线拉高到高电平(逻辑1)状态。当信号线不被其他元件拉低时,上拉电阻会将信号线连接到正电源,使其保持在高电平状态。

施密特触发器:电压比较器    例如 0  <= 0.7       1>=1.7

写——>置位/复位寄存器:只能写1(0到15是置位,16到31是复位)

输出控制:使用反相器 

问:VDD、VSS、VCC分别表示什么意思?

           VCC :接入电路的电压

           VDD :  元器件内部的工作电压

           VSS :  公共接地端电压

问:施密特触发器的作用?

由于外部输入的信号,可能会出现脉冲等噪声的影响,为了让信号更加清晰,所以就设置了TTL施密特触发器来进行整形。

问:模拟信号和数字信号的区别?

1、时间连续性不同:

1)模拟信号时间上是连续的;

2)数字信号时间上不是连续的。

2、幅度变化不同:

1)模拟信号指幅度的取值是连续的(幅值可由无限个数值表示)。

2)数字信号指幅度的取值是离散的,幅值表示被限制在有限个数值之内。

3、信号传输方式不同:

1)模拟信号是用模拟量的电压或电流来表示的电信号;

2)数字信号是通过0和1的数字串所构成的数字流来传输的。

4、保密性不同:

1)模拟信号的微波通信和有线明线通信,很容易被窃听。只要收到模拟信号,就容易得到通信内容。

2)数字信号保密性较强,语音信号可以先进行加密处理,再进行传输,在接收端解密后再变换还原成模拟信号。

  1. 功能详述

浮空输入

IO端口 -  施密特触发器 - 输入数据寄存器 - 读

通俗讲就是让管脚什么都不接,悬空着。

此时VDD和VSS所在路径的两个开关同时断开。因为没有上拉和下拉,所以当IO口没有接输入的时候,此时的电平状态会是一个不确定的值,完全由外部输入决定。

由于浮空输入一般多用于外部按键输入,结合图上的输入部分电路,浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的,易受干扰。 

优势:

这一种输入模式的电平会完全取决于外部电路而与内部电路无关

      缺点:

在没有外部电路接入的时候,IO脚浮空会使得电平不确定

应用:

该模式是STM32复位之后的默认模式,一般用作对开关按键的读取或用于标准的通讯协议,比如IIC、USART的等。

上拉输入 

 IO端口  -   上拉电阻  -  施密特触发器 - 输入数据寄存器 - 读

输入的电平不会因上下浮动而导致输入信号不稳定,当外部没有信号输入时,上拉电阻会将输入信号钳在高电平,此时引脚始终读到高电平信号。

下拉输入 

 IO端口  -   下拉电阻  -  施密特触发器 - 输入数据寄存器 - 读

输入的电平不会因上下浮动而导致输入信号不稳定,当外部没有信号输入时,下拉电阻会将输入信号钳在低电平,此时引脚始终读到低电平信号。

模拟输入 

IO端口 - 片上外设模块(电压信号)

信号进入后不经过上拉电阻或者下拉电阻,关闭施密特触发器,经由另一线路把电压信号传送到片上外设模块。 所以可以理解为模拟输入的信号是未经处理的信号,是原汁原味的信号。

应用:当 GPIO 引脚用于 ADC 采集电压的输入通道时,则需要选择“模拟输入”功能,因为经过施密特触发器后信号只有 0、1 两种状态,所以 ADC 外设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。

开漏输出 

推挽 开漏 高阻 这都是谁想出来的词??_哔哩哔哩_bilibili

开漏输出:PMOS不使用

输出寄存器上的的’0’激活 N-MOS,输出寄存器上的’1’将端口置于高阻状态 (P-MOS 从不被激活 )。 

无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动

可以利用改变上拉电源的电压来适应所需,进而提高外部电路的驱动能力。

MOS管的漏极等于啥也没接,处于一个开路状态,所以这个模式称之为开漏模式

优势1:

虽然我们可以看到开漏输出是没有办法在内部输出一个高电平,但是这一个看似是缺点。其实实际上是一种优点。当给一个低电平的时候,MOS管没有导通,此时电压不确定导致无法输出高电平,但是一旦我们在外部增加一个上拉,那么这一个缺点就会被有效避免。并且,因为是我们自己设计一个上拉,这个上拉的电压是由我们自己确定,这样我们就可以根据外部电路需要多少V的高电平来给这一个上拉的电压,可以更好的适应更多情况。如下图,我们可以给定任意的VDD电压,来适应我们实际所需要的情况。

优势2:

开漏输出的实质其实就是一个OD门(OD:漏极输出(Open Drain))。而在数电中,OD门有一个非常重要的特性就是可以实现线与的功能,简单来说,就是在像IIC这样的总线协议中,只要有一个给低电平,那么总线都会被拉低。

    推挽输出

输出数据寄存器'0'——>输出控制‘1’——>NMOS激活

输出数据寄存器'1'——>输出控制‘0’——>PMOS激活

输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-MOS。

具备输出高低电平的能力。

推挽输出就是可以需要利用两个不同的MOS管来实现输出。

推挽输出模式下(P-MOS管+N-MOS管),通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。

开漏和推挽的区别

三、GPIO相关寄存器

     4 个 32 位 配 置 寄 存 器 

           GPIOx_MODER       模式寄存器

           GPIOx_OTYPER      输出模式寄存器

           GPIOx_ OSPEEDR  输出速度寄存器

           GPIOx_PUPDR        上拉下拉寄存器

个 32 位数据寄存器 

           GPIOx_IDR      输入数据寄存器

           GPIOx_ODR    输出数据寄存器

      1个 32 位置位 复位寄存器 

           GPIOx_BSRR  置位 / 复位寄存器

       2 个 32 位复用功能寄存器 

           GPIOx_AFRH 

           GPIOx_AFRL

四、寄存器详细讲解

(英文参考手册151页)

使能时钟寄存器(RCC_IOPENR)

偏移地址:偏移地址就是计算机里的内存分段后,在段内某一地址相对于段首地址(段地址)的偏移量。

  如8086存储系统中 20位的物理地址(就是数据存储的实际地址)=16位的段基地址*16+16位的偏移量  (0X34)

以下是STM32F051的  (101页)

GPIO端口模式寄存器(GPIOx_MODER)(x=A...D,F)

偏移地址:0x00

复位值:

0xEBFF FFFF 端口A

0xFFFF FFFF 其他口

GPIO 端口输出类型寄存器 (GPIOx_OTYPER) (x = A..D,F) 

偏移地址:0x04 

复位值: 0x0000 0000

GPIO 口输出速度寄存器 (GPIOx_OSPEEDR) (x = A..D,F)

偏移地址:0x08 

复位值: 0x0000 0000

GPIO 口上拉 / 下拉寄存器 (GPIOx_PUPDR) (x = A..D,F) 

偏移地址:0x0C 

复位值:

0x2400 0000 端口 A

0x0000 0000 其它端口

GPIO 端口输入数据寄存器 (GPIOx_IDR) (x = A..D,F) 

偏移地址:0x10 

复位值: 0x0000 XXXX (X 表明不定 )

GPIO 端口输出数据寄存器 (GPIOx_ODR) (x = A..D,F) 

偏移地址:0x14 

复位值: 0x0000 0000

GPIO 端口置位 / 复位寄存器 (GPIOx_BSRR) (x = A..D,F) 

偏移地址:0x18 

复位值:0x0000 0000

端口位复位寄存器(GPIOx_BRR) (x=A..G) 

偏移地址:0x28 

复位值: 0x0000 0000

五、点亮一盏LED灯

1 实验步骤

   1.查看开发板实物,找到LED灯

   2.查看底板原理图

要让LED2亮,则为低电平

只要将PB2配置为低电平,灯就点亮

2 编程实现

 寄存器分析

RCC->IOPENR |= 1<<1;

配置PB2为输出模式

GPIOB->MODER  &=  ~(0X3<<4); //先清零

GPIOB->MODER   |= 1<<4; //后置位

选择推挽输出模式

GPIOB->OTYPER  &= ~(1<<2);

GPIOB->ODR  &= ~(1<<2);

MX配置

代码编写

	//使能GPIO端口的时钟
	RCC->IOPENR |= 1<<1;				//配置GPIO为输出模式
	GPIOB->MODER &= ~(0X3<<4);	//先清零
	GPIOB->MODER |= 1<<4;	//后置位//选择推挽输出模式
	GPIOB->OTYPER &= ~(1<<2);//控制引脚输出低电平
	GPIOB->ODR &= ~(1<<2);

版本2:使用STM32CubeMX工具

六、HAL库函数分析

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

功能: 设置或清除指定的端口位

参数:GPIO_TypeDef *GPIOx  端口号

           uint16_t GPIO_Pin         引脚号

           GPIO_PinState PinState  电平状态

                        GPIO_PIN_SET         1 

                        GPIO_PIN_RESET    0

返回值:无

void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t  GPIO_Pin) 

功能: 切换指定的引脚电平状态

参数:GPIO_TypeDef * GPIOx  端口号

            uint16_t  GPIO_Pin     引脚号

返回值:无

GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef * GPIOx,  uint16_t GPIO_Pin) 

功能: 读取指定的引脚电平状态

参数:GPIO_TypeDef * GPIOx  端口号

            uint16_t  GPIO_Pin     引脚号

返回值:GPIO_PinState 电平状态

              GPIO_PIN_RESET   0

              GPIO_PIN_SET        1

利用HAL库函数实现LED灯闪烁

练习:实现流水灯效果

方法一:

方法二:

  1. 实验:按键控制LED灯亮灭(输入)
  1. .查看实物找到按键和控制的LED灯

    五向按键 - S1

  1. 查看原理图  

MX配置

所有的机械元件都有抖动问题

关于消抖问题

写法一:延时消抖

写法二:抬手检测

相关文章:

STM32-GPIO编程

一、GPIO 1.1 基本概念 GPIO&#xff08;General-purpose input/output&#xff09;通用输入输出接口 --GP 通用 --I input输入 --o output输出 通用输入输出接口GPIO是嵌入式系统、单片机开发过程中最常用的接口&#xff0c;用户可以通过编程灵活的对接口进行控制&#xff0c;…...

Go语言基础知识学习(一)

Go基本数据类型 bool bool型值可以为true或者false,例子&#xff1a; var b bool true数值型 类型表示范围int8有符号8位整型-128 ~ 127int16有符号16位整型-32768 ~ 32767int32有符号32位整型-2147783648 ~ 2147483647int64有符号64位整型uint8无符号8位整型0 ~ 255uint16…...

Vue 3项目的目录结构

使用vite创建完VUE项目后&#xff0c;使用VS Code编辑器打开项目目录&#xff0c;可以看到一个默认生成的项目目录结构 下图是目录结构&#xff1a; 详细介绍.vscode&#xff1a;存放VS Code编辑器的相关配置。 node_modules&#xff1a;存放项目的各种依赖和安装的插件。…...

RPG项目01_技能释放

基于“RPG项目01_新输入输出”&#xff0c; 修改脚本文件夹中的SkillBase脚本&#xff1a; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; //回复技能&#xff0c;魔法技能&#xff0c;物理技能…...

Leetcode—209.长度最小的子数组【中等】

2023每日刷题&#xff08;五十六&#xff09; Leetcode—209.长度最小的子数组 实现代码 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int left 0, right 0;int ans nums.size() 1, s 0;for(; right < nums.size(); righ…...

Nacos源码解读12——Nacos中长连接的实现

短连接 VS 长连接 什么是短连接 客户端和服务器每进行一次HTTP操作&#xff0c;就建立一次连接&#xff0c;任务结束就中断连接。 长连接 客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭&#xff0c;客户端再次访问这个服务器时&#xff0c;会继续使用这一条已经建立…...

k8s 安装部署

一&#xff0c;准备3台机器&#xff0c;安装docker&#xff0c;kubelet、kubeadm、kubectl firewall-cmd --state 使用下面命令改hostname的值&#xff1a;(改为k8s-master01)另外两台改为相应的名字。 172.188.32.43 hostnamectl set-hostname k8s-master01 172.188.32.4…...

TCP/IP五层(或四层)模型,IP和TCP到底在哪层?

文章目录 前言一、应用层二.传输层三.网络层&#xff1a;四.数据链路层五.物理层&#xff1a;六.OSI七层模型&#xff1a;1.物理层&#xff08;Physical Layer&#xff09;&#xff1a;2.数据链路层&#xff08;Data Link Layer&#xff09;&#xff1a;3.网络层&#xff08;Ne…...

STM32串口接收不定长数据(空闲中断+DMA)

玩转 STM32 单片机&#xff0c;肯定离不开串口。串口使用一个称为串行通信协议的协议来管理数据传输&#xff0c;该协议在数据传输期间控制数据流&#xff0c;包括数据位数、波特率、校验位和停止位等。由于串口简单易用&#xff0c;在各种产品交互中都有广泛应用。 但在使用串…...

LeetCode56. Merge Intervals

文章目录 一、题目二、题解 一、题目 Given an array of intervals where intervals[i] [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input. Example 1: Input: interva…...

【华为OD题库-083】玩牌高手-Java

题目 给定一个长度为n的整型数组&#xff0c;表示一个选手在n轮内可选择的牌面分数。选手基于规则选牌&#xff0c;请计算所有轮结束后其可以获得的最高总分数。 选择规则如下: 1.在每轮里选手可以选择获取该轮牌面&#xff0c;则其总分数加上该轮牌面分数&#xff0c;为其新的…...

ARM day3

题目&#xff1a;实现3盏灯的流水 代码&#xff1a; .text .global _start _start: 设置RCC寄存器使能 LDR R0,0X50000A28 LDR R1,[R0] ORR R1,R1,#(0X1<<4) ORR R1,R1,#(0X1<<5) STR R1,[R0]设置PE10管脚为输出模式 LDR R0,0X50006000 LDR R1,[R0] BIC R1,R1,…...

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-2稳定性分析Stability

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-2稳定性分析Stability 0. 序言1. 稳定的分类2. 稳定的对象3. 稳定的系统4. 系统稳定性的讨论5. 补充内容——Transfer Function(传递函数) - nonzero Initial Condition(非零初始…...

Android Audio实战——音频链路分析(二十五)

在 Android 系统的开发过程当中,音频异常问题通常有如下几类:无声、调节不了声音、爆音、声音卡顿和声音效果异常(忽大忽小,低音缺失等)等。尤其声音效果这部分问题通常从日志上信息量较少,相对难定位根因。想要分析此类问题,便需要对声音传输链路有一定的了解,能够在链…...

PHP基础 - 常量字符串

常量 在PHP中,常量是一个简单值的标识符,定义后默认是全局变量,可以在整个运行的脚本的任何地方使用。常量由英文字母、下划线和数字组成,但数字不能作为首字母出现。 PHP中定义常量的方式是使用define()函数,其语法如下: bool define( string $name, mixed $value [,…...

Linux查看命令的绝对路径

linux查看命令的绝对路径 在Linux中&#xff0c;可以使用以下命令来查看命令的绝对路径&#xff1a; 1、which 命令名 例如&#xff0c;要查看chronyc命令的绝对路径&#xff0c;可以运行&#xff1a; which chronyc 2、whereis 命令名 例如&#xff0c;要查看chronyc命令…...

Docker build 无法解析域名

### 报错 Docker build 无法解析域名 报错&#xff1a;ERROR [ 2/12] RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 解决Docker build无法解析域名 # 追加到 etc/docker/daemon.json&#xff0c;注意JSON的格式 {"dn…...

退稿论文重复率太高会怎么样【保姆教程】

大家好&#xff0c;今天来聊聊退稿论文重复率太高会怎么样&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff1a; 退稿论文重复率太高会怎么样 在学术出版领域&#xff0c;论文的重复率是衡量其原创性和学术诚…...

Flask 最佳实践(一)

Flask是一个轻量级而强大的Python Web框架&#xff0c;它的简洁性和灵活性使其成为许多开发者的首选。然而&#xff0c;为了确保项目的可维护性和可扩展性&#xff0c;我们需要遵循一些最佳实践。本文将探讨Flask中一些关键的最佳实践。 1. 项目结构 构建一个清晰的项目结构是…...

直流电和交流电

直流电&#xff08;Direct Current&#xff0c;简称DC&#xff09;和交流电&#xff08;Alternating Current&#xff0c;简称AC&#xff09;是电流的两种基本形式。 1. 直流电 直流电是指电流方向始终保持不变的电流。在直流电中&#xff0c;电子只能沿着一个方向移动。直流电…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

Netty自定义协议解析

目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...