第四章 S5PV210微处理器GPIO编程
4.1 S5PV210硬件资源
S5PV210是一款32位精简指令集计算机(RISC),具有低成本、低功耗、高性能的微处理器解决方案,适用于手机及一般应用。它集成了ARM Cortex-A8的内核,并实现了ARM构架的V7-A的配套外设。
S5PV210采用64位的内部总线架构,包括许多强大的硬件加速器,用来完成像运动视频处理、显示控制和缩放等任务。集成多格式编解码器(MFC)。S5PV210拥有一个外部存储器,能够承受高端通信服务所需要的大记忆频宽。为了降低系统总成本和提高整体功能,S5PV210包括许多硬件外设。
硬件框图
封装与管脚
·电源管脚分配
·地线管脚分配
·UART涉及管脚
·SPI端口管脚
·PWM/I2C管脚
·I2S/PCM/SPDIF/AC97
·摄像头处理器管脚
·LCD管脚
·EINT/KEYPAD管脚
·Modem/CAMIF等管脚
·内存端口管脚
·JTAG管脚
·Clock管脚
·ADC/DAC/HDMI等管脚
·USB OTG/USB HOST管脚
·E-fuse管脚
·……
4.2 S5PV210的GPIO
GPIO概述
GPIO的英文全称General-Purpose Input /Output Ports,即通用I/O端口。嵌入式系统需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CPU控制,有的需要CPU提供输入信号。许多设备或电路只要求有开/关两种状态就够了,比如LED的亮与灭。对这些设备的控制,使用传统的串口或者并口就显得比较复杂,所以,在嵌入式微处理器上通常提供了一种“通用可编程I/O端口”,也就是GPIO。
每个GPIO端口至少需要两个寄存器,一个做控制用的“通用IO端口控制寄存器”,还有一个是存放数据的“通用I/O端口数据寄存器”。数据寄存器的每一位是和GPIO的硬件引脚对应的,而数据的传递方向是通过控制寄存器设置的,通过控制寄存器可以设置每一位引脚的数据流向。
GPIO管脚
S5PV210芯片包含237根多功能的GPIO管脚和142根内存接口引脚,共分为35组通用GPIO端口和2组内存端口,其中:
GPA0:8线输入/输出 端口 ,或2×UART 带流控制端口;
GPA1:5线输入/输出端口,或2×UART 不带流控或1×UART带流控端口;
GPB:8线输入/输出端口,或2×SPI端口;
GPC0:5线输入/输出端口,或I2S、PCM、AC97端口;
GPC1:5线输入/输出端口,或I2S、SPDIF、LCD_FRM端口;
GPD0:4线输入/输出端口,或PWM端口;
GPD1:6线输入/输出端口,或3×I2C、PWM、IEM端口;
GPE0,1:13线输入/输出端口,或Camera I/F端口;
GPF0,1,2,3:30线输入/输出端口,或LCD I/F端口;
GPG0,1,2,3:28线输入/输出端口,或4×MMC 通道端口;
GPH0,1,2,3:32线输入/输出端口,或键盘及最大32位睡眠可唤醒接口;
GPI:低功率I2S、PCM,或AUDIO_SS PDN寄存器控制PDN 掉电配置端口;
GPJ0,1,2,3,4:35线输入/输出端口,或Modem IF、CAMIF、CFCON、KEYPAD、SROM ADDR[22:16] 端口;
MP0_1,2,3:20线输入/输出端口,或EBI(SROM、NF、OneNAND)控制信号口;
MP0_4,5,6,7:32线输入/输出内存端口,或EBI端口;
MP1_0-8:71线DRAM1 端口;
MP2_0-8:71 线DRAM2 端口;
ETC0, ETC1, ETC2, ETC4:28线输入/输出ETC 端口,或JTAG端口等。
GPIO功能框图
4.3 S5PV210的GPIO寄存器
端口控制寄存器GPnCON
端口数据寄存器GPnDAT
如果端口被配置为输出端口,可以向GPnCON的相应位写数据。如果端口被配置成输入端口,可以从GPnDAT的相应位读出数据。
例如:GPA0DAT数据寄存器定义(其他端口数据寄存器定义类似)。
端口上拉寄存器GPnUP
端口上拉寄存器控制了每个端口组的上拉电阻的允许/禁止。如果某一位为0,相应的上拉电阻被允许;如果某一位为1,相应的上拉电阻被禁止。如果端口的上拉电阻被允许,无论在哪种状态下(输入、输出、DATAn、EINTn等),上拉电阻都起作用
例如:GPA0UP上拉寄存器定义:
4.4 GPIO编程实例
电路连接
该实例电路通过GPD0_0管脚连接蜂鸣器,并通过GPH2_0/1/2/3管脚连接4只独立按键,通过GPJ2_0/1/2/3管脚连接LED等。对S5PV210的GPIO口进行编程,用查询方式获取按键状态,当按键按下时,对应的LED灯闪亮,蜂鸣器鸣响一声。当按键松开,对应的LED灯熄灭。
寄存器设置
为了达到读取按键及控制蜂鸣器的目的,需要通过配置GPD0CON寄存器将GPD0_0管脚配置为输出方式,LED灯控制引脚寄存器GPJ2CON配置为GPJ2_0/1/2/3引脚为输出功能,将按键输入引脚寄存器GPH2CON使GPH2_0/1/2/3引脚为输入功能。
蜂鸣器控制程序buzzer.c
#define GPD0CON(*(volatile unsigned long *)0xE02000A0)
#define GPD0DAT(*(volatile unsigned long *)0xE02000A4)
// 初始化buzzer
void buzzer_init(void)
{
GPD0CON |= 1<<0;
}
void buzzer_on(void)
{
GPD0DAT |= 1<<0;
}
void buzzer_off(void)
{
GPD0DAT &= ~(1<<0);
}
主程序 main.c
// LED
#define GPJ2CON (*(volatile unsigned long *) 0xE0200280)
#define GPJ2DAT(*(volatile unsigned long *) 0xE0200284)
// KEY
#define GPH2CON (*(volatile unsigned long *) 0xE0200C40)
#define GPH2DAT(*(volatile unsigned long *) 0xE0200C44)
//灯输出与按键输入
#define GPJ2_0_OUTPUT (1<<(0*4))
#define GPJ2_1_OUTPUT (1<<(1*4))
#define GPJ2_2_OUTPUT (1<<(2*4))
#define GPJ2_3_OUTPUT (1<<(3*4))
#define GPH2_0_INTPUT ~(0xf<<(0*4))
#define GPH2_1_INTPUT ~(0xf<<(1*4))
#define GPH2_2_INTPUT ~(0xf<<(2*4))
#define GPH2_3_INTPUT ~(0xf<<(3*4))
void main()
{ unsigned long dat;
// LED:设置寄存器GPJ2CON0使GPJ2_0/1/2/3引脚为输出功能
GPJ2CON = GPJ2_0_OUTPUT|GPJ2_1_OUTPUT|GPJ2_2_OUTPUT|GPJ2_3_OUTPUT;
// KEY:设置寄存器GPH2CON0使GPH2_0/1/2/3引脚为输入功能
GPH2CON =GPH2_0_INTPUT&GPH2_1_INTPUT&GPH2_2_INTPUT&GPH2_3_INTPUT;
buzzer_init();
while(1){
// 读取KEY相关的引脚值,用于判断KEY是否被按下
dat = GPH2DAT;
// 判断KEY1:GPH2_0
if(dat & (1<<0))// KEY1被按下,则LED1亮,否则LED1灭
{GPJ2DAT |= 1<<0;// OFF
buzzer_off();
}
else
{GPJ2DAT &= ~(1<<0);// ON
buzzer_on();
delay(0x10000);
}
// 判断KEY2:GPH2_1
if(dat & (1<<1))// KEY2被按下,则LED2亮,否则LED2灭
{GPJ2DAT |= 1<<1; buzzer_off();}
else
{GPJ2DAT &= ~(1<<1); buzzer_on(); delay(0x10000); }
// 判断KEY3:GPH2_2
if(dat & (1<<2))// KEY3被按下,则LED3亮,否则LED3灭
{……}
else
{……}
// 判断KEY4:GPH2_3
if(dat & (1<<3))// KEY4被按下,则LED4亮,否则LED4灭
{……}
else
{……}
} //End of while(1)
} //End of main()