我正在尝试学习arm汇编程序(在stm32上)并遇到了问题。我在TIM2上配置了定时器中断。 ISR已执行,但是在从加载0的中断程序计数器返回时。我已经调查了中断如何调用并检查了堆栈的主线程寄存器值。在堆栈程序中,计数器值是正确的,但NVIC不接受它。有没有人有想法为什么会如此?
.thumb
.syntax unified
.text
.org 0x00000000
SP: .word STACKINIT
RESET: .word main + 1
NMI_HANDLER: .word nmi_fault + 1
HARD_FAULT: .word hard_fault + 1
MEMORY_FAULT: .word memory_fault + 1
BUS_FAULT: .word bus_fault + 1
USAGE_FAULT: .word usage_fault + 1
.org 0x000000B0
TIMER2_INTERRUPT: .word timer2_interupt + 1
main:
push {lr}
bl cpu_init
pop {lr}
push {lr}
bl sleep_mode_init
pop {lr}
push {lr}
bl timer2_init
pop {lr}
cpsie i
push {lr}
bl timer2_enable
pop {lr}
_main_loop:
b _main_loop
bx lr
@ initialize timer 2 for using
timer2_init:
push {r0, r1}
@ TIM2 timer clock enable
@ load value from RCC_APB1ENR register
ldr r1, =RCC_APB1ENR
ldr r0, [r1]
@ set bit 0 (TIM2 timer clock enable)
orr r0, r0, 0x01
@ store r0 to RCC_APB1ENR
str r0, [r1]
@ load value from TIM2_CR1 register
ldr r1, =TIM2_CR1
ldr r0, [r1]
@ set timer2 Clock division bits (to 00), Auto-reload preload enable bit, Update request source bit and Counter enable bit
ldr r0, =0x8D
str r0, [r1]
@ set timer2 prescaler register
ldr r1, =TIM2_PSC
ldr r0, =0x10000 @ maximum prescaler value
str r0, [r1]
@ set auto-reload value to 1 (The counter is blocked while the auto-reload value is null.)
ldr r1, =TIM2_ARR
ldr r0, =0xFFFF @=0x01
str r0, [r1]
@ clear pending state for TIM2 interrupt
ldr r1, =NVIC_ICPR0
ldr r0, [r1]
orr r0, r0, 0x10000000
str r0, [r1]
@ set timer2 interrupt priority (each priority register contains priority for 4 interrrupts (each priority 8bit long))
ldr r1, =NVIC_IPR7
ldr r0, =0x23000000 @ priority 35 as defined in manuals
str r0, [r1]
@ set 28th bit in NVIC_ISER0 register, this should enable TIM2 interrupt
ldr r1, =NVIC_ISER0
ldr r0, [r1]
orr r0, r0, 0x10000000
str r0, [r1]
pop {r0, r1}
bx lr
@ sets Update interrupt enable bit in TIM2_DIER register
@ function does not take, nor recieve parameters
timer2_enable:
push {r0, r1}
ldr r1, =TIM2_DIER
ldr r0, [r1]
orr r0, r0, 0x01
str r0, [r1]
pop {r0, r1}
bx lr
@ initialize CPU for using
@ function does not take, nor recieve parameters
cpu_init:
push {r0, r1}
@ set RCC_CFGR register to system clock
ldr r1, =RCC_CFGR @ load address of RCC_CFGR registers
ldr r0, =0x5000000 @ high speed (clock) internal selected (HSI)
str r0, [r1] @ store value from r0 to address in r1
pop {r0, r1}
bx lr
@ initialize sleep mode behaviours
sleep_mode_init:
push {r0, r1}
@ set SLEEPONEXIT bit in System Control register (if the SLEEPONEXIT bit is set, the MCU enters Sleep mode as soon as it exits the lowest priority ISR)
@ read SCR register value (system control register)
ldr r1, =SCR
ldr r0, [r1]
@ set SLEEPONEXIT bit (first bit)
orr r0, r0, 0x02
@ store r0 value to SCR register
str r0, [r1]
pop {r0, r1}
bx lr
timer2_interupt:
@ check values in stack
mov r1, 0x18
ldr r0, [sp, r1]
bx lr
nmi_fault:
bkpt
bx lr
hard_fault:
bkpt
bx lr
memory_fault:
bkpt
bx lr
bus_fault:
bkpt
bx lr
usage_fault:
bkpt
bx lr
.end