您的位置:首页 > 其它

ARM裸机——FS2410按键控制LED灯(查询方式)

2012-03-26 23:12 471 查看
一、开发环境

1、硬件平台:FS2410(s3c2410)

2、主机:Ubuntu 10.10

二、硬件的原理图(LED和按键)

1、LED灯的原理图:



2、按键的原理图:



按键的接线资源:

KSCAN0 -> GPE11 KSCAN1 -> GPG6 KSCAN2 -> GPE13 KSCAN3 -> GPG2

EINT0 -> GPF0 EINT2 -> GPF2 EINT11 -> GPG3 EINT19 -> GPG11



三、程序的主要原理:

主要涉及到K1,K2, K3, K4这四个按键,要用查询的方式进行判断哪个键被按下去了,因此将EINT11, EINT19设置为输入,用于读取,将KSCAN0,KSCAN1, KSACAN2,设置为输出,并分别设置为0,1,1或1,0,1或1,1,0这三种情况下,这样可用于区分K1、K2、K3中哪个键按下去,例如先让KSCAN0~2 = 011,那么K1被按下时,EINT19才会变为低电平,这时K2按下时,EINT19不会变低,这样就区分了按键K1和K2,区分其它按键原理一样。



四、寄存器的配置

1、有关LED的寄存器的配置:(设置GPF4-GPF7为输出)



2、按键方面涉及到寄存器配置(设置相关寄存器输入输出):























五、程序的详细代码:

led_key.c:(s3c2410.h头文件可在keil目录下找到,由s3c2440.h重命名得来)

#include "s3c2410.h"

void delay(long long max)      //延迟函数
{
	for(; max > 0; max--);

}

int main(void)
{
	int read_value;

	GPFCON = GPFCON & (~(0xff) << 8) | (0x55 << 8);     //设置4个LED灯为输出(GPF4-GPF7输出)
	GPFDAT |= (0xf << 4);       //先将4个灯都熄灭掉

	GPGCON = (0 << 7) | (1 << 12) | (0 << 23);       //GPG3, GPG11 输入,GPG6, GPE11, GPE13输出
	GPECON =  (1 << 22) | (1 << 26);

	while(1)
	{
		GPEDAT &= (0 << 11);      //将GPE11置0,同时将GPE13和GPG6置1
		GPEDAT |= (1 << 13);
		GPGDAT |= (1 << 6);

		read_value = GPGDAT & 0x808;      //读取GPG11和GPG3的输入值

		if((read_value & 0x800) == 0)       //判断GPG11输入是否为0,以此判断K1键是否按下
		{
			read_value = 0x800;
			delay(200000);        //按键去抖

			if((read_value &= GPGDAT) == 0)
			{
				if((GPFDAT & (1 << 4)) == 0)      //判断D12是否亮着,如果亮着则熄灭,反之相反
					GPFDAT |= (0x1 << 4);
				else
					GPFDAT &= (0xe << 4);
			}
		}
		else
		{
			if((read_value & 0x8) == 0)     //判断GPG3输入的值是否为0, 以此K4键是否按下
			{
				read_value = 0x8;
				delay(200000);        //按键去抖

				if((read_value &= GPGDAT) == 0)
				{
					if((GPFDAT & (0x8 << 4)) == 0)     //判断D9是都亮着,如果亮着则熄灭,反之相反
						GPFDAT |= (0x8 << 4);
					else
						GPFDAT &= (0x7 << 4);
				}
			}
		}

		GPEDAT |= (1 << 11);     //将GPE11和GPE13置1,同时将GPG6置0
 		GPEDAT |= (1 << 13);
		GPGDAT &= (0 << 6);
	
		read_value = GPGDAT & (0x8 << 8);       //读取GPG11的值
						        
		if(read_value == 0)       //判断GPG11是否输入0,以此判断K2键按下
		{   
			read_value = 0x800;  
			delay(200000);       //按键去抖
															           
			if((read_value &= GPGDAT) == 0)
			{  
				if((GPFDAT & (0x2 << 4)) == 0)     //判断D11是否亮着, 如果亮着则熄灭,反之相反
					GPFDAT |= (0x2 << 4);  
				else  
					GPFDAT &= (0xd << 4);  
			}  
		} 

		GPEDAT &= (0 << 13);      //将GPE13置0, 同时将GPE11和GPG6置1
		GPEDAT |= (1 << 11);
		GPGDAT |= (1 << 6);

		read_value = GPGDAT & 0x800;           //读取GPG11的值

		if(read_value == 0)        //判断GPG11是否为0,以此判断K3键是否按下
		{
			read_value = 0x800;
			delay(200000);      //按键去抖,延迟一段时间

			if((read_value &= GPGDAT) == 0)
			{
				if((GPFDAT & (0x4 << 4)) == 0)      //判断D10是否亮着,如果亮着则熄灭,反之相反
					GPFDAT |= (0x4 << 4);
				else
					GPFDAT &= (0xb << 4);
			}
		}
	}

	return 0;
}


Makefile:

led.bin: start.S led_key.c
	arm-none-linux-gnueabi-gcc -c start.S -o start.o
	arm-none-linux-gnueabi-gcc -c led_key.c -o led_key.o
	arm-none-linux-gnueabi-ld -Ttext 0x30008000 start.o led_key.o -o led_key
	arm-none-linux-gnueabi-objcopy -O binary -S led_key led_key.bin

clean:
	rm -f *.o led_key.bin


启动文件start.S:

.text
.global _start
_start:
#define WATCHDOG 0x53000000
	ldr r0, =WATCHDOG
	mov r1, #0
	str r1, [r0]

	ldr sp, =1024*4
	bl main

loop:
	b loop


然后在开发板的uboot上执行以下命令:

tftp 30008000 led_key.bin

go 30008000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: