学习目标与要求 
1.掌握嵌入式输入/输出接口的结构和数据传输方式。 
2.掌握常见的嵌入式输入/输出接口的实现原理。 
3.掌握常见的嵌入式输入/输出接口的使用方法。 


5.1 
I/O接口 
5.1.1接口结构
嵌入式系统需要连接的外部输入/输出设备(简称外设)具备多样性、复杂性和异构性

(处理速度不同)等特点,因此一般需要借助于接口电路来实现外设与 
CPU之间的连接。
负责外设与 
CPU连接的中间接口电路即输入/输出接口电路,简称 
I/O接口。I/O接口在
嵌入式系统中所处的位置如图 
5.1所示。


图 
5.1 
I/O接口在嵌入式系统中所处的位置 


5.1.2 
I/O接口组成 
I/O接口通常具备如下几方面的功能。

(1)数据缓存。
(2)CPU命令接收和执行。
(3)信号电平转换。
(4)数据格式转换。
(5)外设选择。
(6)中断管理。

为实现上述功能,I/O接口一般包括数据缓存、逻辑控制和外设连接 
3个基本的功能
模块,I/O接口的结构如图 
5.2所示。


图 
5.2 
I/O接口的结构

数据缓存功能模块主要对应一组寄存器,负责 
I/O交互过程的控制和记录等。数据缓
存寄存器可根据存放数据类型的不同,划分为数据寄存器、控制寄存器和状态寄存器。其
中数据寄存器用来存放交互过程中需传输的数据,控制寄存器用来存放外设、 
I/O接口的
控制命令(如 
I/O接口启动、中断使能等),状态寄存器则用来记录外设、 
I/O接口的状
态信息(如中断状态、系统故障等)。

逻辑控制功能模块主要接收 
CPU传输过来的地址,根据地址进行外设选择。

外设连接功能模块是 
I/O接口与外设的交互接口。同一个 
I/O控制器可与多个外设
连接,因此需要设置一个或多个外设连接逻辑功能来实现外设与 
CPU的连接。 


5.1.3 
I/O接口的数据传输 
I/O接口的数据传输方式一般包括程序查询方式、中断方式和直接访存方式 
3种。

程序查询方式是 
CPU负责查询外设的状态寄存器,判断外设的数据是否就绪。若就
绪,则直接进行数据传输;否则,CPU等待数据就绪或继续查询其他外设。

中断方式是当外设数据就绪时,外设向 
CPU发出中断服务请求信号。CPU根据当前
执行程序以及外设中断请求各自优先级的高低,判断是否暂停当前执行的程序以响应外设
的中断服务请求。若外设中断服务请求的优先级高,则 
CPU暂停当前执行程序来完成外
设数据传输;否则继续执行完当前程序再响应外设中断服务请求。从 
CPU响应的角度看,
程序查询方式是一种主动的处理方式,程序中断方式是一种被动的处理方式。因此,后一
种处理方式可实现 
CPU与外设的并行处理,使得 
CPU的利用率更高。

直接访存方式 
DMA在外设与内存之间建立直接的数据传输通道,数据传输过程中不
需要 
CPU的参与,从而进一步提升了数据传输效率。 
I/O接口 
3种数据传输方式的对比
如表 
5.1所示。 



表 
5.1 
I/O接口 
3种数据传输方式的对比

数据传输方式优点缺点适用场合 
程序查询方式实现成本低
CPU利用率低
低速的字符外设
数据传输速度慢
低速的字符外设
中断方式 
CPU与外设可并行执行
CPU利用率较高
数据传输速度较快
不适用于批处理数据传输常见外设 
直接访存方式
无须 
CPU参与
数据传输速度最快 
需 
DMA控制器高速外设

5.2 
GPIO 
5.2.1 
GPIO概述 
GPIO(General 
Purpose 
Input/Output,通用输入 
/输出接口)用来实现外设与 
CPU
的连接。 
I/O接口的功能一般固定,但是 
GPIO可通过寄存器配置和编程实现功能复用。
每个 
GPIO端口对应微处理器的一组 
16个引脚, 
GPIO端口的功能通过一组寄存器来进
行配置。GPIO端口的内部结构如图 
5.3所示。


