STM32F4系列单片机GPIO概述和寄存器分析

第2章 STM32-GPIO口

2.1 GPIO口概述

通用输入/输出口

2.1.1 GPIO口作用

GPIO是单片机与外界进行数据交流的窗口。

2.1.2 STM32的GPIO口

在51单片机中,IO口,以数字进行分组(P0~P3),每一组里面又有8个IO口。

在STM32里面,GPIO口,以英文字母进行分组,针对M4系列最多可以分为AI组,而在我们现在使用的stm32f407zgt6这款芯片一共分成AG组。每一组里面有16个IO口(以0~15进行编号),所以我们这款芯片一共有112个GPIO口。

并不是所以的管脚都是GPIO口

每一个GPIO口都是多功能的,在使用之前需要先配置好特定的一个功能,需要用什么功能就要配置成什么功能。

对GPIO的配置就是学习如何使用GPIO口。

对GPIO口操作其实就是操作GPIO对应的寄存器。

寄存器其实就是一段内存空间。芯片内部有很多模块,系统会给每一个模块都分配一段特定的内存空间,这些内存空间的地址其实就是这些模块的寄存器地址。每个寄存器都有自己特定的一些功能,我们往寄存器里面读写的数据也都是有一定意义的,不是随意的。如果我们想要操作一个模块做某些事情,就需要找到这个模块对应有这个功能的寄存器,往这个寄存器里面写入特定的指令数据,系统就会根据你的操作对这个模块进行控制。

img

补充:

变量:声明变量其实就是在内存中申请了一段内存空间,我们可以在这个内存空间进行读写操作。这个内存空间的地址是随机。

寄存器:寄存器其实也是一段内存空间,同样可以往里面进行读写操作,但是寄存器的地址是固定的,是已知的,是芯片厂家出厂时就已经固化了,不可更改的。

img

从上图可以知道GPIO模块寄存器边界地址和所在的总线(AHB1)

img

相邻两组GPIO之间的偏移量是0x0400,换句话说每组GPIO的空间大小为1024字节。

img

总结:

相邻GPIO组之间的偏移量为1K字节,每一组GPIO相邻寄存器之间的偏移量为0x04.

2.1.3 STM32的GPIO口特征

每个通用 I/O 端口包括 4 个 32 位配置寄存器(GPIOx_MODER、 GPIOx_OTYPER、GPIOx_OSPEEDR 和 GPIOx_PUPDR)、 2 个 32 位数据寄存器(GPIOx_IDR 和GPIOx_ODR)、 1 个 32 位置位/复位寄存器 (GPIOx_BSRR)、 1 个 32 位锁定寄存器(GPIOx_LCKR) 和 2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)。

● 受控 I/O 多达 16 个
● 输出状态:推挽或开漏 + 上拉/下拉
● 从输出数据寄存器 (GPIOx_ODR) 或外设(复用功能输出)输出数据
● 可为每个 I/O 选择不同的速度
● 输入状态:浮空、上拉/下拉、模拟
● 将数据输入到输入数据寄存器 (GPIOx_IDR) 或外设(复用功能输入)
● 置位和复位寄存器 (GPIOx_BSRR),对 GPIOx_ODR 具有按位写权限
● 锁定机制 (GPIOx_LCKR),可冻结 I/O 配置
● 模拟功能
● 复用功能输入/输出选择寄存器(一个 I/O 最多可具有 16 个复用功能)
● 快速翻转,每次翻转最快只需要两个时钟周期
● 引脚复用非常灵活,允许将 I/O 引脚用作 GPIO 或多种外设功能中的一种

2.1.4 STM32的GPIO功能

根据数据手册中列出的每个 I/O 端口的特性,可通过软件将通用 I/O (GPIO) 端口的各个端口
位分别配置为多种模式:
● 输入浮空
● 输入上拉
● 输入下拉
● 模拟功能----用在模数转换/数模转换上
● 具有上拉或下拉功能的开漏输出
● 具有上拉或下拉功能的推挽输出
● 具有上拉或下拉功能的复用功能推挽
● 具有上拉或下拉功能的复用功能开漏
每个 I/O 端口位均可自由编程,但 I/O 端口寄存器必须按 32 位字、半字或字节进行访问。
GPIOx_BSRR 寄存器旨在实现对 GPIO ODR 寄存器进行原子读取/修改访问。这样便可确保
在读取和修改访问之间发生中断请求也不会有问题。

