stm32学习:(寄存器2)GPIO总体说明

目录

GPIO的主要特点

GPIO的8种工作模式

GPIO电路结构

GPIO输出模式

输出流程

复用输出模式

GPIO输入模式

输入流程

模拟输入流程

GPIO相关的7个寄存器

GPIOx_CRL

GPIOx_CRH

GPIOx_IDR

GPIOx_ODR

GPIOx_BSRR

GPIOx_BRR

GPIOx_LCKR

 实例   三个灯流水灯

main.c 

Delay.h   

Delay.c   

Driver_LED.h 

Driver_LED.c


STM32有多组GPIO,比如我们使用的芯片:STM32F103ZET6共有7GPIO端口,他们分别是GPIOxxA-G),每组控制16个引脚,共有112GPIO引脚。具体一个其他STM32芯片有多少组GPIO,可以去查看他们的对应的数据手册

每个引脚的电平是0-3.3V,部分引脚最高可以兼容到5V。

GPIO的主要特点

  1. 不同型号,IO口的数量可能不一样
  2. 快速翻转。最快可以达到每2个时钟周期翻转一次
  3. 每个IO都可以作为外部中断
  4. 支持8种工作模式

GPIO的8种工作模式

GPIO端口的每个位(引脚)可以由软件分别配置成8种模式,当然对同一个引脚同一时间只能处于某一种模式中

  1. 输入浮空(Input floating)
  2. 输入上拉(Input pull-up)
  3. 输入下拉(Input-pull-down)
  4. 模拟输入(Analog)
  5. 通用开漏输出(Output open-drain)
  6. 通用推挽式输出(Output push-pull)
  7. 推挽式复用功能(Alternate function push-pull)
  8. 开漏复用功能(Alternate function open-drain)

每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字节被访问

输出模式下可以控制端口输出高电平低电平,用于驱动LED,蜂鸣器等,如果是大功率器件(比如电机),还需要加上驱动器(小电流控制大电流)。

输入模式下可以读取端口的高低电平,用于读取外接按键,外接模拟信号的输入,ADC电压采集,模拟通信协议接受数据等。

GPIO电路结构

GPIO输出模式

输出流程

  1. 输出缓冲器被激活
  2. 推挽模式:输出寄存器上的 1 将激活P-MOS,输出高电平。0 将激活N-MOS,输出低电平。
  3. 开漏模式:PMOS永远关闭。 输出寄存器上的 0 激活N-MOS,而输出寄存器上的1 将端口置于高阻状态,所以外部必须要接上拉电阻。
  4. 施密特触发输入被激活。
  5. 弱上拉和下拉电阻被禁止。
  6. 出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器。
  7. 在开漏模式时,对输入数据寄存器的读访问可得到I/O状态。
  8. 在推挽模式时,对输出数据寄存器的读访问得到最后一次写的值。

复用输出模式

  1. 在开漏或推挽式配置中,输出缓冲器被打开。
  2. 内置外设的信号驱动输出缓冲器(复用功能输出)。
  3. 施密特触发输入被激活。
  4. 弱上拉和下拉电阻被禁止。
  5. 在每个APB2时钟周期,出现在I/O脚上的数据被采样到输入数据寄存器。
  6. 开漏模式时,读输入数据寄存器时可得到I/O口状态。
  7. 在推挽模式时,读输出数据寄存器时可得到最后一次写的值。

GPIO输入模式

输入流程

  1. 2个保护二极管的作用是保护我们的芯片不会由于电压过高或过低而烧毁。
    1. VDD是接电源(3.3V),VSS接地(0V)。如果IO引脚的输入电压高于VDD的值到一定程度,上方保护二极管导通,则引脚电压被拉低到VDD。如果IO引脚的输入电压(负电压)低于VSS到一定程度,则下方保护二极管导通,电压被拉高到VSS
  2. 2个开关控制引脚没有输入的时候是上拉,下拉还是浮空。当上面的开关闭合的时候,输入被拉高到高电平。当下面的开关闭合的时候,输入被拉低到低电平。如果两个都不闭合,输入就是悬空状态。两个同时闭合,就是费电了,不会这么做的
  3. TTL触发器是包含正反馈的比较器电路。可以对信号进行波形整形
  4. 从TTL触发起出来的数据,进入到输入数据寄存器中,我们就可以从中读取数据了

模拟输入流程

当配置为模拟输入时:

  1. 输出部分被禁止
  2. 禁止TTL触发输入,实现了每个模拟I/O引脚上的零消耗。施密特触发输出值被强置为0
  3. 弱上拉和下拉电阻被禁止
  4. 读取输入数据寄存器时数值永远为0

GPIO相关的7个寄存器

