您的位置:首页 - 汇编语言
ARM汇编示例—按键LED(中断)
这个例子演示了ARM汇编如何去编写一个中断响应程序。

对于外部引脚的中断,需要配置外部引脚为中断模式(EINT)。

之后如果需要配置引脚的触发方式,默认采用低电平触发方式,你还是设置成高电平触发、上升沿触发、下降沿触发、两边沿触发。这些方式的设置在EXTINTn中设置。接着可以设置中断屏蔽位INTMASK。

最后就是编写中断响应程序了。

中断响应程序中的需要固定的设置

;返回地址等于中断地址减4
sub lr, lr, #4
;保存现场
stmdb sp!, {r0-r12,lr}

;这里需要关中断,否则程序一直响应某个中断

;恢复现场
ldmia sp!, {r0-r12,pc}^



下面是我的代码:
GPFCON EQU 0x56000050
GPFDAT EQU 0x56000054
GPGCON EQU 0x56000060
GPGDAT EQU 0x56000064

SRCPND EQU 0X4A000000
INTMSK EQU 0X4A000008
PRIORITY EQU 0x4A00000C
INTPND EQU 0X4A000010
INTOFFSET EQU 0x4A000014
EINTMASK EQU 0x560000a4
EINTPEND EQU 0x560000a8

AREA KEY_LED_INT, CODE, READONLY ;这里表示此区域是只读代码"KEY_LED"
EXPORT _ENTRY ;引入程序入口

_ENTRY

b START ;程序从START开始执行
b . ;0x4
b . ;0x8
b . ;0xc
b . ;0x10
b . ;0x14
b IRQ_HANDLER ;0x00000018中断入口
b . ;0x1c

;程序从这里开始运行
START
ldr sp, =4096 ;初始化当前模式(系统模式)栈指针

msr cpsr_c, #0x92 ;设置当前模式为中断模式
ldr sp, =3072 ;初始化中断模式的栈指针

bl INIT_CONF ;跳转到中断初试化

msr cpsr_c, #0x5f ;定义当前模式为系统模式,并开启中断允许


LOOP
;将LED熄灭
ldr r0, =GPFDAT
mov r1, #0xff
str r1, [r0]
b LOOP

INIT_CONF
;GPIO的配置
;这里包括K1~K4中断配置和LED1~LED4的配置
ldr r0, =GPFCON
ldr r1, =0x55aa
str r1, [r0]

;K5和K6的配置,配置成中断模式
ldr r0, =GPGCON
ldr r1, =0x00800080
str r1, [r0]

;初始化将led都熄灭
ldr r0, =GPFDAT
mov r1, #0xf0
str r1, [r0]

;初始化中断屏蔽位
ldr r0, =INTMSK
ldr r1, = 0xffffffd0
str r1, [r0]

;初始化外中断屏蔽位
ldr r0, =EINTMASK
ldr r1, = 0xf7f7ff ;
str r1, [r0]

;函数返回
mov pc, lr

IRQ_HANDLER
;返回地址等于中断地址减4
sub lr, lr, #4
;保存现场
stmdb sp!, {r0-r12,lr}

;得到offset寄存器的值,它反映了触发中断的中断号
ldr r0, =INTOFFSET
ldr r2, [r0]

;得到LED的状态数据寄存器
ldr r0, =GPFDAT
ldr r1, [r0]

;判断是否触发了INT0,即按键1的中断
cmp r2, #0
;是则重新布置LED状态
moveq r1, #0xef
beq INIT_OVER

;INT1,按键2
cmp r2, #1
moveq r1, #0xdf
beq INIT_OVER

;INT2,按键3
cmp r2, #2
moveq r1, #0xcf
beq INIT_OVER

;INT3, 按键4
cmp r2, #3
moveq r1, #0xbf
beq INIT_OVER

;INT5,它可能是按键5和6发生了中断,按键5和6引脚比较特殊
cmp r2, #5
;如果不是,跳转到结束标志
bne INIT_OVER
;如果是,就看EINTPEND的值,它必定有一个中断被置1
ldr r2, =EINTPEND
ldr r3, [r2]

;如果是11号引脚发生中断,即按键5发生了中断
tst r3, #0x800 ;2^11
movne r1, #0xaf
bne INIT_OVER

; 如果是19号引脚发生中断,即按键6发生了中断
tst r3, #0x80000 ;2^19
movne r1, #0x9f
bne INIT_OVER


INIT_OVER
;更新LED状态
str r1, [r0]

;清除所有中断
ldr r0, =EINTPEND
mov r1, #0xfffffff
str r1, [r0]

ldr r0, =INTPND
mov r1, #0xff
str r1, [r0]

ldr r0, =SRCPND
mov r1, #0xff
str r1, [r0]

;恢复现场
ldmia sp!, {r0-r12,pc}^

END


本程序在ARM920T中运行成功
本站导航
相关文章
柯乐义 Copyright© keleyi.com