2.2 STM32的GPIO口框架(重点)

img

输入电路和输出电路是独立的。

2.2.1 输出配置框架分析

对 I/O 端口进行编程作为输出时:
● 输出缓冲器被打开:
— 开漏模式:输出寄存器中的“0”可激活 N-MOS,而输出寄存器中的“1”会使端
口保持高组态 (Hi-Z)(P-MOS 始终不激活)。
— 推挽模式:输出寄存器中的“0”可激活 N-MOS,而输出寄存器中的“1”可激活
P-MOS。
● 施密特触发器输入被打开
● 根据 GPIOx_PUPDR 寄存器中的值决定是否打开弱上拉电阻和下拉电阻
● 输入数据寄存器每隔 1 个 AHB1 时钟周期对 I/O 引脚上的数据进行一次采样
● 对输入数据寄存器的读访问可获取 I/O 状态
● 对输出数据寄存器的读访问可获取最后的写入值

img

在配置成输出模式时,输入功能并没有被关闭。

推挽输出:当配置成推挽模式时,P-MOS和N-MOS均可以工作(都被打开)

当要输出高电平‘1’时,P-MOS导通,N-MOS不导通,VDD电源正极(高电平)连接到IO引脚

当要输出低电平‘0’时,P-MOS不导通,N-MOS导通,VSS电源负极(低电平)连接到IO引脚

推挽输出即可以输出高电平也可以输出低电平

开漏输出:当配置成开漏模式时,P-MOS被关闭(高阻态),N-MOS被打开

当要输出高电平‘1’时,P-MOS不导通,N-MOS不导通,不能把高电平从输出驱动器输出出去,IO引脚的电平值取决外界环境。

当要输出低电平‘0’时,P-MOS不导通,N-MOS导通,VSS电源负极(低电平)连接到IO引脚

开漏输出只具有输出低电平的能力,不具有输出高电平的能力。

如果仍然想输出高电平‘1’,那么需要在外部电路中接一个上拉电阻

上拉电阻:电阻的一端接着电源正极,在IO口没有电流流过时,保证电阻另外一端有一个稳定高电平

下拉电阻:电阻的一端接着电源负极(GND),在IO口没有电流流过时,保证电阻另外一端有一个稳定低电平

芯片内部上拉电阻和下拉电阻都是弱上拉和弱下拉,驱动能力比较弱

2.2.2 输入配置框架分析

对 I/O 端口进行编程作为输入时:
● 输出缓冲器被关闭
● 施密特触发器输入被打开
● 根据 GPIOx_PUPDR 寄存器中的值决定是否打开上拉和下拉电阻
● 输入数据寄存器每隔 1 个 AHB1 时钟周期对 I/O 引脚上的数据进行一次采样
● 对输入数据寄存器的读访问可获取 I/O 状态

img

变换一下如下图:

img

img

这种情况下,配置成输入浮空(不上拉也不下拉)

img

这种情况下可以配置成输入上拉

img

这种情况下可以配置成输入下拉

2.2.3 模拟功能框架分析

对 I/O 端口进行编程作为模拟配置时:
● 输出缓冲器被禁止。
● 施密特触发器输入停用, I/O 引脚的每个模拟输入的功耗变为零。施密特触发器的输出被
强制处理为恒定值 (0)。
● 弱上拉和下拉电阻被关闭。
● 对输入数据寄存器的读访问值为“0”。

img

img

2.2.4 复用功能框架分析

对 I/O 端口进行编程作为复用功能时:
● 可将输出缓冲器配置为开漏或推挽
● 输出缓冲器由来自外设的信号驱动(发送器使能和数据)
● 施密特触发器输入被打开
● 根据 GPIOx_PUPDR 寄存器中的值决定是否打开弱上拉电阻和下拉电阻
● 输入数据寄存器每隔 1 个 AHB1 时钟周期对 I/O 引脚上的数据进行一次采样
● 对输入数据寄存器的读访问可获取 I/O 状态

img

img

2.3 STM32的GPIO口相关寄存器

img

img

2.3.1 GPIO 端口模式寄存器 (GPIOx_MODER) (x = A…I)

偏移地址: 0x00
复位值:(默认值)
● 0xA800 0000(端口 A)
● 0x0000 0280(端口 B)
● 0x0000 0000(其它端口)

img

位 2y:2y+1 MODERy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
这些位通过软件写入,用于配置 I/O 方向模式。
00:输入(复位状态)
01:通用输出模式
10:复用功能模式
11:模拟模式

