GPIO使用教程(学习笔记)

2023-11-06

前言

本文主要讲解如何驱动GPIO外设的相应寄存器搭建GPIO的工作环境,牵及的各种代码本人都会逐条进行讲解。主控芯片采用STM32F103C8T6,外设采用普通的LED发光二极管。驱动LED发光二极管显示GPIO的工作状态。因本人的知识有限,文章中难免有错误,还请读者们谅解。在此本人非常希望读者能反馈错误,以便日后写出的文章更好。

文中出现的术语含义如下:
(1)外设:该术语如果出现在芯片外设中表示寄存器组,如出现在芯片外则表示外部设备。像LED、按键、显示屏等。
(2)内核外设:属于内核(CPU)中的外设。
(3)片上外设:属于内核(CPU)外的外设,即芯片厂家设计的各种寄存器组,如下面要讲的GPIO,还有像RCC、EXTI、USART/UART、I2C、SPI等。
(4)片外外设:属于芯片外的设备,如LED、按键、显示屏。
统一称谓:在讲解各芯片的片上外设时,都简称为外设。除开片上外设,其他外设都统称术语。

一、GPIO简介

GPIO即通用输入输出端口,是STM32单片机中最重要也是最基本的外设之一,GPIO起到了与外部设备通信的作用。GPIO输入(检测)或输出(驱动)控制着STM32的可编程引脚的电平变换,从而驱动各个片外外设工作。GPIO除了可以控制可编程引脚,还支持复用功能。即与外设建立起链接作用,如一些外设需要与外界通信。像EXTI、ADC、USART等。
本文只介绍GPIO控制引脚输出相应的高低电平。

EXTI外部中断/事件控制器:需与GPIOA~G_Pinx 建立起链接关系。
ADC模拟数字转换器:把外界时时变化的模拟信号转换成STM32可处理的数字信号。
USART通用同步异步收发器:即串行口,是一个非常常用的一种通信方式。

1.1GPIO框图讲解

GPIO框图如下:
在这里插入图片描述
该图片剪取于STM32F10x参考手册中的第8.1节GPIO功能描述
(1)输入讲解:输入模式有4种。1.上拉输入,2.下拉输入,3.浮空输入,4.模拟输入。
1.1 上拉输入
输入信号经过两个钳位二极管,上方进行过压保护,下方的进行欠压保护。之后来到两个电阻,上电阻为上拉电阻,下电阻为下拉电阻。现在设置为上拉输入,上拉电阻的开关将闭合。再到TTL肖特基触发器,到触发器之前有一路到模拟输入去了,这是通向ADC的在这不讨论。经过触发器有一路送到复用功能中,在这我们不讨论复用功能。再一路送到了GPIO中的IDR数据输入寄存器中。用户可驱动该寄存器读出数据。
1.2 下拉输入
下拉输入的信号流向与上拉输入一样的。但是有一点不同,下拉输入是下面的电阻开关闭合工作,上拉输入是上面的电阻工作。
1.3 浮空输入
浮空输入的信号流向与上下拉输入一样,但是开启浮空输入上下拉电阻都不闭合,输入状态随片外外设而定。
1.4.模拟输入
唯一一个输入信号流向不与先前所提的3种一样。上下拉电阻不闭合工作,信号流不经过TTL肖特基触发器,直接送到了模拟输入。即输入如何,检测就如何。此功能常用作ADC采集外界模拟信号。

(2)输出讲解: 输出模式有4种。1.推挽输出,2.开漏输出,3.复用推挽输出,4复用开漏输出。
2.1.推挽输出
数据写入到位设置/清除寄存器BSRR或数据输出寄存器ODR,ODR寄存器是可读可写的。之后送到一个选择开关中,选择开关还有一路由复用功能送来。再送到输出控制单元,控制单元类似于一个非门。当输入到控制单元中的信号为1时输出为0,上方的P-MOS管工作。输入为0,输出为1下方的N-MOS管工作。两管子轮流工作形成灌电流(P-MOS)与拉电流(N-MOS)。之后信号输出到引脚驱动外部设备。推挽输出模式具有驱动能力强。
2.2.开漏输出:
开漏输出模式在数据的写入,流向都与推挽输出一致。但是开漏输出只有下方的N-MOS管工作,无论内部送来的信号电平如何变化,输出都呈高阻态。在把开漏输出模式作为普通IO口使用时,必须外接上拉或下拉电阻。开漏输出具有电平兼容功能(外部上拉电阻可接+5v作为上拉电源)。
2.3.复用推挽输出
复用推挽输出的工作方式与普通推挽一致。只是输入源来自片上的一些外设,如EXTI,USART/UART等。
2.4.复用开漏输出:
复用开漏输出的工作方式与普通开漏一致。只是输入源来自片上的一些外设,如EXTI,USART/UART等。