图 
5.3 
GPIO端口内部结构图

以 
Cortex-M4微处理器为例,它包含 
GPIO 
A~GPIO 
I共 
9个 
GPIO端口,每

个 
GPIO端口对应 
1个 
32位操作寄存器( 
GPIOx_BSRR)、 
1个 
32位锁定寄存器
(GPIOx_LCKR)、 
4个 
32位配置寄存器(包括 
GPIOx_MODER、GPIOx_OTYPER、 
GPIOx_OSPEEDR和 
GPIOx_PUPDR)、2个 
32位数据寄存器( 
GPIOx_IDR和 
GPIOx 



_ODR)和 
2个 
32位备用功能选择寄存器( 
GPIOx_AFRH和 
GPIOx_AFRL)。由于每
个端口对应 
16个引脚,因此上述寄存器中的每 
2位控制一个引脚。 
Cortex-M4的 
GPIO
端口对应寄存器的功能如表 
5.2所示。

表 
5.2 
GPIO寄存器功能描述

配置寄存器组
模式(输入/输出/模拟/备用) 
输出类型(推挽/开漏) 
输出速度 
上拉/下拉使能 
GPIOx_MODERGPIOx_OTYPERGPIOx_OSPEEDRGPIOx_PUPDR
数据寄存器组
输出数据 
输入数据 
GPIOx_ODRGPIOx_IDR
位操作寄存器 
GPIOx_BSRR
配置锁定寄存器 
GPIOx_LCKR
复用功能及重映射寄存器 
GPIOx_AFRL, 
GPIOx_AFRH 


5.2.2 
GPIO功能特点 
GPIO具备如下资源。

(1)输出状态:推挽、开漏,上拉/下拉。
(2)输入状态:浮动、上拉/下拉、模拟。
(3)数据从输出数据寄存器(GPIOx_ODR)或外设(备用功能输出)输出。
(4)输入数据到输入数据寄存器(GPIOx_IDR)或外设(备用功能输入)。
(5)I/O端口速度可配置。
(6)位设置和位重置寄存器( 
GPIOx_BSRR),然后可按位写入 
GPIOx_ODR寄存器。
(7)可通过配置锁定寄存器(GPIOx_LCKR)锁定 
I/O配置。
(8)可实现 
ADC和 
DAC模拟信号输入/输出。
(9)复用功能输入/输出选择寄存器(每个 
I/O端口最多支持 
16个 
AFS复用功能)。
(10)可实现每两个时钟周期快速切换。
(11)高度灵活的引脚复用功能,允许 
I/O引脚使用 
GPIO或几种外设功能之一。 
5.2.3 
GPIO输入/输出模式 
GPIO端口对应的引脚可配置为如下 
8种模式,其中( 
1)~(4)为输入模式,(5)和

(6)为输出模式,(7)和(8)为复用模式。
(1)浮空输入_IN_FLOATING:可以用作按键识别。
(2)带上拉输入_IPU:I/O内部上拉电阻输入。
(3)带下拉输入_IPD:I/O内部下拉电阻输入。
(4)模拟输入_AIN:应用 
ADC模拟输入,或者低功耗模式下进行节能操作。
(5)开漏输出 
_OUT_OD:I/O输出 
0接 
GND;I/O输出 
1悬空,需外接上拉电阻才
能实现高电平输出。 

(6)推挽输出 
_OUT_PP:I/O输出 
0接 
GND;I/O输出 
1接 
VCC,读输入值未知。
(7)复用功能的推挽输出_AF_PP:片内外设功能(如 
I2C的 
SCL、SDA)。
(8)复用功能的开漏输出_AF_OD:片内外设功能(TX1、MOSI、MISO、SCK)。 
5.2.4 
GPIO引脚复用
由于微处理器的引脚有限,为了提高 
I/O接口的利用率,更好地协调不同外设与 
CPU
之间的交互,将通过多路复用器实现引脚的多路复用。引脚多路复用是通过寄存器配置,实
现同一引脚在不同时刻与不同外设之间的交互,即不同的外设可共享相同的引脚连接。在
某一个时刻,只允许引脚与某一个外设交互。

如表 
5.2所示,每个 
GPIO端口均对应一组寄存器,其中 
GPIOx_AFRL和 
GPIOx 
_AFRH两个寄存器用来实现 
x端口对应引脚的多路复用功能。GPIOx_AFRL和 
GPIOx 
_AFRH两个 
32位寄存器使用寄存器的每 
4位来配置一个引脚。GPIOx_AFRL寄存器配
置 
x端口对应的第 
0~7号引脚, 
GPIOx_AFRH配置 
x端口对应的第 
8~15号引脚。如
以 
STM32F4系列芯片为例,每个端口包含的 
16个引脚将通过多路复用器一一对应连接
到 
16个复用功能模块( 
AF0~AF15)。GPIOx_AFRL寄存器用来选择 
AF0~AF7功能
模块, 
GPIOx_AFRH用来选择 
AF8~AF15功能模块。 
GPIO引脚的多路复用器和多路
复用配置如图 
5.4所示。


图 
5.4 
GPIO引脚的多路复用器和多路复用配置

如图 
5.4所示,系统复位后,所有的 
GPIO引脚将连接到系统的备用功能 
AF0,所有
外设的复用功能将映射到 
AF1~AF13,EVENTOUT事件将映射到 
AF15。

举例说明,假设开发板 
x端口对应的 
11号引脚 
PC11可作为 
SPI3_MISO/U3_RX/ 
U4_RX/SDIO_D3/DCMI_D4/I2S3ext_SD等复用功能,而现在需要配置 
PC11为 
SDIO 
_D3功能使用。11号引脚的复用功能将通过 
GPIOx_AFRH[15:12]来进行配置,因此需要
选择 
AF12,即设置 
GPIOx_AFRH[15:12]=AF12。 


5.2.5 
GPIO配置 
GPIO引脚的配置需完成输入配置、输出配置和复用配置等。 



1.输入配置
当 
GPIO引脚被配置为输入时,其输入配置如图 
5.5所示。


图 
5.5输入配置

(1)输出缓冲器被禁止。
(2)施密特触发输入被激活。
(3)根据寄存器 
GPIOx_PUPDR中的值选择引脚为上拉或下拉。
(4)GPIO引脚上的数据在每个 
AHB1时钟周期被采样到输入数据寄存器。
(5)对输入数据寄存器的读访问可获得 
GPIO状态。 
2.输出配置
当 
GPIO引脚被配置为输出时,其输出配置如图 
5.6所示。


图 
5.6输出配置 



(1)输出缓冲器被激活。 
1

.开漏模式:输出寄存器上的 
0激活 
NMOS,而输出寄存器上的 
1将端口置于高阻
状态(PMOS从不被激活)。 


2

.推挽模式:输出寄存器上的 
0激活 
NMOS,而输出寄存器上的 
1将激活 
PMOS。

(2)施密特触发器输入被激活。
(3)根据寄存器 
GPIOx_PUPDR中的值选择引脚为弱上拉或弱下拉。
(4)GPIO引脚上的数据在每个 
AHB1时钟周期被采样到输出数据寄存器 
GPIOxODR
。
(5)对输入数据寄存器的读访问可得到 
GPIO状态。
(6)对输出数据寄存器的读访问得到最后一次写入的值。 
3.复用配置
当 
GPIO引脚被配置为输出时,其复用配置如图 
5.7所示。


图 
5.7复用功能配置

(1)输出缓冲器可以被配置成开漏或推挽。
(2)输出缓冲器被片上外设信号驱动。
(3)施密特触发器输入被激活。
(4)根据 
GPIOx_PUPDR寄存器中的值选择引脚为弱上拉或弱下拉。
(5)GPIO引脚上的数据在每个 
AHB1时钟周期被采样到输入数据寄存器 
GPIOxIDR
。
(6)对输入数据寄存器的读访问将得到 
GPIO状态。
(7)对输出数据寄存器的读访问得到最后一次写入的值。
根据以上机制,可以设计一个通用的配置函数来进行 
GPIO配置。该函数的代码
如下。 



