声明:本文由个人学习过程中整理而成,转载请注明出处


实验开发版:S5PV210

1、什么是GPIO?

General Purpose Input Output (通用输入/输出)简称为GPIO,属于芯片引脚的一部分。

嵌入式系统中常常有数量众多,但是结构却比较简单的外部设备/电路,对这些设备/电路有的需要CPU为之提供控制手段,有的则需要被CPU用作输入信号。而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了,比如灯亮与灭。对这些设备/电路的控制,使用传统的串行口或并行口都不合适。所以在微控制器芯片上一般都会提供一个“通用可编程IO接口”,即GPIO。


2、点亮LED的原因

点亮LED要求正极与负极之间有一定的正向电压差。

熄灭LED就是让正极与负极之间没有电压差。


3、查询原理图

ARM裸机之点亮LED_第1张图片

D22:正极接3.3v,负极接引脚GPJ0_3。

D23:正极接3.3v,负极接引脚GPJ0_4。

D24:正极接3.3v,负极接引脚GPJ0_5。

D25:正极接3.3v,负极接引脚PWMTOUT1(GPD0_1)。

D26:正极接5V,负极接地。

可以通过编程控制GPIO引脚输出低电平,产生电压差。


4、查询数据手册

设置GPJ0CON控制寄存器,GPJ0_3、GPJ0_4、GPJ0_5引脚为Output工作模式,使其能输出电压。

ARM裸机之点亮LED_第2张图片


设置GPJ0DAT数据寄存器,GPJ0_3、GPJ0_4、GPJ0_5引脚相应位为0(低电平)。


5、点亮LED的步骤:

(1)设置GPJ0CON控制寄存器,GPJ0_3、GPJ0_4、GPJ0_5引脚为Output工作模式,使其能输出电压。

(2)设置GPJ0DAT数据寄存器,GPJ0_3、GPJ0_4、GPJ0_5引脚相应位为0(0为低电平,1为高电平)。


6、汇编代码实现LED流水灯

.global _start//链接属性改为外部

_start:

//配置GPJ0_3 ~ GPJ0_5为输出模式

ldr r0, =0xE0200240

ldr r1, =0x00111000

str r1, [r0]

 

//配置GPD0_1为输出模式

ldr r0, =0xE02000A0

ldr r1, =0x00000010

str r1, [r0]

 

loop_led:

//配置GPJ0_3为低电平

ldr r0, =0xE0200244

ldr r1, =((0<<3) | (1<<4) | (1<<5))

str r1, [r0]

//延时

bl delay

 

//配置GPJ0_4为低电平

ldr r0, =0xE0200244

ldr r1, =((1<<3) | (0<<4) | (1<<5))

str r1, [r0]

//延时

bl delay

 

//配置GPJ0_5为低电平

ldr r0, =0xE0200244

ldr r1, =((1<<3) | (1<<4) | (0<<5))

str r1, [r0]

//延时

bl delay

 

//配置GPJ0_3 ~ GPJ0_5为高电平

ldr r0, =0xE0200244

ldr r1, =((1<<3) | (1<<4) | (1<<5))

str r1, [r0]


//配置GPD0_1为低电平

ldr r0, =0xE02000A4

ldr r1, =(0<<1)

str r1, [r0]


//延时

bl delay


//配置GPD0_1为高电平

ldr r0, =0xE02000A4

ldr r1, =(1<<1)

str r1, [r0]

 

b loop_led


// 延时功能

delay:

ldr r1, =0

ldr r2, =7777777

loop_delay:

sub r2, r2, #1

cmp r1, r2

bne loop_delay

mov pc, lr


7、C语言代码实现流水灯

// 寄存器宏定义

#defineGPJ0CON(0xE0200240)

#defineGPJ0DAT(0xE0200244)

 

#define GPD0CON(0xE02000A0)

#define GPD0DAT(0xE02000A4)


#define rGPJ0CON(*(volatile unsigned int *)GPJ0CON)

#define rGPD0CON(*(volatile unsigned int *)GPD0CON)

 

#definerGPJ0DAT(*(unsigned volatile int *)GPJ0DAT)

#definerGPD0DAT(*(unsigned volatile int *)GPD0DAT)

 

// 延时函数

void delay_time(void)

{

    volatile unsigned int i = 0;

    for(i=0; i<40000; i++)

    for(i=0; i<600000; i++);

}

 

void illumine_led(void)

{

    // 配置为输出模式

    rGPJ0CON = 0x00111000;

    rGPD0CON = 0x00000010;

    

    while(1)

    {

        //点亮LED1、延迟

        rGPJ0DAT = ~(1 << 3);

        delay_time();

        

        //点亮LED2、延迟

        rGPJ0DAT = ~(1 << 4);

        delay_time();

        

        //点亮LED3、延迟

        rGPJ0DAT = ~(1 << 5);

        delay_time();

        

        //熄灭LED1~LED3

        rGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));

        

        //点亮LED4、延迟

        rGPD0DAT = ~(1<<1);

        delay_time();

        

        //熄灭LED4

        rGPD0DAT = (1<<1);

    }

}


参考资料:《ARM裸机全集---朱有鹏老师》