按键中断,点亮LED实验

硬件:mini2440开发板

编译环境:ads

烧写到nand flash

 

1,  按键

本开发板总共有 6 个用户测试用按键,它们均从 CPU 中断引脚直接引出,属于低电

平触发,这些引脚也可以复用为 GPIO 和特殊功能口,为了用户把它们引出作为其他用途,

6 个引脚也通过 CON12 引出,6个按键和CON12 的定义如下

 

K1

K2

K3

K4

K5

K6

对应中断

EINT8

EINT11

EIN13

EINT14

EINT15

EINT19

GPIO

GPG0

GPG3

GPG5

GPG6

GPG7

GPG11

GPGCON_BIT

[1:0]

 

 

 

 

 

 

00 = Input                01 = Output

10 = EINT[x]            11 = Reserved

GPGCON      0x56000060

GPGDAT       0x56000064

GPGUP         0x56000068

;************************************************************************** ; FILE: head.S ; 功能: 初始化,设置中断模式,系统模式的栈,设置好中断处理函数 ;************************************************************************** IMPORT Main IMPORT disable_watch_dog IMPORT init_led IMPORT init_irq IMPORT EINT_Handle AREA init, CODE, READONLY ENTRY _start b Reset ;0x00:复位 HandleUndef b HandleUndef ;0x04 HandleSWI b HandleSWI ;0x08 HandlePrefetchAbort b HandlePrefetchAbort ;0x0c HandleDataAbort b HandleDataAbort ;0x10 HandleNotUsed b HandleNotUsed ;0x14 b HandleIRQ ;0x18:中断模式的向量地址 HandleFIQ b HandleFIQ ;0x1c ;以上是中断向量表,中断发生后,pc指针会强制指向相应的中断向量地址 Reset ldr sp, =4*1024 ;设置栈指针 bl disable_watch_dog msr cpsr_c, #0xd2 ;进入中断模式[7:0]=10110010 ldr sp, =3072 ;设置中断模式的栈指针 msr cpsr_c, #0xdf ;进入系统模式 ldr sp, =4096 ;复位之后,CPU处于系统模式 bl init_led ;初始化LED的GPIO管脚 bl init_irq ;调用中断初始化函数,在init.c中 msr cpsr_c, #0x5f ;设置I-bit=0,开IRQ中断 ldr lr, =halt_loop ;设置返回地址 ldr pc, =Main ;调用main函数; halt_loop b halt_loop HandleIRQ sub lr, lr, #4 ;计算返回地址 stmdb sp!, {r0-r12,lr} ;保存使用的寄存器 ldr lr, =int_return ;设置ISR即EINT_Handle函数返回后的地址 ldr pc, =EINT_Handle ;调用中断服务函数,再intterupt.c int_return ldmia sp!, {r0-r12,pc}^ ;中断返回,^表示spsr的值复制到cpsr end /************************************************************************** * FILE:init.c * 初始化GPIO引脚为外部中断PIO引脚作为外部中断时,默认为低电平触发 * 设置外部中断屏蔽寄存器,不屏蔽4个按键的 ***************************************************************************/ #include "s3c24xx.h" /* 定义一些寄存器的宏 */ /* * LED1-4分别对应GPB5、GPB6、GPB7、GPB8 */ #define GPB5_out (1<<(5*2)) // LED1 #define GPB6_out (1<<(6*2)) // LED2 #define GPB7_out (1<<(7*2)) // LED3 #define GPB8_out (1<<(8*2)) // LED4 /* k1-k4 设置中断 */ #define GPG0_eint (2<<2*0) //k1,EINT8 #define GPG3_eint (2<<2*3) //k2,EINT11 #define GPG5_eint (2<<2*5) //k3,EINT13 #define GPG6_eint (2<<2*6) //k4,EINT14 /* * ClOSE WATCHDOG */ void disable_watch_dog(void) { WTCON = 0x00; } void init_led(void) { GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ; GPBDAT = 0xffff; } void init_irq() { /* 初始化 input 状态 */ GPGCON = GPG0_eint| GPG3_eint| GPG5_eint | GPG6_eint; EINTMASK &= (~(1<<8)) & (~(1<<11)) & (~(1<<13)) & (~(1<<14)); /* EINT8_23使能 */ INTMSK &= (~(1<<5)); } /******************************************* * FILE:intrrupt.c * 中断处理函数 ********************************************/ void Delay(unsigned int x) { unsigned int i,j; while(x--) for(i=0;i<0xff;i++) for(j=0;j<0xff;j++); } void EINT_Handle() { unsigned long oft = INTOFFSET; /* 获取哪一位中断 */ unsigned long val; /* 判断哪一个按键中断发生,然后点亮,延迟一会后熄灭 */ val = EINTPEND; if (val & (1<<8)){ GPBDAT &= ~(1<<5); Delay(10); GPBDAT = 0xffff; } else if (val & (1<<11)) { GPBDAT &= ~(1<<6); Delay(10); GPBDAT = 0xffff; } else if (val & (1<<13)){ GPBDAT &= ~(1<<7); Delay(10); GPBDAT = 0xffff; } else if (val & (1<<14)) { GPBDAT &= ~(1<<8); Delay(10); GPBDAT = 0xffff; } /* 清中断 */ EINTPEND = (1<<8) | (1<<11) | (1<<13)| (1<<14); SRCPND = 1<

 

 

 

你可能感兴趣的:(ARM开发,嵌入式)