【小趴菜STM32开发笔记】---- 01输入输出端口GPIO
目录
1 GPIO概述
2 GPIO的特性
3 两个重要概念
3.1 端口(PORT):
3.2 引脚(PIN):
4 电路基本结构
4.1 端口寄存器组
4.2 输入驱动器
4.3 输出驱动器
4.4 引脚电路
4.4.1保护二极管
4.4.2 上拉/下拉电阻
5 工作模式
5.1 输入模式
5.2 输出模式
5.3 模拟模式:
5.4 复用模式:
6 寄存器介绍
6.1 基于寄存器开发的特点
6.2 GPIO相关寄存器
6.2.1模式寄存器(GPIOx_MODER)
6.2.2 输出类型寄存器(GPIOx_OTYPER)
6.2.3 输出速度寄存器(GPIOx_OSPEEDR)
6.2.4 上拉/下拉寄存器(GPIOx_PUPDR)
6.2.5 输入数据寄存器(GPIOx_IDR)
6.2.6 输出数据寄存器(GPIOx_ODR)
6.2.7 置位/复位寄存器(GPIOx_BSRR)
6.3 利用指针访问单个寄存器
6.4 利用寄存器操作点亮LED
1 GPIO概述
GPIO通用输入输出接口(General Purpose Input/Output)的简称,主要用于数字量的输入输出,是微控制器中使用频率最高的外设。包括以下功能:
输出功能:输出高低电平,控制外围设备
输入功能:读取引脚电平状态,获取按键和各类传感器的信息输入
复用功能:作为片内外设的接口
时序模拟:通过改变引脚高低电平模拟时序信号
2 GPIO的特性
多种工作模式:提供四种工作模式
灵活复用:STM32微控制器内部集成了很多外设,这些外设的对外引脚都是与GPIO引脚复用
5V电压容限:大部分引脚具备5V电压的输入,方便与5V供电的外围电路连接
外部中断:每一个GPIO引脚都具备外部中断的能力
3 两个重要概念
3.1 端口(PORT):
一组端口可以看成独立的子模块,由多个寄存器控制,包括多个引脚,如GPIOA。每一组端口可以看成独立的子模块,包括多个引脚,通过多个硬件寄存器(端口寄存器组)来控制引脚的工作模式
3.2 引脚(PIN):
引脚对应微控制器的一个管脚,归属于端口,每组端口最多包含16个引脚;引脚的工作模式由端口寄存器组的对应位控制
4 电路基本结构
4.1 端口寄存器组
用于设置该组端口所含引脚的工作模式,通过设置这三个寄存器的内容,并结合驱动电路,就可以在该端口指定的引脚上输出高低电平或者读取指定引脚的电平状态。
4.2 输入驱动器
输入驱动器的主要电路元件是TTL肖特基触发器(由肖特基管构成的施密特触发器),其原理是当输入电压高于正向阈值电压时,输出高电平;当输入电压低于负向阈值电压时,输出低电平。引脚上的模拟电压经过触发器后,转换为0或1的数字信号,并输入到输入数据寄存器。
4.3 输出驱动器
输出驱动器的主要元件是一对P-MOS管和N-MOS管,由输出数据寄存器控制两个MOS管的导通和截止,根据导通和截止状态,使得GPIO具有“推挽输出”和“开漏输出”的模式。
4.4 引脚电路
4.4.1保护二极管
用于防止外部过高或过低的电压输入芯片而损坏芯片。当引脚电压高于Vdd_pt(5V电压容限)时,上方二极管导通,将输入电压限制在“Vdd_pt + Ud”(Ud表示二极管导通电压);当引脚电压低于Vss时,下方二极管导通,将输入电压限制在“Vss - Ud”。
4.4.2 上拉/下拉电阻
上拉/下拉电阻用于设置引脚的默认电压。上拉使能,引脚默认电压为高电平,下拉使能,引脚默认电压为低电平。
5 工作模式
5.1 输入模式
禁用输出驱动器,打开施密特触发器,引脚电平状态经过施密特触发器转换后,送到输入数据寄存器,以供读取引脚的电平状态。
根据是否开启上拉/下拉电阻,可分为三种输入模式:
浮空输入:不使能上拉/下拉电阻。这种情况下,IO引脚的电平状态不确定,完全由外部输入决定。MCU上电复位后,引脚默认的工作模式就是浮空输入。
上拉输入:使能上拉电阻。引脚外部没有信号输入时,默认为高电平。
下拉输入:使能下拉电阻。引脚外部没有信号输入时,默认为低电平。
5.2 输出模式
启用输出驱动器,打开施密特触发器,可以读取引脚状态。
根据MOS管工作状态,可分为两种输出模式:
推挽输出:P-MOS管和N-MOS管轮流工作,可以输出高低电平。输出数据寄存器中某一位为1时,经过非门,P-MOS导通,N-MOS截止,引脚输出高电平;输出数据寄存器中某一位为0时,经过非门,P-MOS截止,N-MOS导通,此时引脚的输出低电平。
开漏输出:P-MOS一直处于截止状态,只有N-MOS工作,只能输出低电平。输出数据寄存器中某一位为0时,N-MOS导通,此时引脚的输出低电平;但如果输出数据寄存器中某一位为1时,N-MOS也截止,此时引脚的输出电平跟引脚外部的上拉/下拉电阻决定,如果没有上拉/下拉电阻,则引脚处于悬空状态。开漏输出一般用于IIC总线(开漏输出加上拉电阻实现双向数据通信)或者作为电平转换(3.3V与5V之间的转换)
5.3 模拟模式:
模拟模式主要用于片内模拟外设(A/D,D/A,模拟比较器等)的信号通道。
当引脚工作于模拟模式时,施密特触发器被旁路,输出驱动器关闭,上拉/下拉电阻禁能,输入数据寄存器的值恒为0。此时IO引脚的功耗较小,因此在工程应用中,常常将没有用到的IO引脚设置为模拟模式,以减少系统功耗,提高抗干扰能力。
5.4 复用模式:
GPIO的基本功能是数字IO,而STM32微控制器片内集成了大量外设,如TIMER和UART等,这些片内外设的外部引脚可与GPIO引脚复用。
复用模式下,引脚的电平状态不再受端口寄存器的控制,而是由片内外设直接控制。但此时输出驱动器依旧可以启用,可以·配置为推挽输出和开漏输出;施密特触发器依旧可以打开,可以读取引脚的电平状态。
6 寄存器介绍
6.1 基于寄存器开发的特点
- 程序编写直接面向底层的寄存器,与硬件密切相关
- 要求编程者熟悉STM32微控制器的体系架构和工作原理,特别是每个寄存器的功能以及寄存器中每一位的含义
- 程序代码简练,执行效率高
- 开发难度大,开发周期长,后期维护升级以及硬件平台移植的工作量较大
6.2 GPIO相关寄存器
6.2.1模式寄存器(GPIOx_MODER)
31~30 | 29~28 | 27~26 | 25~24 | 23~22 | 21~20 | 19~18 | 17~16 |
MODER 15[1:0] |
MODER 14[1:0] |
MODER 13[1:0] |
MODER 12[1:0] |
MODER 11[1:0] |
MODER 10[1:0] |
MODER 9[1:0] |
MODER 8[1:0] |
15~14 | 13~12 | 11~10 | 9~8 | 7~6 | 5~4 | 3~2 | 1~0 |
MODER 7[1:0] |
MODER 6[1:0] |
MODER 5[1:0] |
MODER 4[1:0] |
MODER 3[1:0] |
MODER 2[1:0] |
MODER 1[1:0] |
MODER 0[1:0] |
模式寄存器一共有32位,每2位一组,对应一个不同的IO口,通过软件写入,配置IO引脚的模式:
00 | 输入模式(复位值) |
01 | 通用输出模式 |
10 | 复用功能模式 |
11 | 模拟模式 |
6.2.2 输出类型寄存器(GPIOx_OTYPER)
31~16 | |||||||||||||||
保留 | |||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
OT15 | OT14 | OT13 | OT12 | OT11 | OT10 | OT9 | OT8 | OT7 | OT6 | OT5 | OT4 | OT3 | OT2 | OT1 | OT0 |
该寄存器用于控制GPIO端口各引脚的输出类型,该寄存器需在引脚设置为输出模式下才有效,其他工作模式无效。该寄存器高16位保留,低16位的每1位对应一个不同的IO口
0 | 推挽输出(复位值) |
1 | 开漏输出 |
6.2.3 输出速度寄存器(GPIOx_OSPEEDR)
31~30 | 29~28 | 27~26 | 25~24 | 23~22 | 21~20 | 19~18 | 17~16 |
OSPEEDR 15[1:0] |
OSPEEDR 14[1:0] |
OSPEEDR 13[1:0] |
OSPEEDR 12[1:0] |
OSPEEDR 11[1:0] |
OSPEEDR 10[1:0] |
OSPEEDR 9[1:0] |
OSPEEDR 8[1:0] |
15~14 | 13~12 | 11~10 | 9~8 | 7~6 | 5~4 | 3~2 | 1~0 |
OSPEEDR 7[1:0] |
OSPEEDR 6[1:0] |
OSPEEDR 5[1:0] |
OSPEEDR 4[1:0] |
OSPEEDR 3[1:0] |
OSPEEDR 2[1:0] |
OSPEEDR 1[1:0] |
OSPEEDR 0[1:0] |
该寄存器用于控制GPIO端口各引脚的输出速度,该寄存器需在引脚设置为输出模式下才有效,其他工作模式无效。
00 | 低速(复位值) |
01 | 中速 |
10 | 高速 |
11 | 超高速 |
【注意】引脚的输出速度跟芯片的最高工作频率有关
6.2.4 上拉/下拉寄存器(GPIOx_PUPDR)
31~30 | 29~28 | 27~26 | 25~24 | 23~22 | 21~20 | 19~18 | 17~16 |
PUPDR 15[1:0] |
PUPDR 14[1:0] |
PUPDR 13[1:0] |
PUPDR 12[1:0] |
PUPDR 11[1:0] |
PUPDR 10[1:0] |
PUPDR 9[1:0] |
PUPDR 8[1:0] |
15~14 | 13~12 | 11~10 | 9~8 | 7~6 | 5~4 | 3~2 | 1~0 |
PUPDR 7[1:0] |
PUPDR 6[1:0] |
PUPDR 5[1:0] |
PUPDR 4[1:0] |
PUPDR 3[1:0] |
PUPDR 2[1:0] |
PUPDR 1[1:0] |
PUPDR 0[1:0] |
该寄存器用于使能GPIO端口各引脚的上拉/下拉电阻,可用于输入模式和输出模式
00 | 不上拉也不下拉(复位值) |
01 | 上拉 |
10 | 下拉 |
11 | 保留 |
6.2.5 输入数据寄存器(GPIOx_IDR)
31~16 | ||||||||||||||||
保留 | ||||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
IDR15 | IDR14 | IDR13 | IDR12 | IDR11 | IDR10 | IDR9 | IDR8 | IDR7 | IDR6 | IDR5 | IDR4 | IDR3 | IDR2 | IDR1 | IDR0 |
该寄存器用于读取GPIO端口各引脚的电平状态,可用于输入和输出模式
0 | 对应引脚输入低电平 |
1 | 对应引脚输入高电平 |
【注意】输入数据寄存器是只读模式,不能通过软件写入。当引脚设置为输出或复用模式时,也可以通过输入数据寄存器读取引脚电平状态
6.2.6 输出数据寄存器(GPIOx_ODR)
31~16 | ||||||||||||||||||
保留 | ||||||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
ODR15 | ODR14 | ODR13 | ODR12 | ODR11 | ODR10 | ODR9 | ODR8 | ODR7 | ODR6 | ODR5 | ODR4 | ODR3 | ODR2 | ODR1 | ODR0 |
该寄存器用于控制GPIO端口各引脚的输出电平,仅用于输出模式
0 | 对应引脚输出低电平 |
1 | 对应引脚输出高电平 |
6.2.7 置位/复位寄存器(GPIOx_BSRR)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
BR 15 |
BR 14 |
BR 13 |
BR 12 |
BR 11 |
BR 10 |
BR 9 |
BR 8 |
BR 7 |
BR 6 |
BR 5 |
BR 4 |
BR 3 |
BR 2 |
BR 1 |
BR 0 |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
BS 15 |
BS 14 |
BS 13 |
BS 12 |
BS 11 |
BS 10 |
BS 9 |
BS 8 |
BS 7 |
BS 6 |
BS 5 |
BS 4 |
BS 3 |
BS 2 |
BS 1 |
BS 0 |
该寄存器用于置位或复位GPIO端口的各个引脚,功能和输出数据寄存器类似,都可以控制引脚输出高低电平
高16位 | 低16位 | ||
0 | 无效 | 0 | 无效 |
1 | 输出低电平 | 1 | 输出高电平 |
和输出数据寄存器相比,置位复位寄存器有两个优势:
- 置位复位寄存器的操作是原子操作,不会被中断打断
- 在控制多个引脚同时输出时更加方便
6.3 利用指针访问单个寄存器
#define GPIOA_MODER *(volatile unsigned int *)(0x40020000UL) //寄存器映射GPIOA_MODER = 0x00000004; //向GPIOA_MODER写入0x03
unsigned int a; //定义无符号整形变量a
a = GPIOA_MODER; //读取GPIOA_MODER的值并赋值给a
【代码解析】:
- 0x40020000表示GPIOA_MODER的起始地址
- 后缀UL表示无符号长整型(强制类型转换,将signed int 转为 unsigned long)
- 地址前加(unsigned int *)修饰,表示将该地址强制转换为一个指向无符号整形数据的指针,来实现访问0x40020000这个地址时,可以连续访问4字节存储单元
- volatile关键字的作用是避免编译器优化,即每次访问该存储单元时,都要去访问它的原始数据
- 最外面的 * 表示解引用,即访问指针所指向地址的内容
6.4 利用寄存器操作点亮LED
#define GPIOA_MODER *(unsigned int *)(0x40020000UL) //模式寄存器映射
#define GPIOA_ODR *(unsigned int *)(0x40020014UL) //输出数据寄存器映射
#define RCC_AHB1ENR *(unsigned int *)(0x40023830UL) //外设时钟使能寄存器映射unsigned int delay = 1000000; //定义延时大小int main()
{RCC_AHB1ENR |= 1<<0; //开启GPIOA的时钟GPIOA_MODER &= ~(3<<(5*2)); //清除模式寄存器的bit11:bit10为00GPIOA_MODER |= 1<<(5*2); //设置bit11:bit10为01,引脚A5为推挽输出while(1){GPIOA_ODR |= 1<<5; //设置bit5为1,输出高电平delay = 1000000; //重新赋值while(delay--); //延时GPIOA_ODR |= ~(1<<5); //设置bit5为0,输出低电平delay = 1000000; //重新赋值while(delay--); //延时}
}
【LED其他实验可参考:基于STM32G0B1+Cubemx + HAL库的LED实验】
【小趴菜STM32开发笔记】---- 01输入输出端口GPIO相关推荐
- 微信公众号Java开发-笔记01【微信公众号介绍、开发环境搭建】
学习网址:哔哩哔哩网站 微信公众号开发-Java版 微信公众号Java开发-笔记01[微信公众号介绍.开发环境搭建] 微信公众号Java开发-笔记02[] 微信公众号Java开发-笔记03[] 微信公 ...
- Bootstrap响应式Web开发笔记01——基础入门
Bootstrap响应式Web开发笔记01--基础入门 Bootstrap响应式Web开发笔记02--移动端页面布局 Bootstrap响应式Web开发笔记03--Bootstrap栅格系统 Boot ...
- 跟小甲鱼学Web开发笔记07
跟小甲鱼学Web开发笔记07 格式化大作战 加粗效果 strong元素 b元素 斜体效果 em元素 i元素 使用css代替b和i元素 久的不去新的不来 del和ins元素 s元素 u元素 mark元素 ...
- STM32开发笔记77: 内部看门狗长延时的产生
单片机型号:STM32L053R8T6 开发笔记STM32开发笔记45:看门狗驱动程序的移植介绍了看门狗驱动程序的基本设计方法.今天项目中看门狗的延时时间达到10秒,则实际运行效果只有3秒. 以下是看 ...
- J4125小主机部署软路由笔记01
J4125部署软路由笔记01 硬件 软件 硬件 闲鱼淘了一个,幻网J4125,上家配好了8G内存+240G SSD硬盘,4口2.5G网络,2个USB口,到手就可以用了. 软件 软件比较复杂,方案太多了 ...
- 微信小程序实例——天气预报开发笔记(进行中...)
★ 背景 [提示]:正在补充更新中- 首先,附上一张效果图. 之前就有关注过小程序的发展,感觉可以抽一点的时间来学习一下,通过官方文档以及提供的示例 Demo,发现兴趣挺高,不失为一个可以扩展自身技能 ...
- 【unity 保卫星城】--- 开发笔记01(飞机移动)
[unity 保卫星城]--- 开发笔记 一.在UnityHub中创建2D项目,取名Defend_Star_City 二.导入MangerOfManger框架 三.在打包中,切换安卓开发模式 四.创建 ...
- STM32开发笔记之——CMSIS DAP
都说开发stm32都是使用kail iar+jatg/swd的方式,然而arm公司已经开发出了CMSIS DAP的开源下载工具,全称是CoreSight Debug Access Port,网络上有大 ...
- ESP32-IDF开发笔记 | 01 - ESP-IDF开发环境搭建(2023.04.08更新)
更新内容 更新时间 2021.05.01 基于ESP32+IDF 4.4完成初稿 2023.03.12 基于IDF 5.0.1添加VScode IDF扩展安装.配置.使用方法 2023.04.07 增 ...
最新文章
- 超声波测距测速升压可调中周倒车雷达变频器传感器1:10
- React Native 常见问题集合
- kendo-ui学习笔记——题记
- 嵌入式Linux系统编程学习之十二守护进程
- 15-Scala使用Option、Some、None,避免使用null
- java,python,scala发送http请求
- 中国湖北区域汉至现代行政区划GIS数据
- matlab实对称矩阵对角化,第四节 实对称矩阵的对角化
- 计算机科学本科科研经历,秦瑶:一名本科生的科研故事
- mysql报错1194_MYSQL ERROR 1194 (HY000)
- 给图片加水印最简单的方法
- VS2005中UNICODE和ANSI以及MBCS的问题
- 《萌小甜动图字帖》使用简介
- OSChina 周二乱弹 —— 求借妹纸肩膀一用!
- 计算机考研四大名著,2017考研英语翻译每日一句:四大名著
- 计算机科学与技术选修课方向,计算机与科学专业主要的课程和学习方向是什么?...
- 石墨笔记, Onenote 和 Effie 哪个适合 up 主?
- opencv学习笔记十八:模板匹配(cv2.matchTemplate、cv2.minMaxLoc)
- 可截断素数(Truncatable primes)
- 用jar包生成maven依赖