2.3.2 GPIO 端口输出类型寄存器 (GPIOx_OTYPER) (x = A…I)

偏移地址: 0x04
复位值: 0x0000 0000

img

位 31:16 保留,必须保持复位值。
位 15:0 OTy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
这些位通过软件写入,用于配置 I/O 端口的输出类型。
0:输出推挽(复位状态)
1:输出开漏

2.3.3 GPIO 端口输出速度寄存器 (GPIOx_OSPEEDR) (x = A…I/)

偏移地址: 0x08
复位值:
● 0x0000 00C0(端口 B)
● 0x0000 0000(其它端口)

img

位 2y:2y+1 OSPEEDRy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
这些位通过软件写入,用于配置 I/O 输出速度。
00: 2 MHz(低速)
01: 25 MHz(中速)
10: 50 MHz(快速)
11: 30 pF 时为 100 MHz(高速)(15 pF 时为 80 MHz 输出(最大速度))

2.3.4 GPIO 端口上拉/下拉寄存器 (GPIOx_PUPDR) (x = A…I/)

偏移地址: 0x0C
复位值:
● 0x6400 0000(端口 A)
● 0x0000 0100(端口 B)
● 0x0000 0000(其它端口)

img

位 2y:2y+1 PUPDRy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
这些位通过软件写入,用于配置 I/O 上拉或下拉。
00:无上拉或下拉(浮空)
01:上拉
10:下拉
11:保留

2.3.5 GPIO 端口输入数据寄存器 (GPIOx_IDR) (x = A…I)

偏移地址: 0x10
复位值: 0x0000 XXXX(其中 X 表示未定义)

img

位 31:16 保留,必须保持复位值。
位 15:0 IDRy[15:0]: 端口输入数据 (Port input data) (y = 0…15)
这些位为只读形式,只能在字模式下访问。它们包含相应 I/O 端口的输入值。

2.3.6 GPIO 端口输出数据寄存器 (GPIOx_ODR) (x = A…I)

偏移地址: 0x14
复位值: 0x0000 0000

img

位 31:16 保留,必须保持复位值。
位 15:0 ODRy[15:0]: 端口输出数据 (Port output data) (y = 0…15)
这些位可通过软件读取和写入。
注意: 对于原子置位/复位,通过写入 GPIOx_BSRR 寄存器,可分别对 ODR 位进行置位和复
位 (x = A…I/)。

2.4 寄存器访问方法

操作GPIOA_MODE,写入data值

第一种:

*(unsigned int *)0x4002 0000=data;

第二种:

#define GPIOA_MODE *(unsigned int *)0x4002 0000

GPIOA_MODE=data;

第三种:

#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)#define GPIOI ((GPIO_TypeDef ) GPIOI_BASE) typedef struct{ __IO uint32_t MODER; /!< GPIO port mode register, Address offset: 0x00 / __IO uint32_t OTYPER; /!< GPIO port output type register, Address offset: 0x04 / __IO uint32_t OSPEEDR; /!< GPIO port output speed register, Address offset: 0x08 / __IO uint32_t PUPDR; /!< GPIO port pull-up/pull-down register, Address offset: 0x0C / __IO uint32_t IDR; /!< GPIO port input data register, Address offset: 0x10 / __IO uint32_t ODR; /!< GPIO port output data register, Address offset: 0x14 / __IO uint16_t BSRRL; /!< GPIO port bit set/reset low register, Address offset: 0x18 / __IO uint16_t BSRRH; /!< GPIO port bit set/reset high register, Address offset: 0x1A / __IO uint32_t LCKR; /!< GPIO port configuration lock register, Address offset: 0x1C / __IO uint32_t AFR[2]; /!< GPIO alternate function registers, Address offset: 0x20-0x24 /} GPIO_TypeDef; 说明:GPIO_TypeDef :结构体 GPIO_TypeDef:结构体指针 #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000)#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400)#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800)#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00)#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000)#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400)#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00)#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000)//---------------------------------------------------------------------------------------#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)//---------------------------------------------------------------------------------------#define PERIPH_BASE ((uint32_t)0x40000000) 分析:#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) ((PERIPH_BASE + 0x00020000)+0x0000) ((((uint32_t)0x40000000)+ 0x00020000)+0x0000) ((uint32_t)0x40020000) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOA ((GPIO_TypeDef *) (uint32_t)0x40020000)GPIOA—结构体常量指针 操作寄存器方法:GPIOA->MODE=data;