每个GPIO端口有7个相关的

  1. 2个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)
  2. 2个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)
  3. 1个32位置位/复位寄存器(GPIOx_BSRR)
  4. 1个16位复位寄存器(GPIOx_BRR)
  5. 1个32位锁定寄存器(GPIOx_LCKR)

GPIOx_CRL

端口配置低寄存器,x可以是A-G

 该寄存器配置的每个GPIO的 0-7 这个8个位,所以叫低寄存器

  • MODE:每个端口有2个MODE位进行控制
    • 00:输入模式(复位后的状态)
    • 01:输出模式,最大速度10MHz
    • 10:输出模式,最大速度2MHz
    • 11:输出模式,最大速度50MHz
  • CNF:每个端口有2个CNF位进行控制
    • 当MODE是00 (输入模式)
      • 00:模拟输入模式
      • 01:浮空输入模式(复位后的状态)
      • 10:上拉/下拉输入模式
      • 11:保留
    • 当MODE>00(输出模式)
      • 00:通用推挽输出模式
      • 01:通用开漏输出模式
      • 10:复用功能推挽输出模式
      • 11:复用功能开漏输出模式

GPIOx_CRH

端口配置高寄存器

该寄存器配置的是每个端口的 8-15引脚,配置方式和低位寄存器完全一样

GPIOx_IDR

端口输入数据寄存器,

 保留位始终读为0。剩下的分别对应每个引脚的输入值

GPIOx_ODR

端口输出数据寄存器

保留位始终读为0。剩下的分别对应每个引脚的输出值 

GPIOx_BSRR

端口位设置/清除寄存器

 高16位是用清除对应的数据输出寄存器的位(0-15)的值:设置为0不影响,设置为1会清除ODR对应的位的值(置为0)

低16位是用设置对应的数据输出寄存器的位(0-15)的值:设置为0不影响,设置为1会设置ODR对应的位的值(置为1)

GPIOx_BRR

端口位清除寄存器

这个寄存器具有了GPIOx_BSRR一半的功能:清除

GPIOx_LCKR

端口配置锁定寄存器

该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置

每个锁定位锁定控制寄存器(CRL,CRH)中相应的4个位(CNF2位和MODE2位)。

第16位用来激活锁定寄存器,必须按照规定的时序来操作才行: 写1 -> 写0 -> 写1 -> 读0 -> 读1

对0-15位:

  • 0:不锁定对应端口的配置
  • 1:锁定对应端口的配置 

 实例   三个灯流水灯

一共有好几个文件,

main.c 

#include "Driver_LED.h"
#include "Delay.h"int main()
{uint32_t leds[] = {LED_1, LED_2, LED_3};/* 1. 初始化LED */Driver_LED_Init();Drviver_LED_OffAll(leds, 3);while (1){for (uint8_t i = 0; i < 3; i++){Drviver_LED_OffAll(leds, 3);Drviver_LED_On(leds[i]);Delay_ms(500);}Drviver_LED_OffAll(leds, 3);Drviver_LED_On(leds[1]);Delay_ms(500);}
}

Delay.h   

#ifndef __delay_h
#define __delay_h
#include "stm32f10x.h"                  // Device headervoid Delay_us(uint16_t us);
void Delay_ms(uint16_t ms);
void Delay_s(uint16_t s);#endif

Delay.c   

#include "delay.h" // Device headervoid Delay_us(uint16_t us)
{/* 定时器重装值 */SysTick->LOAD = 72 * us;/* 清除当前计数值 */SysTick->VAL = 0;/*设置内部时钟源(2位->1),不需要中断(1位->0),并启动定时器(0位->1)*/SysTick->CTRL = 0x5;/*等待计数到0, 如果计数到0则16位会置为1*/while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG));/* 关闭定时器 */SysTick->CTRL &= ~SysTick_CTRL_ENABLE; 
}void Delay_ms(uint16_t ms)
{while (ms--){Delay_us(1000);}
}void Delay_s(uint16_t s)
{while (s--){Delay_ms(1000);}
}

Driver_LED.h 

#ifndef __DRIVER_LED_H
#define __DRIVER_LED_H#include "stm32f10x.h"#define LED_1 GPIO_ODR_ODR0
#define LED_2 GPIO_ODR_ODR1
#define LED_3 GPIO_ODR_ODR8void Driver_LED_Init(void);void Drviver_LED_On(uint32_t led);void Drviver_LED_Off(uint32_t led);void Drviver_LED_Toggle(uint32_t led);void Drviver_LED_OnAll(uint32_t leds[], uint8_t size);void Drviver_LED_OffAll(uint32_t leds[], uint8_t size);#endif

Driver_LED.c

#include "Driver_LED.h"/*** @description: 对LED进行初始化*/
void Driver_LED_Init(void)
{/* 1. 打开GPIOA的时钟 */RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;/* 2. 给用到的端口的所有 PIN (PA0 PA1 PA8) 设置工作模式: 通用推挽输出 MODE:11  CNF:00 */GPIOA->CRL |= (GPIO_CRL_MODE0 | GPIO_CRL_MODE1);GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1);GPIOA->CRH |= GPIO_CRH_MODE8;GPIOA->CRH &= ~GPIO_CRH_CNF8;/* 3. 关闭所有灯  */Drviver_LED_Off(LED_1);Drviver_LED_Off(LED_2);Drviver_LED_Off(LED_3);
}/*** @description: 点亮指定的LED* @param {uint32_t} led 要点亮的LED*/
void Drviver_LED_On(uint32_t led)
{GPIOA->ODR &= ~led;
}/*** @description: 关闭指定的LED* @param {uint32_t} led 要关闭的LED*/
void Drviver_LED_Off(uint32_t led)
{GPIOA->ODR |= led;
}/*** @description: 翻转LED的状态* @param {uint32_t} led 要翻转的LED*/
void Drviver_LED_Toggle(uint32_t led)
{/* 1. 读取引脚的电平,如果是1(目前是关闭), 打开, 否则就关闭 */if ((GPIOA->IDR & led) == 0){Drviver_LED_Off(led);}else{Drviver_LED_On(led);}
}/*** @description: 打开数组中所有的灯* @param {uint32_t} leds 所有灯* @param {uint8_t} size 灯的个数*/
void Drviver_LED_OnAll(uint32_t leds[], uint8_t size)
{for (uint8_t i = 0; i < size; i++){Drviver_LED_On(leds[i]);}
}/*** @description: 关闭数组中所有的灯* @param {uint32_t} leds 所有灯* @param {uint8_t} size 灯的个数*/
void Drviver_LED_OffAll(uint32_t leds[], uint8_t size)
{for (uint8_t i = 0; i < size; i++){Drviver_LED_Off(leds[i]);}
}

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

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

相关文章

C语言基础 9. 指针