二、需驱动的寄存器

在前面讲解了GPIO框图的信号流向,使读者大致了解了GPIO的工作方式。这里我们将学习如何控制GPIO的寄存器,以及一些必要的寄存器。

2.1时钟

在讲解驱动GPIO寄存器之前我们先来了解一下STM32F103中的时钟。学过单片机的读者一定不会对时钟感到陌生,如典型的51单片机(8位)最高支持40MHz的时钟频率,典型的为11.0592MHz。51单片机的时钟理解起来比较简单,差不多全程采用相同的时钟频率工作。而STM32单片机的时钟就显得复杂很多,牵及到时钟频率的倍频分频以及选择。因为每一些外设使用的时钟频率都不一样。下面我们讲解常用的3大总线的常见时钟频率。

2.2总线

(1)AHB总线:即系统总线,管理分配各个外设的时钟来源除开USB。时钟频率最高为72MHz。
(2)APB1总线:低速外设总线。时钟频率最高为36MHz。
(3)APB2总线:高速外设总线。在STM32F103中全部的GPIO都悬挂在该总线中。时钟频率最高为72MHz。
这里我们不详细介绍时钟频率是如何分配供给各外设的,因为这已经超出了我们讨论的范畴

2.3时钟配置

在STM32F103启动时,首先会进入启动文件中配置基本的运行环境。如初始化栈堆指针,用户程序指针,中断向量表,调用 SystemInit ()时钟配置函数等。 SystemInit ()函数在system_stm32f103.c文件中。该函数缺省值为:AHB=72MHz,APB1=36MHz,APB2=72MHz。其它时钟频率清查阅该函数。

2.4寄存器配置

(1)设置相应外设的时钟源。
(2)设置外设的工作参数。
设置RCC时驱动的寄存器有:RCC_APB2ENR
RCC_APB2ENR:APB2外设时钟使能寄存器。
在驱动RCC_APB2ENR的寄存器位中,只设置位2 GPIOA的时钟。
具体其它位功能请查阅STM32F10x中文参考手册时钟章节第7.3.7小节

设置GPIO时需驱动的寄存器有:CRL/CRH,ODR,BSRR,BRR。
CRL/CRH:低/高配置寄存器,用来配置GPIO的工作模式以及输出速度。如图2.4-1所示。
ODR:数据输出寄存器,用来驱动GPIO的输出状态。可读可写。如图2.4-2所示。
BSRR:位设置/清除寄存器,用来驱动GPIO的输出状态。只可写。
BRR:位清除寄存器,用来驱动GPIO的输出状态只能输出低电平。只可写。
图2.4-1
在这里插入图片描述
该图截取于STM32F10x参考手册GPIO章节的8.2.1
该寄存器属于端口配置低位寄存器CRL,控制着低8位GPIO口。高位寄存器CRH负责控制高8位GPIO口。两个寄存器的参数是一致的。设置的参数分析如下:
该寄存器4位控制着1个GPIO端口。MODEy[1:0]控制着端口的输出速度(频率),CNFy[1:0]控制着端口的工作模式,如输入/输出。下面我们来配置一下,我们把GPIOx_Pin_0(x=A~G)配置成输出速度为10MHz的通用推挽输出模式。我们先配置输出速度MODEy这里配置为01,再来配置工作模式CNFx这里为00。
在设置工作模式为输出时,是判断MODEy是否 >00,如大于则为输出模式,等于为输入模式。这里设置的MODEy大于0,所以为输出模式。总参数为0001,输出速度为10MHz的通用推挽输出模式。
注意:在设置工作模式为上拉/下拉输入模式时,该参数由GPIO_Init()初始化函数单独驱动BSRR和BRR寄存器实现。
图2.4-2
在这里插入图片描述
该图截取于STM32F10x参考手册GPIO章节的8.2.4
该寄存器负责控制(写入)和检测(读取)GPIO端口的状态(电平高低)。往ODR寄存器中写1输出高电平,写0输出低电平。每个位控制一个GPIO端口。
图2.4-3
在这里插入图片描述
该图截取于STM32F10x参考手册GPIO章节的8.2.5
该寄存器也是控制GPIO端口的电平状态只可写。往位【31:16】写1清0,写0不影响ODR位的状态,即ODR的位原值不变。【位15:0】BSy:写1置1,写1不影响ODR位的状态。
图2.4-4
在这里插入图片描述
在这里插入图片描述
该寄存器和BSRR差不多,只是把BSy置1位剪切掉了。保留了BRy清0位。每1位控制着1位GPIO端口。
下面我们采用官方固件库的方式来搭建编程环境。

