功能简介:
通过按键来控制4个LED的亮灭状态,在key1按下时,LED1状态取反,key2,key3,key4同理。key5按下则全亮,key6按下则全灭。
1.管脚介绍
1)与key模块相关的原理图如下:
2)LED灯模块相关原理图
3)用以上原理图可得,管脚对应关系及功能如下表:
名称 | 对应管脚 | 管脚功能 | 对应逻辑 |
| 名称 | 对应管脚 | 管脚功能 | 对应逻辑 | |||
KEY1 | GPG0 | 内部上拉输入 | 0:有按下 1:无按下 |
| KEY2 | GPG3 | 内部上拉输入 | 0:有按下 1:无按下 | |||
KEY3 | GPG5 | 内部上拉输入 | 0:有按下 1:无按下 |
| KEY4 | GPG6 | 内部上拉输入 | 0:有按下 1:无按下 | |||
KEY5 | GPG7 | 内部上拉输入 | 0:有按下 1:无按下 |
| KEY6 | GPG11 | 内部上拉输入 | 0:有按下 1:无按下 | |||
LED1 | GPB5 | 内部上拉输出 | 0:灯亮 1:灯灭 |
| LED2 | GPB6 | 内部上拉输出 | 0:灯亮 1:灯灭 | |||
LED3 | GPB7 | 内部上拉输出 | 0:灯亮 1:灯灭 |
| LED4 | GPB8 | 内部上拉输出 | 0:灯亮 1:灯灭 |
2. 相关寄存器及其功能
1)关于LED灯部分:
GPBCON相关Pin:
GPBDAT和GPBUP相关Pin:
2)关于按键部分:
GPGCON相关Pin:
GPGDAT和GPGUP相关Pin:
3.程序流程图:
4.程序设计:
① Makefile
demokey.bin : demokey.Sarm-linux-gcc -g -c -o demokey.o $<
arm-linux-ld -Ttext 0x0000000 -g demokey.o -o demokey_elf
arm-linux-objcopy -O binary -S demokey_elf $@
clean :
rm -f demokey.bin demokey_elf *.o
② demokey.S(其中需要注意arm指令中的立即数必须满足8位位图)
#define GPBCON 0x56000010
#define GPBDAT 0x56000014
#define GPBUP 0x56000018
#define GPGCON 0x56000060
#define GPGDAT 0x56000064
#define GPGUP 0x56000068
#define DELAY_nand 0x1000 /*在nand flash里面用这个延时值*/
;#define DELAY_sdram 0x100000 /*在SDRAM里面用这个*/
.text
.global _start
_start:
/******配置KEY1和KEY6相关管脚为内部上拉输入功能******/
/*把KEY1到KEY6管脚置为输入*/
ldr r0 , =GPGCON
ldr r1 , [r0]
ldr r2 , =(0x3<<22)|(0x3F<<10)|(0x3<<6)|(0x3<<0)
bic r1 , r1 , r2
str r1 , [r0]
/*使能KEY1到KEY6按键的内部上拉输出功能*/
ldr r0 , =GPGUP
ldr r1 , [r0]
ldr r2 , =(0x1<<11)|(0x7<<5)|(0x1<<3)|(0x1<<0)
bic r1 , r1 , r2
str r1 , [r0]
/******配置LED1,2相关管脚为内部上拉输出功能******/
/*把LED1-4管脚置为输出*/
ldr r0 , =GPBCON
ldr r1 , [r0] /*把GPBCON里的内容加载到r1里*/
ldr r2 , =(0xFF<<10)
bic r1 , r1 ,r2 /* 操作数取反码或上r1,用于清零工作*/
ldr r2 , =(0x55<<10)
orr r1 , r1 , r2
str r1 , [r0]
/*使能LED1-4管脚的上拉功能*/
ldr r0 , =GPBUP
ldr r1 , [r0]
ldr r2 , =(0x0F<<5)
bic r1 , r1 ,r2
str r1 , [r0]
/*下面初始化灯为全灭*/
ldr r0 , =GPBDAT
ldr r1 , [r0]
ldr r2 , =(0x0F<<5)
bic r1 , r1 , r2
orr r1 , r1 , r2
str r1 , [r0] /*此时灯全灭*/
/***************下面开始判断是否有按键按下************/
IS_KEY:
ldr r0 , =GPGDAT
ldr r1 , [r0]
ldr r2 , =(0x1<<11)|(0x7<<5)|(0x1<<3)|(0x1<<0)
and r3 , r1 , r2
cmp r2 , r3
beq IS_KEY
bl DELAY /*此处用于消抖延时*/
ldr r1 , [r0]
and r3 , r1 , r2
cmp r2 , r3
beq IS_KEY
/*判断是否为KEY6被按下*/
ldr r2 , =(0x1<<11)
and r2 , r2 , r1
cmp r2 , #0x0
beq IS_KEY6
/*判断是否为KEY5被按下*/
ldr r2 , =(0x1<<7)
and r2 ,r2 ,r1
cmp r2 , #0x0
beq IS_KEY5
/*判断是否为KEY4被按下*/
ldr r2 , =(0x1<<6)
and r2 , r2 , r1
cmp r2 , #0x0
mov r2 , #(0x1<<8)
beq IS_KEY1_4
/*判断是否为KEY3被按下*/
ldr r2 , =(0x1<<5)
and r2 , r2 , r1
cmp r2 , #0x0
mov r2 , #(0x1<<7)
beq IS_KEY1_4
/*判断是否为KEY2被按下*/
ldr r2 , =(0x1<<3)
and r2 , r2 , r1
cmp r2 , #0x0
mov r2 , #(0x1<<6)
beq IS_KEY1_4
/*判断是否为KEY1被按下*/
ldr r2 , =(0x1<<0)
and r2 , r2 , r1
cmp r2 , #0x0
mov r2 , #(0x1<<5)
beq IS_KEY1_4
OTHERS:
b IS_KEY
/****************判断结束***************/
/************按键触发事件**************/
IS_KEY6:/*灯全灭*/
ldr r0 , =GPBDAT
ldr r1 , [r0]
ldr r2 , =(0x0F<<5)
bic r1 , r1 , r2
orr r1 , r1 , r2
str r1 , [r0]
b IS_KEY
IS_KEY5:/*灯全亮*/
ldr r0 , =GPBDAT
ldr r1 , [r0]
ldr r2 , =(0x0F<<5)
bic r1 , r1 , r2
str r1 , [r0]
b IS_KEY
IS_KEY1_4:/*用于KEY1—4按下对应LED灯状态反转*/
ldr r0 , =GPBDAT
ldr r1 , [r0]
and r3 , r1 , r2
cmp r3 , #0x0
beq D1
bic r1 , r1 , r2
str r1 , [r0]
b IS_KEY
D1:
orr r1 , r1 , r2
str r1 , [r0]
b IS_KEY
/********按键触发事件END***********/
/************延时函数***********/
DELAY:
ldr r3 , =DELAY_nand
DELAY1:
sub r3 , r3 , #0x1
cmp r3 , #0x0
bne DELAY1
mov pc , lr
/*************END*************/
注:S3C2440开机启动后默认是开启看门狗的,上面我并没有先关闭看门狗,如果看着它老复位不爽可以加入关闭看门狗的相关代码。