C语言基础 9. 指针 文章目录 C语言基础 9. 指针9.1. &9.2. 指针9.3. 指针的使用9.4. 指针与数组9.5. 指针与const9.6. 指针运算9.7. 动态内存分配 9.1. & 运算符&: scanf(“%d”, &i);里的& 获得变量的地址, 它的操作数必须是变量 int i;printf(“%x”, &…

【SpringBoot Web开发之静态资源访问】笔记

详细内容见官方文档&#xff1a;Static Content SpringBoot Web开发之静态资源访问 1.准备工作&#xff1a;创建WebDemo2.静态资源目录2.1官网原文2.2静态资源目录第一步&#xff1a;依照上面2.1官网原文中创建如下目录第二步&#xff1a;复制粘贴图片到静态资源目录中第三步…

MySQL:JOIN 多表查询

多表查询 在关系型数据库中&#xff0c;表与表之间是有联系的&#xff0c;它们通过 外键 联系在一起&#xff0c;所以在实际应用中&#xff0c;经常使用多表查询。多表查询就是同时查询两个或两个以上的表。 MySQL多表查询是数据库操作中非常重要的一部分&#xff0c;它允许你…

【深入理解SpringCloud微服务】浅析微服务注册中心Eureka与nacos,手写实现一个微服务注册中心

【深入理解SpringCloud微服务】浅析微服务注册中心Eureka与nacos&#xff0c;手写实现一个微服务注册中心 注册中心手写实现一个注册中心服务端设计客户端设计 注册中心 注册中心是微服务体系里面非常重要的一个核心组件&#xff0c;它最重要的作用就是实现服务注册与发现。 …

【MyBatisPlus】快速掌握MP插件使用方法

一、MyBatis-Plus简介 1.1 简介 1.2 特性 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑损耗小&#xff1a;启动即会自动注入基本 CURD&#xff0c;性能基本无损耗&#xff0c;直接面向对象操作强大的 CRUD 操作&#x…

【ACM独立出版|EI检索稳定】2024年智能感知与模式识别国际学术会议(ISPC 2024,9月6日-8)

2024年智能感知与模式识别国际学术会议 (ISPC 2024)将于2024年9月6日-8日于中国青岛召开。 会议将围绕智能感知与模式识别等领域中的最新研究成果&#xff0c;为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师等提供一个分享专业经验&#xff0c;扩大…

初谈Linux信号-=-信号的产生

文章目录 概述从生活角度理解信号Linux中信号信号常见的处理方式理解信号的发送与保存 信号的产生core、term区别 概述 从生活角度理解信号 你在网上买了很多件商品&#xff0c;再等待不同商品快递的到来。但即便快递没有到来&#xff0c;你也知道快递来临时&#xff0c; 你该…

机械臂泡水维修|机器人雨后进水维修措施

如果机器人不慎被水淹&#xff0c;别慌&#xff01;我们为你准备了一份紧急的机械臂泡水维修抢修指南&#xff0c;帮助你解决这个问题。 【机器人浸水被淹后紧急维修抢修&#xff5c;如何处理&#xff1f;】 机械臂被淹进水后维修处理方式 1. 机械手淹水后断电断网 首先&am…

spring整合mybatis,junit纯注解开发(包括连接druid报错的所有解决方法)

目录 Spring整合mybatis开发步骤 第一步&#xff1a;创建我们的数据表 第二步&#xff1a;编写对应的实体类 第三步&#xff1a;在pom.xml中导入我们所需要的坐标 spring所依赖的坐标 mybatis所依赖的坐标 druid数据源坐标 数据库驱动依赖 第四步&#xff1a;编写SpringC…

linux在ssh的时候询问,yes or no 如何关闭

解决&#xff1a; 在~/.ssh/config文件中添加如下配置项&#xff1a; Host *StrictHostKeyChecking no

数据可视化配色新工具,颜色盘多达2500+类

好看的配色,不仅能让图表突出主要信息,更能吸引读者,之前分享过很多配色工具,例如, 👉可视化配色工具:颜色盘多达3000+类,数万种颜色! 本次再分享一个配色工具pypalettes,颜色盘多达2500+类。 安装pypalettes pip install pypalettes pypalettes使用 第1步,挑选…

【LeetCode】分隔链表

目录 一、题目二、解法完整代码 一、题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&a…

JVM中的GC流程与对象晋升机制

JVM中的GC流程与对象晋升机制 1、JVM堆内存结构2、Minor GC流程3、Full GC流程4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;垃圾回收&#xff08;GC&#xff09;是自动管…

VTK源码分析:Type System

作为一款开源跨平台的数据可视化代码库&#xff0c;VTK以其清晰的流水线工作方式、丰富的后处理算法、异种渲染/交互方式&#xff0c;而被众多CAx软件选作后处理实施方案。而异种渲染/交互方式的实现&#xff0c;主要是倚重于VTK的类型系统&#xff0c;因此&#xff0c;有必要对…

最新 Docker 下载镜像超时解决方案:Docker proxy

现在Docker换源也下载失败太常见了&#xff0c;至于原因&#xff0c;大家懂得都懂。本文提供一种简洁的方案&#xff0c; 利用 Docker 的http-proxy&#xff0c;代理至本机的 proxy。 文章目录 前言Docker proxy 前言 这里默认你会安装 clash&#xff0c;然后有配置和数据库。…

排序算法

排序算法 内部排序&#xff1a;指将需要处理的所有数据都加载到内部存储器中进行排序 外部排序&#xff1a;数据量过大&#xff0c;无法全部加载到内存中&#xff0c;需要借助外部存储进行排序 算法的时间复杂度 一个算法花费的时间与算法中语句的执行次数成正比&#xff0c;…

Unity XR Interaction Toolkit(VR、AR交互工具包)记录安装到开发的流程,以及遇到的常见问题(一)!

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、XR Interaction Toolkit是什么&#xff1f;二、跨平台交互三、 AR 功能四、XR Interaction Toolkit的特点五、XR Interaction Toolkit 示例总结 前言 随着VR行业的发展&#…

一文搞懂 Java 基础:新手入门必备

目录 &#x1f4dd; Java基础Java起源第一个Java程序基础语法Java标识符Java变量Java注释Java数据类型Java运算符Java流程控制语句 &#x1f4dd; Java基础 Java起源 Java programming language具有大部分编程语言所共有的一些特征&#xff0c;被特意设计用于互联网的分布式环…

《算法笔记》总结No.10——链表

从第10期破例插叙一期单链表的实现&#xff0c;这个东东相当重要&#xff01;考研的同学也可以看&#xff1a;相较于王道考研的伪码不太相同&#xff0c;专注于可以运行。如果是笔试中的伪码&#xff0c;意思正确即可~ 注&#xff1a;博主之前写过一个版本的顺序表和单链表的C实…

Jolt路线图

1. 引言 a16z crypto团队2024年7月更新了其Jolt路线图&#xff1a; 主要分为3大维度&#xff1a; 1&#xff09;链上验证维度&#xff1a; 1.1&#xff09;Zeromorph&#xff1a;见Aztec Labs团队2023年论文 Zeromorph: Zero-Knowledge Multilinear-Evaluation Proofs from…