2.5 STM32的GPIO口相关实验

2.5.1 通用输出功能实验

通过GPIO口点亮LED灯

LED其实是发光二极管,当给阳极高电平,给阴极低电平,会让二极管正向导通,LED点亮

2.5.1.1 硬件设计

img

img

img

2.5.1.2 软件设计

点亮LED1,把PF6配置成普通功能推挽输出

配置流程:

\1. 配置模式寄存器(把GPIOF的MODER寄存器的第13和12位分配成01)—输出模式

\2. 配置输出类型寄存器(把GPIOF的OTYPER寄存器的第6位分配成0)—输出推挽

\3. 配置输出速度寄存器(把GPIOF的OSPEEDR寄存器的第13和12位分配成00)–低速2Mhz

\4. 配置上/下拉寄存器(把GPIOF的PUPDR寄存器的第13和12位分配成00)–浮空

点亮LED1----往GPIOF的ODR寄存器的第6位写入0

熄灭LED1----往GPIOF的ODR寄存器的第6位写入1

操作寄存器的原则:操作你要操作的相关位,而不能影响到其他位的值。

2 软件设计

点亮LED1,把PF6配置成普通功能推挽输出

配置流程:

\1. 配置模式寄存器(把GPIOF的MODER寄存器的第13和12位分配成01)—输出模式

\2. 配置输出类型寄存器(把GPIOF的OTYPER寄存器的第6位分配成0)—输出推挽

\3. 配置输出速度寄存器(把GPIOF的OSPEEDR寄存器的第13和12位分配成00)–低速2Mhz

\4. 配置上/下拉寄存器(把GPIOF的PUPDR寄存器的第13和12位分配成00)–浮空

点亮LED1----往GPIOF的ODR寄存器的第6位写入0

熄灭LED1----往GPIOF的ODR寄存器的第6位写入1

操作寄存器的原则:操作你要操作的相关位,而不能影响到其他位的值。

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

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

相关文章

AcWing 717. 简单斐波那契

原题链接 题目 以下数列 0 1 1 2 3 5 8 13 21 … 被称为斐波纳契数列。 这个数列从第 3 项开始&#xff0c;每一项都等于前两项之和。 输入一个整数 N &#xff0c;请你输出这个序列的前 N 项。 输入格式 一个整数 N 。 输出格式 在一行中输出斐波那契数列的前 N 项&…

共享内存和信号量的配合机制

进程之间共享内存的机制&#xff0c;有了这个机制&#xff0c;两个进程可以像访问自己内存中的变量一样&#xff0c;访问共享内存的变量。但是同时问题也来了&#xff0c;当两个进程共享内存了&#xff0c;就会存在同时读写的问题&#xff0c;就需要对于共享的内存进行保护&…

快速集成Skywalking 9(Windows系统、JavaAgent、Logback)

目录 一、Skywalking简介二、下载Skywalking服务端三、安装Skywalking服务端3.1 解压安装包3.2 启动Skywalking 四、关于Skywalking服务端更多配置五、Java应用集成skywalking-agent.jar5.1 下载SkyWalking Java Agent5.2 集成JavaAgent5.3 Logback集成Skywalking5.4 集成效果 …

数据库的三范式(Normalization)

数据库的三范式&#xff08;Normalization&#xff09;是关系数据库设计中的基本理论原则&#xff0c;旨在减少数据冗余和提高数据库的数据组织结构。三范式通过将数据分解为更小的表&#xff0c;并通过关系建立连接&#xff0c;使得数据库设计更加灵活、规范和容易维护。在这篇…

C语言——函数的嵌套调用

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>void new_line() {printf("Hello\n"); }void three_line() {int i0;for(i0;i<3;i){new_line();} }int main() {three_line();return 0; }

FPGA实现双向电平转换

网上搜了一圈&#xff0c;好像没看到的类似的中文资料&#xff0c;不过MicroSemi有个文档AC349上给出了完整的解决方案&#xff0c;还有参考代码。 话不多说&#xff0c;看图&#xff1a; 欲知详情的朋友&#xff0c;请参考 AC349

你听说过“消费多少返利多少的”模式吗?

