mini2440 裸机编程 -键盘中断

来源:互联网 发布:plc编程软件通用版 编辑:程序博客网 时间:2024/04/29 21:33

 前面一篇文章讲了用时钟中断控制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_loopHandleIRQ:        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






原创粉丝点击