// 
GPIO通用设置, 
GPIOx: 
GPIOA~GPIOI 
// 
BITx: 
0X0000~0XFFFF,位设置,每个位代表一个 
I/O 
//第0位代表 
Px0,第 
1位代表 
Px1,以此类推。比如 
0X0101代表同时设置 
Px0和Px1 
// 
MODE:0~3模式选择, 
0输入(系统复位默认状态); 
1普通输出; 
2复用功能; 
// 
3模拟输入 
// 
OTYPE: 
0/1,输出类型选择, 
0推免输出; 
1开漏输出 
// 
OSPEED: 
0~3,输出速度设置, 
0 
2MHz;1 
25MHz;250MHz;3 
100MHz 
// 
PUPD: 
0~3,上下拉设置, 
0不带上下拉; 
1上拉; 
2下拉; 
3保留 
//注意:在输入模式(普通输入 
/模拟输入)下, 
OTYPE和 
OSPEED参数无效 


void 
GPIO_Set(GPIO_TypeDef* 
GPIOx,u32 
BITx, 
u32 
MODE, 
u32 
OTYPE, 
u32 
OSPEED, 
u32 
UPPD) 


{ 
u32 
pinpos 
=0, 
pos=0, 
curpin 
=0. 
for 
( 
pinpos 
=0.pinpos 
<16. 
pinpos++) 
{ 


pos=1<<pinpos 
. 
//一位位检查 
curpin=BITx&pos 
. 
if 
( 
curpin==pos) 
//需要设置 
{ 


GPIO.>MODER&=~(3<<(pinpos 
*2)) 
. 
//清除原来的

设置 
GPIO.>MODER|=(MODE<<(pinpos 
*2)) 
. 
//设置新的模式 
if(MODE==0X01) 
||(MODE==0X02) 
{ 


GPIO.>OSPEED&=~(3<<(pinpos 
*2)) 
. 
GPIO.>OSPEED|=(OSPEED<<(pinpos 
*2)) 
. 
GPIO.>OTYPE&=~(1<<pinpos 
) 
. 
GPIO.>OTYPE|=(OTYPE<<pinpos 
) 
. 


} 
GPIO.>PUPDR&=~(3<<(pinpos 
*2)) 
. 
GPIO.>PUPDR|=(PUPDR<<(pinpos 
*2)) 
. 


} 
} 
} 


5.3外部中断/事件 
5.3.1外部中断/事件概述
外部中断 
/事件是实现外设与微处理器之间通信的主要方式之一。微处理器中包含一 



个外部中断 
/事件控制器( 
External 
Interrupt/Event 
Controller,EXTI),用于管理微处
理器中的外部中断 
/事件线。每个中断 
/事件线都对应一个边沿检测器,实现输入信号的
上升沿或下降沿检测。 
EXTI可以对每个中断 
/事件线进行单独配置,配置中断或者事件
类别以及触发时间的属性。 
EXTI还包含一个挂起寄存器,用于记录每个中断 
/事件线的
状态。 


Cortex-M4中的 
EXTI可支持如下所示的 
23个外部中断/事件:

