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)数字信号保密性较强,语音信号可以先进行加密处理,再进行传输,在接收端解密后再变换还原成模拟信号。
- 功能详述
浮空输入
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 上拉下拉寄存器
2 个 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灯闪烁

练习:实现流水灯效果
方法一:

方法二:

- 实验:按键控制LED灯亮灭(输入)
- .查看实物找到按键和控制的LED灯
五向按键 - S1
- 查看原理图






MX配置

所有的机械元件都有抖动问题
关于消抖问题
写法一:延时消抖

写法二:抬手检测

相关文章:
STM32-GPIO编程
一、GPIO 1.1 基本概念 GPIO(General-purpose input/output)通用输入输出接口 --GP 通用 --I input输入 --o output输出 通用输入输出接口GPIO是嵌入式系统、单片机开发过程中最常用的接口,用户可以通过编程灵活的对接口进行控制,…...
Go语言基础知识学习(一)
Go基本数据类型 bool bool型值可以为true或者false,例子: var b bool true数值型 类型表示范围int8有符号8位整型-128 ~ 127int16有符号16位整型-32768 ~ 32767int32有符号32位整型-2147783648 ~ 2147483647int64有符号64位整型uint8无符号8位整型0 ~ 255uint16…...
Vue 3项目的目录结构
使用vite创建完VUE项目后,使用VS Code编辑器打开项目目录,可以看到一个默认生成的项目目录结构 下图是目录结构: 详细介绍.vscode:存放VS Code编辑器的相关配置。 node_modules:存放项目的各种依赖和安装的插件。…...
RPG项目01_技能释放
基于“RPG项目01_新输入输出”, 修改脚本文件夹中的SkillBase脚本: using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; //回复技能,魔法技能,物理技能…...
Leetcode—209.长度最小的子数组【中等】
2023每日刷题(五十六) 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操作,就建立一次连接,任务结束就中断连接。 长连接 客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立…...
k8s 安装部署
一,准备3台机器,安装docker,kubelet、kubeadm、kubectl firewall-cmd --state 使用下面命令改hostname的值:(改为k8s-master01)另外两台改为相应的名字。 172.188.32.43 hostnamectl set-hostname k8s-master01 172.188.32.4…...
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
文章目录 前言一、应用层二.传输层三.网络层:四.数据链路层五.物理层:六.OSI七层模型:1.物理层(Physical Layer):2.数据链路层(Data Link Layer):3.网络层(Ne…...
STM32串口接收不定长数据(空闲中断+DMA)
玩转 STM32 单片机,肯定离不开串口。串口使用一个称为串行通信协议的协议来管理数据传输,该协议在数据传输期间控制数据流,包括数据位数、波特率、校验位和停止位等。由于串口简单易用,在各种产品交互中都有广泛应用。 但在使用串…...
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的整型数组,表示一个选手在n轮内可选择的牌面分数。选手基于规则选牌,请计算所有轮结束后其可以获得的最高总分数。 选择规则如下: 1.在每轮里选手可以选择获取该轮牌面,则其总分数加上该轮牌面分数,为其新的…...
ARM day3
题目:实现3盏灯的流水 代码: .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
本文仅供学习使用 本文参考: B站: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中,可以使用以下命令来查看命令的绝对路径: 1、which 命令名 例如,要查看chronyc命令的绝对路径,可以运行: which chronyc 2、whereis 命令名 例如,要查看chronyc命令…...
Docker build 无法解析域名
### 报错 Docker build 无法解析域名 报错: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,注意JSON的格式 {"dn…...
退稿论文重复率太高会怎么样【保姆教程】
大家好,今天来聊聊退稿论文重复率太高会怎么样,希望能给大家提供一点参考。 以下是针对论文重复率高的情况,提供一些修改建议和技巧: 退稿论文重复率太高会怎么样 在学术出版领域,论文的重复率是衡量其原创性和学术诚…...
Flask 最佳实践(一)
Flask是一个轻量级而强大的Python Web框架,它的简洁性和灵活性使其成为许多开发者的首选。然而,为了确保项目的可维护性和可扩展性,我们需要遵循一些最佳实践。本文将探讨Flask中一些关键的最佳实践。 1. 项目结构 构建一个清晰的项目结构是…...
直流电和交流电
直流电(Direct Current,简称DC)和交流电(Alternating Current,简称AC)是电流的两种基本形式。 1. 直流电 直流电是指电流方向始终保持不变的电流。在直流电中,电子只能沿着一个方向移动。直流电…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