三、编程环境搭建

所牵及的官方库文件:
(1)startup_stm32f10x_md.s 该文件属于汇编语言文件。里面包含了启动时需配置的参数,此文件也称为启动文件。不同型号,容量的STM32单片机需包含的启动文件都不一样。
*启动文件初始化的参数有:1 初始化堆栈指针,2 初始化程序指针,3 初始化中断向量表,设置时钟环境,调用库函数_main,最后进入c函数main。
(2)stm32f10x.h该文件包含了STM32F10x的所有寄存器映象以及一些宏定义,结构,枚举类型。
(3)system_stm32f10x.h和system_stm32f10x.c这两个文件用来初始化STM32时钟环境的。
默认配置为PCLK=72MHz,PCLK1=36MHz,PCLK2=72MHz
(4)stm32f10x_rcc.h和stm32f10x_rcc.c这两个文件用来设置各个外设的时钟源的。
该文件与第2点提到的有些区别,一个是配置时钟的环境,一个是控制各个外设的时钟开启或关闭
(5)stm32f10x_gpio.h和stm32f10x_gpio.h这两个文件用来配置GPIO外设的工作环境。
所牵及的库函数这里不做详细讲解
用户编写的文件:
(1)bsp_led.h和bsp_led.c这两个文件用来设置GPIO的工作环境。
(2)main.c这个文件用来设置LED的工作方式。

3.1完整程序

bsp_led.h

#ifndef __BSP_LED_H__
#define __BSP_LED_H__
#include "stm32f10x.h"
/*	LED工作环境设置	*/
void LED_GPIO_Config(void);
#endef	/*	__BSP_LED_H__	*/

bsp_led.c

/*******************	GPIOA端口的参数配置函数	********************/
#include "bsp_led.h"
void LED_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure ;
	/*	开启GPIO_A的时钟	*/
	RCC_APB2PeriphClockCmd(GPIOA, ENABLE);
	/*	选择GPIO_0 端口		*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
	/*	工作模式为 推挽式输出	*/
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	/*	输出速度为 10MHz	*/
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz ;
	/*	初始化GPIOA端口		*/
	GPIO_Init(GPIOA , &GPIO_InitStructure);
}

GPIO_InitStructure.GPIO_Pin:用来指定哪个IO端口。以便在配置工作状态时能确定需驱动的寄存器位。如需配置Pin_0引脚的工作模式,这样根据Pin_0所对应的CRL相应的4个位就可以设置相应的IO端口工作模式。也可用作控制IO端口的工作状态。如控制Pin_1输出高电平,这样我们可以把该宏写如BSRR寄存器位1 中。GPIO_Pin_x对应x引脚为高电平,如Pin_0对应编号为0的引脚为高电平
GPIO_InitStructure.GPIO_Mode:设置GPIO的工作模式4输入4输出。在前面的GPIO框图中已做讲解。
GPIO_InitStructure.GPIO_Speed:设置输出速度。主要是配置CRL/CRH寄存器的CNFx[1:0]位。
最后调用GPIO参数初始化函数GPIO_Init写入以上参数到GPIO相应的寄存器中,该函数的配置过程这里不做讲解。
参数配置结构体与参数初始化函数结合使用是库开发的精髓所在
main.c