今天分享一个新的销售套路&#xff0c;看懂套路奋斗节约3年&#xff0c;你听说过“消费多少返利多少的”模式吗&#xff1f; 消费报销模式就是消费者在平台的消费&#xff0c;根据贡献度和活跃度平台去把之前消费的模式&#xff0c;给你返本了甚至还额外给你补贴奖励&#xff…

二阶段提交

二阶段提交 二阶段提交&#xff08;英语&#xff1a;Two-phase Commit&#xff09;是指&#xff0c;为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm)。 二阶段过程 在两阶段提交过程中&#xff0c;主要分为了两种角色协调者&…

【Java】异常处理(一)

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;Java ⭐每日一句&#xff1a;什么都不做&#xff0c;才会来不及 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 &#x1f4cb;前…

影刀sqlite的插入方法

影刀sqlite的插入方法 变量外面不用加‘’

Linux程序设计(上)

系列文章目录 文章目录 系列文章目录前言一、unix, linux, GNU, POSIXLinux程序 二、shellshell语法1.变量2.语句 函数命令命令的执行dialog工具-- 三、文件操作1. Linux 文件结构2. 系统调用和设备驱动程序3. 库函数4. 底层文件访问5. 标准I/O库6.格式化输入输出7. 文件和目录…

Git 基本操作

目录 创建仓库命令 git init git clone 提交与修改 git add git status git diff git commit git reset git rm git mv git checkout git switch git restore 提交日志 git log git blame 远程操作 git remote git fetch git pull git push Git 的工作就…

URAT串口通信协议

UART是异步串行全双工总线&#xff0c;面向设备和设备之间的连接 配置相关内容 1、串口为串行通讯方式&#xff0c;代表一个时钟周期&#xff0c;只可以收发一位数据 2、115200代表什么&#xff0c;以及115200单位 单位&#xff1a;bps(比特率、二进制/秒) 115200代表&#…

MySQL 的执行原理(四)

5.5. MySQL 的查询重写规则 对于一些执行起来十分耗费性能的语句&#xff0c;MySQL 还是依据一些规则&#xff0c;竭尽全力的把这个很糟糕的语句转换成某种可以比较高效执行的形式&#xff0c;这个过程也可以 被称作查询重写。 5.5.1. 条件化简 我们编写的查询语句的搜索条件…

2023下半年软件设计师考试知识点大全思维导图

软件设计师考试知识点大全思维导图 2023年下半年第一次机考 复习资料 以上是我在学习过程中根据自己的知识结构的特点及刷到的考题 做的导图&#xff0c;有需要的可以留言发原版的 mmap格式文件 方便自己拓展. 软考资料 这是网上找的资料 汇总免费放在这里 吧![ 链接&#x…

【封装UI组件库系列】搭建项目及准备工作

封装UI组件库系列第一篇搭建项目 前言 &#x1f31f;搭建项目 创建工程 基本结构 1.创建8个组件展示页面 ​ 2.配置路由文件router/index.js 3.页面布局 &#x1f31f;总结 前言 在前端开发中&#xff0c;大家可能已经用过各种各样的UI组件库了&#xff0c;现在市面上热…

Android WMS——输入系统管理(十七)

一、简介 1、工作原理 输入子系统从驱动文件中读取事件后,再封装提交给 IMS,IMS 再发送给 WMS 进行处理。 Android 输入系统的工作原理概括来说,内核将原始事件写入到设备节点中,InputReader 不断地通过 EventHub 将原始事件取出来并翻译加工成 Android 输入事件,…

MySQL为什么选择了B+树

首先MySQL的数据**&#xff08;索引记录&#xff09;**是存在磁盘里的&#xff0c;磁盘读取非常慢&#xff0c;所以要尽可能减少磁盘操作&#xff0c;因此我们需要更好的利用索引。 首先索引按顺序排列了数据&#xff0c;那么很显然最好的查找方式是二分查找&#xff0c;数组自…

Web3 分布式存储 IPFS(Web3项目一实战之四)

IPFS是一种分布式文件存储协议,它允许世界各地的计算机存储和服务文件作为一个巨大的对等网络的一部分来存储和服务文件。 世界上任何地方的任何计算机都可以下载IPFS软件并开始托管和提供文件。 如果有人在自己的计算机上运行IPFS,并将文件上传到IPFS网络,那么世界上其他任…

OpenVPN Connect使用连接公网VPN服务器实现内网穿透

安装并运行OpenVPN Connect 点击AGREE 添加配置.OVPN文件 点击连接 连接成功 两个内网主机通过公网VPN穿透