ARM学习之GPIO编程

开发环境与平台

开发板:粤嵌的GEC210开发板
处理器:s5pv210
处理器内核:Cortex-A8
开发环境:Keil4


基础知识

1、s5pv210的I/O口

S5PV210芯片上共有237个多功能的I/O口,分为34组I/0端口
ARM学习之GPIO编程_第1张图片

2、内存单元

指针:内存单元的地址。
将一个数值强制转换为指针:(int )0x20391049
给地址赋值:(
(int *)0x20391049) = 0x101001

内存单元的地址就是内存单元的编号。
ARM学习之GPIO编程_第2张图片
对于32位机来说,可寻址的范围是0~2^24,也就是最大可以达到4G。操作寄存器也就是操作特定编号的内存单元。

3、程序操作相关

置位操作:  GPIO_REG  |= (1 << x);     //将GPIO_REG的第x位置1
清零操作:  GPIO_REG  &= ~(1 << x);    //将GPIO_REG的第x位清零

定义寄存器:#define GPJ2CON    (*(volatile unsigned int*)0XE0200280)
           #define GPJ2DAT    (*(volatile unsigned int*) 0XE0200284)

volatile关键字的作用:作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。


实验:LED灯亮灭闪烁

操作控制LED亮灭实际就是控制芯片的GPIO引脚输出高低电平,控制GPIO就是控制GPIO的寄存器

1、查看原理图

通过查看原理图可以得知控制LED接的分别是芯片的GPJ2_0、GPJ2_1、GPJ2_2、GPJ2_3引脚。GPIO输出低电平点亮LED,高电平熄灭。
ARM学习之GPIO编程_第3张图片


2、看S5PV210芯片手册

找到对应GPJ2寄存器相关的章节

1、配置寄存器

ARM学习之GPIO编程_第4张图片
通过配置寄存器配置GPIO的模式,可以看到四位控制一个GPIO引脚的模式,有输入、输出、中断等等模式。可以看到每四位默认是0000,所以引脚默认是输入,这里要控制led,所以要配置为输出。

2、数据寄存器

GPJ2组GPIO只有7个引脚,数据寄存器的0-7位分别对应GPJ2_0~7,对数据寄存器对应的位写入0就将对应的GPIO输出低电平,反之输出高电平。
ARM学习之GPIO编程_第5张图片

3、其他寄存器

暂时只看以上寄存器即可。


3、编写程序

(1)汇编程序

	area init,code ,readonly
	entry
	
	ldr r1, =0xE0200280      ;将控制寄存器地址放到r1
	ldr r0, =0x00001111      ;将0x00001111存放r0中
	str r0, [r1]             ;将控制寄存器的值设置为0x00001111,即将GPJ2_0/1/2/3配置为输出模式
	
led_blink:
	;设置GPJ2DAT的bit[0:3],使GPJ2_0/1/2/3引脚输出低电平,LED亮
	ldr r1, =0xE0200284 					
	mov r0, #0
	str r0, [r1]
	
	bl delay		              	; 延时				

	;设置GPJ2DAT的bit[0:3],使GPJ2_0/1/2/3引脚输出高电平,LED灭
	ldr r1, =0xE0200284 					
	mov r0, #0xf
	str r0, [r1]

	bl delay	                      ;延时
	
	b  led_blink

halt:
	b halt


delay:
	mov r0, #0xf00000
delay_loop:
	cmp r0, #0
	sub r0, r0, #1
	bne delay_loop
	mov pc, lr
	
	end

(2)C语言程序

start.s:

	area init,code ,readonly
	entry

reset
	;先省略设置堆栈这些东西
	import Main
	bl Main
	b .

	end

led.c:

#include "s5pv210.h"
#include "led.h"

void led_init(void)    //LED引脚初始化
{
	GPJ2.GPJ2CON=(GPJ2.GPJ2CON & ~0xffff) | (0x1111);     //配置GPJ2_0/1/2/3为输出

	GPJ2.GPJ2DAT |=0XF;                                  //拉高,默认LED是熄灭的
 
}

void led_on_off(void)
{
    /*异或,不同为1,相同为0。异或0xF,GPJ2_0/1/2/3为低电平时执行该语句后变成高电平熄灭LED
     GPJ2_0/1/2/3为高电平时执行该语句后变成低电平电平点亮LED                                               */
	GPJ2.GPJ2DAT ^= 0xf;        
}
//软件延时
void delay(unsigned int z)
{
	unsigned int x,y;
	for(x = z;x > 0;x--)
		for(y = 120;y > 0;y--);
}

s5pv210.h:

寄存器定义

...
...
...
typedef struct 
{
	unsigned int GPD0CON;
	unsigned int GPD0DAT;
	unsigned int GPD0PUD;
	unsigned int GPD0DRV;
	unsigned int GPD0CONPDN;
	unsigned int GPD0PUDPDN;
}gpd0;
#define GPD0 (*(volatile gpd0 *)0xE02000A0)   

typedef struct 
{
	unsigned int GPJ2CON;
	unsigned int GPJ2DAT;
	unsigned int GPJ2PUD;
	unsigned int GPJ2DRV;
	unsigned int GPJ2CONPDN;
	unsigned int GPJ2PUDPDN;
}gpj2;
#define GPJ2 (*(volatile gpj2 *)0XE0200280)  
...
...
...

main.c:

#include "led.h"

int Main(void)
{
	led_init();
	while(1)
	{
		led_on_off();	         //点亮or熄灭LED
		delay(0xfff);              //延时
	}  
}

你可能感兴趣的:(ARM)