#include "bsp_led.h"
/*	延迟函数	*/
void Delay(__IO u32 nCount );
void main(void)
{
	LED_GPIO_Config();
	while(1)
	{
		/*	置一GPIO端口	*/
		GPIOA->BSRR = GPIO_Pin_0;
		Delay(0xFFFFF);
		/*	清零GPIO端口	*/
		GPIOA->BRR = GPIO_Pin_0;
		Delay(0xFFFFF);
	}
}

void Delay(__IO u32 nCount )
{
	for(; nCount > 0; nCount--);
}


四、小结

(1)先使读者了解作者编写该文章的目的以及文章中出现些相关术语的介绍。
(2)之后带读者解开GPIO框图的工作流程。
(3)在了解GPIO框图之后,再使读者认识GPIO的相关寄存器的介绍和配置。
(4)最后是牵及需添加的官方库文件(函数),以及用户要编写文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPIO使用教程(学习笔记) 的相关文章

  • 关于HTTP的8种请求方法

    关于HTTP请求方法中的8种请求方法 简单介绍 HTTP是超文本传输协议 其定义了客户端与服务器端之间文本传输的规范 HTTP默认使用80端口 这个端口指的是服务端的端口 而客户端使用的端口是动态分配的 当我们没有指定端口访问时 浏览器会默
  • Quartus和ModelSim软件关联

    Quartus和ModelSim软件关联 QuartusII 18 1 和 ModelSim 10 5b 软件的关联 Altera 自身在仿真领域做的并不是很好 所以 Quartus 软件兼容 Mentor 公司的ModelSim 仿真软件
  • hutool实现excel的导出,包括级联下拉

    废话不多说 直接上代码 1 pom xml
  • 什么是 Web 3.0?

    很多人并不理解什么是 Web 3 0 本文尝试以最简洁的语言来解释一下我对于这个问题的理解 01 互联网范式迭代 Web 1 0 也就是第一代互联网 是静态互联网 主要的应用是网络媒体 各网媒雇佣一大批编辑 将图文并茂的内容发布成为网页 读
  • 无法启动程序 xxx.exe,系统找不到指定的文件

    1 问题现象 解绝方法 语法问题 scanf函数调用后边没写分号 导致没能编译生成可执行程序 2 问题现象 解绝方法 printf函数错写成print 导致语法错误 3 问题现象 解决方法 头文件写错了 找不到stdio h 注意 这几种问
  • JavaWeb 项目部署到 Aliyun 服务器

    JavaWeb 项目部署到 Aliyun 服务器 准备工作 环境 Java8 IDEA tomcat8 5 本次 web 项目在本地 tomcat 跑通 打包 项目没问题后进行打包 选择 Artifacts gt 点击 号 gt 右击选择