(1)EXTI线 
0~15:对应 
GPIO的输入中断。
(2)EXTI线 
16:连接到 
PVD输出。
(3)EXTI线 
17:连接到 
RTC闹钟事件。
(4)EXTI线 
18:连接到 
USB 
OTG 
FS唤醒事件。
(5)EXTI线 
19:连接到以太网唤醒事件。
(6)EXTI线 
20:连接到 
USB 
OTG 
HS(在 
FS中配置)唤醒事件。
(7)EXTI线 
21:连接到 
RTC入侵和时间戳事件。
(8)EXTI线 
22:连接到 
RTC唤醒事件。 
5.3.2 
EXTI结构和外部中断/事件响应过程
如图 
5.8所示为 
EXTI结构和外部中断/事件响应过程。图中的实线箭头标注了外部中
断信号的传输路径。响应具体的过程是:外设的中断信号从编号为 
1的芯片引脚进入,经过
编号为 
2的边沿检测电路,通过编号为 
3的或门进入中断挂起请求寄存器。最后,经过编
号为 
4的与门输出到内嵌向量中断控制器( 
Nested 
Vectored 
Interrupt 
Controller,NVIC)
检测电路。该边沿检测电路受上升沿或下降沿选择寄存器控制,用户可以通过它们控制在
哪一个边沿产生中断。由于上升沿或下降沿分别受两个并行的选择寄存器控制,所以用户
可以选择上升沿或下降沿,或者同时选择上升沿和下降沿。如果只有一个寄存器控制,则
只能选择一种边沿触发。编号 
3所对应或门的另一个输入是软件中断/事件寄存器,软件可
以优先于外部信号请求中断或事件,即当软件中断 
/事件寄存器的对应位为 
1时,不管外部
信号如何,编号为 
3的或门都会输出有效信号。中断或事件请求信号经过编号为 
3的或门
后进入挂起请求寄存器,挂起请求寄存器中记录了外部信号的电平变化。在此之前,中断
和事件的信号传输路径一致。外部请求信号经过编号为 
4的与门后,向 
NVIC发出一个中
断请求。如果中断屏蔽寄存器的对应位为 
0,则该请求信号不能传输到与门的另一端,从
而实现了中断屏蔽;反之,则正常响应中断,进入中断服务程序。

如图 
5.8所示,虚线箭头标注了外部事件信号的传输路径。外部事件请求信号经过编
号为 
3的或门后,进入编号为 
5的与门。这个与门的作用与编号为 
4的与门类似,用于引
入事件屏蔽寄存器的控制。最后,编号 
6所对应脉冲发生器的跳变信号转变为一个单脉冲,
输出到芯片中的其他功能模块。如图 
5.8所示,从外部激励信号来看,中断和事件的产生
源可以一样。中断和事件的区别在于,中断需要 
CPU参与后续的中断响应,包括上下文
切换、执行中断服务程序、恢复现场并返回等;但是事件仅触发脉冲发生器产生一个单脉
冲,进而由硬件自动完成事件的响应,比如 
DMA操作、AD转换等。 



图 
5.8 
EXTI结构和外部中断/事件响应过程 


5.3.3外部中断/事件的配置
如果要产生中断/事件,则必须配置中断 
/事件线。首先,选择中断 
/事件的边沿触发信
号,设置两个触发选择寄存器,同时在中断 
/事件屏蔽寄存器相应位写 
1,允许中断 
/事件
请求。当外部中断 
/事件线发生了配置的边沿触发信号时,将产生一个中断 
/事件请求,对
应挂起位将被置为 
1。在挂起寄存器对应位写 
1将清除该中断。通过在软件中断 
/事件寄存
器写 
1,也可以由软件产生中断/事件请求。

具体而言,外部中断/事件的中断配置如下。 


1.硬件中断选择配置
通过如下过程可配置 
23个中断线路作为中断源。

(1)配置 
23个中断线的屏蔽位(EXTI_IMR)。
(2)配置所选中断线路的触发选择位(EXTI_RTSR和 
EXTI_FTSR)。
(3)配置对应到外部中断控制器( 
EXTI)的 
NVIC中断通道的使能和屏蔽位,使得 
23
个中断线路中的中断请求可以被正确响应。 
2.硬件事件选择配置
通过如下过程可配置 
23个线路作为事件源。

(1)配置 
23个事件线的屏蔽位(EXTI_EMR)。
(2)配置所选事件线的触发选择位(EXTI_RTSR和 
EXTI_FTSR)。 
3.软件中断/事件选择配置 
19个线路可配置为软件中断/事件线,其配置如下:

(1)配置 
19个中断/事件线的屏蔽位(EXTI_IMR和 
EXTI_EMR)。
(2)设置软件中断寄存器的请求位(EXTI_SWIER)。