[资料分享] Mini2440的外部中断编写

灞波儿奔   2020-1-7 20:08 楼主

一、中断编写总框图

image.png

二、分步介绍

1、初始化引脚

#define GPGCON (*(volatile unsigned long *)0x56000060)

image.png

对照上图将所有引脚设置为【10】变成外部中断功能(以GPG0 GPG3为例)

GPGCON &=  (~(3<<0)) & (~(3<<6));//清除设置位

GPGCON |= (2<<0) | (2<<6);//设置为外部中断功能

2、初始化中断

#define EINTMASK    (*(volatile unsigned long *)0x560000A4)

#define INTMSK         (*(volatile unsigned long *)0x4A000008)

EINTMASK

image.png

EINTMASK &= (~(1<<8))&(~(1<<11));

INTMSK &= (~(1<<EINT8_23));

打开总中断:

/*打开总中断*/
__asm__ volatile(
    "mrs r0, cpsr\n"
    "bic r0, r0,#0x80\n"
    /*只写控制位*/
    "msr cpsr_c, r0\n"
    :
    :
);

3、进入中断

①保存环境

sub lr, lr,#4  /*保证返回时执行的是下一条命令*/
stmfd sp!, {r0-r12, lr}

②中断处理函数

bl handle_int

③恢复环境

ldmfd sp!, {r0-r12, pc}^ /*恢复环境*/

4、中断处理函数

//宏定义

#define EINTPEND    (*(volatile unsigned long *)0x560000A8)

#define SRCPND      (*(volatile unsigned long *)0x4A000000)

#define INTPND         (*(volatile unsigned long *)0x4A000010)

 

//处理函数
//判断中断源
unsigned long value = INTOFFSET;
unsigned long value2 = 0;

//根据中断源执行不同的中断处理
switch(value)
{
    case 5: //EXINT8_23
        value2 = EINTPEND & ((1<<8)|(1<<11));
        switch(value2)
        {
            case (1<<EINT8):  //K1
                led2_on();
                break;
            case (1<<EINT11): //K2
                led2_off();
                break;                
            default:
                break;
        }
        //清除EINT8_23中断标志
        EINTPEND = value2;
        break;
        
    default:
        break;
}

//清除中断标志
SRCPND = 1<<value;
INTPND = 1<<value;

5、注意问题

由于使用中断功能,当程序进入中断时,此时系统处于irq模式下,正常情况系统处于svc模式,而两者的r13是不一样的,所以初始化堆栈时需要分别进行初始化

init_stack:
msr cpsr_c, 0xd2
ldr sp, =0x33000000 @irq模式下初始化的是r13_irq
msr cpsr_c, 0xd3
ldr sp, =0x34000000 @svc模式下初始化的是r13_svc
mov pc, lr

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复