03. GPIO编程
1. GPIO功能简介
1)什么是GPIO?
GPIO,General-Purpose IO Ports,即通用IO接口。
2)GPIO作用
① 在嵌入式系统中有数量众多但结构却比较简单的外部设备,这些设备有的需要CPU为之提供控制手段。
② 许多这样的设备只要求一位,即只要有开/关两种状态就够了,比如控制某个LED 灯。对这些设备使用串口、并口、USB等均不合适。
小结:GPIO用作控制端口就是实现简单设备的简单控制。
补充:GPIO 一般都是连接简单、低速设备
3)GPIO的构成(data sheet层面)
至少两个寄存器:控制寄存器、数据寄存器
数据寄存器的各位都直接引到芯片外部,而对这种寄存器中每一位的作用、信号的流通方向,则是通过控制寄存器进行设置(输入、输出、特殊功能)。
补充:很多MCU 的GPIO除了上述标准寄存器,还提供上拉/下拉寄存器。当GPIO引脚处于第三态(既不是输出高电平也不是输出低电平,而是呈高阻态,即相当于没接芯片)时,他的电平状态由上拉/下拉电阻决定。
2. S5PV210芯片GPIO控制器简介
1)总额及分类
了解GPIO端口分组,以后可快速确定硬件所使用的端口。
2)原理框图
3)常用寄存器分类
说明:每组GPIO设有一组控制、数据寄存器
注意:此处控制外设的寄存器与CPU 中的寄存器(r0~r15, CPSR, SPSR)是完全不同的概念。
常用寄存器有以下三种:
① 控制寄存器(CON)
说明:MP0_4CON共控制8个外部管脚,每个管脚使用4位进行控制
②数据寄存器(DAT)
说明:MP04_4DAT 寄存器只使用了32位中的8位(数据寄存器使用的位数,与控制寄存器控制的管脚数匹配)
③上拉寄存器(PUD)
说明:每个管脚使用2位进行控制,默认状态不使用上拉/下拉电阻
3. 硬件外设开发流程(以LED为例)
1)分析外设工作原理
尤其是针对较为复杂的外设,他们往往使用了相关总线(如I2C、SPI)
2)查看底板原理图,了解外设的连接方式
3)查看核心板原理图,了解外设使用的接口
4)根据主控芯片手册,控制相关接口
可见LED使用的四个端口分别是:MP04_4 ~ MP04_7,那么针对MP04相关寄存器进行设置即可。
4. LED 驱动开发实例
1)流程
① 设置管脚MP04_4 ~ MP04_7 为输出模式(MP0_4CON)
② 使需要点亮的LED的对应管脚输出低电平
2)汇编语言实现
特别补充:外设控制中,汇编语言程序设计的三个规范(达内课程)
A. 修改所需位时不影响其他位
B. 使用宏定义标识外设寄存器地址
C. 为减少伪指令,对外设寄存器的地址宏定义采用基地址 + 偏移实现
示例:以MP04组GPIO为例
.equ MP04_BASE 0xe0200340
ldr r0, =MP04_BASE @仅需要这一条伪指令
@对MP04CON 赋值
str r1, [r0, #0]
@对MP04DAT 赋值
str r1, [r0, #4]
注意:因为在这种使用方式中r0 保存的是外设寄存器基地址,所以不能随意改变。
3)C语言实现
此处有2个要点:
① 如何定义寄存器
A. 基础版
#define MP04CON (*(volatile unsigned int *)0xe0200340)
#define MP04DAT (*(volatile unsigned int *)0xe0200344)
完善:可以定义一个带参数宏简化上述操作
#define __REG(x) (*(volatile unsigned int *)(x))
#define MP04CON __REG(0xe0200340)
B. 进阶版
将GPIO分组定义为结构体
/*MP04*/
typedef struct
{
unsigned int MP0_4CON;
unsigned int MP0_4DAT;
unsigned int MP0_4PUD;
unsigned int MP0_4DRV;
unsigned int MP0_4CONPDN;
unsigned int MP0_4PUDPDN;
}mp0_4;
#define MP0_4 (*(volatile mp0_4 *)0xe0200340)
如此定义后,就可以在程序中做如下使用:
MP0_4.MP0_4CON = MP0_4.MP0_4CON & ~(0xffff << 16) | (0x1111 << 16);
② 灵活使用移位运算符,实现对寄存器的位控制
MP0_4.MP0_4CON = MP0_4.MP0_4CON & ~(0xffff << 16) | (0x1111 << 16);
4)注意事项
注意裸机汇编代码最后的死循环
作用:防止程序跑飞~~