一、原理图及芯片手册分析
开发板一共有四个按键 s2 s3 s4 s5,我们今天使用s2来进行开发测试。
1.原理图分析
由原理图可以看到,三个EINT0标号相连,按键未按下时,GFP0引脚外接3.3V,为高电平,当按键按下后,与地相连,为低电平。所以我么你可以设置GFP0引脚为输入模式,通过读取GPF0引脚的电平来判断按键是否按下,当为低电平的时候,表示按键按下。
2.分析芯片手册
我们打开芯片手册,找到GPF0引脚如图:
看芯片手册知道我们要设置GPFCON寄存器[1:0]位为00,由于这里默认已经是0,所以不需要改动。然后我们读取GFPDAT寄存器的值,判断第0位,为0代表低电平,这时候按键按下。
二、代码部分
我们写程序实现一个目的:按下S2按键,我们板子上的三个LED灯全部亮,松开之后全部熄灭。程序如下:
start.S文件内容:
.text
.global _start
_start:
/* 这三行是关闭看门狗的代码,这里先不仔细说明了*/
ldr r0, =0x53000000
ldr r1, =0
str r1, [r0]
/* 设置内存: sp 栈 */
/* 分辨是nor/nand启动
* 写0到0地址, 再读出来
* 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动
* 否则就是nor启动
*/
mov r1, #0
ldr r0, [r1] /* 读出原来的值备份 */
str r1, [r1] /* 0->[0] */
ldr r2, [r1] /* r2=[0] */
cmp r1, r2 /* r1==r2? 如果相等表示是NAND启动 */
ldr sp, =0x40000000+4096 /* 先假设是nor启动 */
moveq sp, #4096 /* nand启动 */
streq r0, [r1] /* 恢复原来的值 */
bl main
halt:
b halt
main.c文件内容:
#include "s3c2440_soc.h"
int main(void)
{
int val1;
/*初始化led,设置三个led为输出模式*/
GPFCON &= ~((3<<8) | (3<<10) | (3<<12));
GPFCON |= ((1<<8) | (1<<10) | (1<<12));
/*初始化按键s2,设为输入模式*/
GPFCON &= ~((3<<0);
while(1)
{
val1 = GPFDAT;
if(val1 & (1<<0)) //松开,高电平
{
GPFDAT |= ((1<<6) | (1<<5) | (1<<4));//设置三个led引脚输出高电平,灯灭
}
else
{
GPFDAT &= ~((1<<6) | (1<<5) | (1<<4)); //设置三个led引脚输出低电平,等量
}
}
return 0;
}
makefile文件内容:
all:
arm-linux-gcc -c -o main.o main.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0 start.o main.o -o key_led.elf
arm-linux-objcopy -O binary -S key_led.elf key_led.bin
arm-linux-objdump -D key_led.elf > key_led.dis
clean:
rm *.bin *.o *.elf *.dis
三、编译烧写
编写通过oflash烧写到nand flash中,按键发现灯亮,松开灯灭。如图:
3.1编译过程
3.2烧写过程
观察结果,按下S2后,三个led灯全部点亮,实现实验目标