mini2440 裸机编程 -键盘中断

 前面一篇文章讲了用时钟中断控制led灯,这篇文章则重点将用按键控制led灯,内容基本上差不多。

首先看启动部分代码 head.S

@********************************
@file: head.S
@功能:初始化,设置中断模式,系统模式,设置好中断处理函数
@********************************

.extern main
.text
.global _start
_start:
@*******************************
@这段代码只核心写中断向量
@*******************************

        b Reset

@0x04:未定义指令终止模式的向量地址
HandleUndef:
        b        HandleUndef

@定义软中断的向量地址
HandleSWI:
        b        HandleSWI

@定义欲取址中断异常向量地址
HandlePrefectchAbort:
        b        HandlePrefectchAbort

@定义数据中止异常
HandleDataAbort:
        b        HandleDataAbort

@定义保留向量地址
HandleNotUsed:
        b        HandleNotUsed
        
@定义中断的向量地址
        b        HandleIRQ

@定义快中断的向量地址
HandleFIQ:
        b        HandleFIQ

@reset的处理函数
Reset:
        ldr        sp, =4096 			@先设置栈指针,以下都是C语言需要设置栈指针
        bl        disable_watch_dog 		@跳到init.c文件去执行

        msr        cpsr_c, #0xd2 		@进入中断模式
        ldr        sp, =3072 			@中断模式的栈指针定义

        msr        cpsr_c, #0xdf 		@进入系统模式
        ldr        sp, =4096 			@设置系统模式的栈指针

        bl         init_led 			@初始化led,使其均输出状态而且熄灭,在init.c
        bl         init_irq 			@调用init.c中的init_irq函数,初始化中断各个寄存器配置
        msr        cpsr_c, #0x5f @开启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     r0, =0x56000014			@ WATCHDOG¼Ä´æÆ÷µØÖ·
	@ldr     r1, =0xFFDF
        @str   	r1, [r0]    

        ldr        lr, =int_return
        ldr        pc, =EINT_Handle 		@调用中断处理函数

int_return:
        ldmia        sp!, {r0-r12, pc}^

上面调用了函数  init_irq 来初始化按键对应的外部中断 :

void init_irq()
{
        GPGCON = (10) | (10 << 6) | (10 << 10) | (10 << 12); //设置EINT8, 11, 13, 14,reuse GPG0 GPG3 GPG5 GPG6     10D=1010b
        INTMSK &= (~(1 << 5)); //开启总外部中断屏蔽
        EINTMASK &= (~(1 << 8)) &  (~(1 << 11)) & (~(1 << 13)) & (~(1 << 14)); //开启对应的外部中断  EINT8 EINT11 EINT13 EINT14
}

中断处理函数如下:

/*file:interrupt.c*/
#define INTOFFSET (*(unsigned long *)0x4A000014)
#define EINTPEND (*(unsigned long *)0x560000a8)
#define GPBCON (*(unsigned long *)0x56000010)
#define GPBDAT (*(unsigned long *)0x56000014)
#define GPBUP (*(unsigned long *)0x56000018)
#define INTPND (*(unsigned long *)0X4A000010)
#define SRCPND (*(unsigned long *)0X4A000000)


void EINT_Handle()
{
        unsigned long oft = INTOFFSET;
        unsigned long val;

        switch (oft)
        {
                case 5:
                {
                        GPBDAT |= (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);                        
                        //判断到底是哪个按键按下的
                        val = EINTPEND;

                        if (val & (1 << 8)) {
                        //点亮第一个灯        
                                GPBDAT &= ~(1 << 5);
                        } 
                        if (val & (1 << 11)) {
                        //点亮第二个灯        
                                GPBDAT &= ~(1 << 6);
                        }
                        if (val & (1 << 13)) {
                        //点亮第三个灯        
                                GPBDAT &= ~(1 << 7);
                        }
                        if (val & (1 << 14)) {
                        //点亮第四个灯        
                                GPBDAT &= ~(1 << 8);
                        }
                        break;
                }
                default:
                        break;
        }

        //清除中断 
        if (oft == 5) {      // 清外部中断
                EINTPEND = (1 << 8) | (1 << 11) | (1 << 13) | (1 << 14);        
        } 
        SRCPND = 1 << oft;
        INTPND = 1 << oft;
}

加载之后测试发现对应着按键出现led灯的亮灭。

http://s.yunio.com/bYp0Vf






你可能感兴趣的:(mini2440 裸机编程 -键盘中断)