随机推荐

  • 【node】3、fs文件读写流

    fs createReadStream读取指定文件的可读流 const fs require fs const rs fs createReadStream 1 mp4 resume开启可读流 rs resume 通过rs readable
  • 《数据结构题集》求k阶斐波那契序列的第m项值的函数算法

    这个属于学习笔记一篇 刚看到这个题的时候 花了好半天时间 才搞明白题目到底是啥意思 原来我之前接触的斐波那契数列都是2阶的 有了思路之后就开始动手操作 经过我的验证 2阶的前14项的运算结果与百度百科上的一致 5阶前10项与我手动计算结果一
  • tp5下,保存公众号access_token

    在开发公众号的时候 免不了要用到公众号的接口 基于接口 它是需要access token做基础的 而access token它的有效期是有限定的 所以在获取到access token的时候要注意保存 1 在控制器中建一个方法 专门用来保存a
  • Mybatis中"if else"的写法

    在SSM框架中编写mapper xml的时候 需要对数据库进行操作 在对数据库操作的时候有时会遇到需要判断字段内容的情况 如果只需要判断字段满足某个条件 那么直接使用
  • 飞行棋游戏代码(C#)

    220224飞行器v1 0 using System namespace AeroplaneChess class Program 地图 static int Maps new int 100 玩家A B坐标 static int play
  • 良好的Java编程风格

    良好的Java编程风格 正确的注释和注释风格 使用文档注释来注释整个类或整个方法 如果注释方法中的某一个步骤 使用单行或多行注释 正确的缩进和空白 使用一次 tab 操作 实现缩进 运算符两边习惯性各加一个空格 比如 2 4 5 块的风格
  • Qt 关闭窗口时循环依旧运行的解决办法

    在Qt中 经常碰到关闭窗口之后 程序中的循环依旧运行 查资料知道跟线程和进程有关系 比较麻烦 以后再慢慢看线程和进程知识 今天想到一个比较偷懒的方法 具体方法如下 部分代码 1 在类中设立判断循环的标志 isLooopFlag 以及槽函数s
  • 学习笔记-正则表达式

    https www runoob com regexp regexp tutorial html 正则表达式re Regular Expression 是一种文本模式 包括普通字符 例如 a 到 z 之间的字母 和特殊字符 称为 元字符 可
  • CSerialPort教程4.3.x (1) - CSerialPort项目简介

    CSerialPort教程4 3 x 1 CSerialPort项目简介 前言 CSerialPort项目是一个基于C C 的轻量级开源跨平台串口类库 可以轻松实现跨平台多操作系统的串口读写 同时还支持C Java Python Node
  • npm yarn pnpm命令

    命令对比 命令 npm yarn pnpm 安装 install add add 安装到dependencies save 默认 默认 安装到devDependencies D save dev D dev D save dev 安装到op
  • OpenCV-Python快速入门(十四):模板匹配

    OpenCV Python快速入门 十四 模板匹配 前言 前提条件 实验环境 模板匹配 cv2 matchTemplate 匹配单个结果 匹配多个结果 参考文献 前言 本文是个人快速入门OpenCV Python的电子笔记 由于水平有限 难
  • 【C语言】C语言 atoi 函数解析

    个人主页 简 料 所属专栏 C语言 个人社区 越努力越幸运社区 简 介 简料简料 简单有料 在校大学生一枚 专注C C GO的干货分享 立志成为您的好帮手 C C 学习路线 点击解锁 C语言 初阶数据结构与算法 C 高阶数据结构 Linux
  • 万劫不复之地-云原生可观测性的几大误区

    传统监控厂商正把可观测性引入万劫不复之地 可观测性是当前讨论非常多的话题 这个理念由来已久 却在最近开始流行 在20世纪60年代 该理念首次由Rudolf E Kalman在其论文中提出 论文题目是 on a general theory
  • Python中range()函数的用法

    先列几个range 函数的几个用法 函数原型 range start end scan 参数含义 start 计数从start开始 默认是从0开始 例如range 5 等价于range 0 5 end 技术到end结束 但不包括end 例如
  • 配置环境变量后,mysql依旧提示“'mysql' 不是内部或外部命令,也不是可运行的程序或批处理文件”

    在启动菜单搜索 cmd 搜索到后不要点击运行 右击选择以管理员的身份运行 之后输入mysql u 用户名 p 密码 就可以了 在此输入 cmd 找到 命令提示符 右击选择 以管理员的身份运行 之后正常操作就可以了 ps 此外如果之前操作没问
  • Docker安装使用记录

    Docker使用 Docker简介 Docker 架构 Docker安装 Docker CE 镜像源站 使用官方安装脚本自动安装 仅适用于公网环境 手动安装帮助 阿里云ECS可以通过内网安装 见注释部分内容 Ubuntu 14 04 16
  • Linux笔记:命令进阶使用相关功能

    文章目录 目的 通配符 转义符 流程控制 管道符 重定向 环境变量 总结 目的 使用linux时用户可以通过一个又一个的命令来完成各种操作 除了基础的各个命令外linux还提供了各种便利的功能来协调使用这些命令 这些功能让用户在使用linu
  • jenkins 持续集成/项目部署

    前置操作可查阅 docker 安装 jenkins https xijia blog csdn net article details 127021367 spm 1001 2014 3001 5502 win安装及 jenkins 前置配
  • C5.0决策树算法及性能提升

    C5 0算法是基于C4 5开发的新版本 它能适用于很多类型的问题 同神经网络 支持向量机等复杂算法相比 它几乎可以表现地一样优秀 并且更容易理解和部署 这里我们将用UCI机器学习网站http archive ics uci edu ml i
  • GPIO使用教程(学习笔记)

    目录 前言 一 GPIO简介 1 1GPIO框图讲解 二 需驱动的寄存器 2 1时钟 2 2总线 2 3时钟配置 2 4寄存器配置 三 编程环境搭建 3 1完整程序 四 小结 前言 本文主要讲解如何驱动GPIO外设的相应寄存器搭建GPIO的