Assembly TM4C123GX-为什么不';t 16/32位定时器0A中断工作?
我试图在汇编中编程TM4C123GX启动板,以便使用16/32位定时器0A定期打开外部LED。我按照用户手册(TM4C123GH6PM)中的说明操作,但由于某些原因,它无法工作。我打开了定时器时钟,打开了NVIC中的中断,设置了中断级别,将定时器设置为超时中断,并配置了其他部分。GPIO部分工作正常当我为超时读取RIS位(GPTMRIS中的TATORIS位)时,它总是设置为1,即使在GPTMICR中清除了它。为什么中断不起作用?这是我的代码 启动\u rvmdk.S:Assembly TM4C123GX-为什么不';t 16/32位定时器0A中断工作?,assembly,timer,arm,microcontroller,interrupt,Assembly,Timer,Arm,Microcontroller,Interrupt,我试图在汇编中编程TM4C123GX启动板,以便使用16/32位定时器0A定期打开外部LED。我按照用户手册(TM4C123GH6PM)中的说明操作,但由于某些原因,它无法工作。我打开了定时器时钟,打开了NVIC中的中断,设置了中断级别,将定时器设置为超时中断,并配置了其他部分。GPIO部分工作正常当我为超时读取RIS位(GPTMRIS中的TATORIS位)时,它总是设置为1,即使在GPTMICR中清除了它。为什么中断不起作用?这是我的代码 启动\u rvmdk.S: ;...
;...
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NmiSR ; NMI Handler
;...
DCD IntDefaultHandler ; ADC Sequence 3
DCD IntDefaultHandler ; Watchdog timer
DCD Timer0A_Handler ; Timer 0 subtimer A
DCD IntDefaultHandler ; Timer 0 subtimer B
;...
;I added the Timer0A_Handler here.
Timer0A_Handler PROC
EXPORT Timer0A_Handler
;write "high" to data register for port F pin 1 to turn on red LED. GPIODATA
LDR r0, =AHB_PORTB
LDR r1, =PB5_MASK ;Get RAM address of PB5 mask value
LDR r2,[r1] ;Grab value of PB5 mask
EOR r2, r2, #0xF0 ;Toggle mas to toggle PB5
STR r2,[r1] ;Store the toggled mask to properly toggle next time
STR r2,[r0,#GPIODATAPB5]
;LDR r2,[r0,#GPIODATAPB5]
;Clear RIS bit
LDR r0, =NVIC_BASE
LDR r1,[r0, #GPTMICR]
BFC r1,#0,#1
ORR r1,r1,#1
STR r1,[r0, #GPTMICR]
;return to __main
BX LR
ENDP
;...
my_Constants.S:
AREA My_Constants, CODE, READONLY
THUMB
;defining addresses here for practice
;general base addresses
AHB_PORTB EQU 0x40059000
SYS_CONTROL EQU 0x400FE000
NVIC_BASE EQU 0xE0000000
SYS_PERIPH EQU 0xE000E000
TIMER16_0 EQU 0x40030000
;offsets
;RCGC Run-time offsets
RCGCGPIO EQU 0x608
RCGCTIMER EQU 0x604
;GPIO offsets
GPIOHBCTL EQU 0x06C
GPIOCTL EQU 0x52C
GPIODIR EQU 0X400
GPIOAFSEL EQU 0X420
GPIODR2R EQU 0X500
GPIOPUR EQU 0X510
GPIODEN EQU 0X51C
GPIODATAPB5 EQU 0x3FC;0X080
;SysTick offsets
STCTRL EQU 0X010
STRELOAD EQU 0X014
STCURRENT EQU 0X018
SYSPRI3 EQU 0XD20
;NVIC offsets
NVIC_ENn EQU 0x100
NVIC_DISn EQU 0x180
NVIC_PRIn EQU 0x440
;Timer offsets
GPTMCTL EQU 0x00C
GPTMCFG EQU 0x000
GPTMTAMR EQU 0x004
GPTMTBMR EQU 0x008
GPTMTAILR EQU 0x028
GPTMTBILR EQU 0x02C
GPTMTAPR EQU 0x038
GPTMTBPR EQU 0x03C
GPTMIMR EQU 0x018
GPTMRIS EQU 0x01C
GPTMICR EQU 0x024
END
my_Variables.S:
AREA My_Variables, DATA, READWRITE
THUMB
EXPORT PB5_MASK
PB5_MASK DCD 240;0x000000F0
END
主要议题:
;Include constants I define to main
INCLUDE my_Constants.s
IMPORT PB5_MASK
AREA |.text|, CODE, READONLY
THUMB
EXPORT __main
ENTRY
;Input arguments:
; r0: IRQn
; r1: 1 = Enable, 0 = Disable
NVIC_Init PROC
PUSH {r4, LR} ;Push context onto stack
AND r2, r0, #0x1F ;Bitoffset
MOV r3, #1
LSL r3, r3, r2 ;Shift enable/disable bit to correct bit position
LDR r4, =NVIC_BASE ;NVIC base address
CMP r1, #0 ;Want to enable to disable?
LDRNE r1, =NVIC_ENn
LDREQ r1, =NVIC_DISn
ADD r1, r4, r1 ;add offset to base address
LSR r2, r0, #5 ;find register number n. IRQn/32
LSL r2, r2, #2 ;Wordoffset with 0 extend. Finds register n address
STR r3, [r1, r2]
POP {r4,LR}
BX LR
ENDP
;Input Arguments:
; r0: IRQn
; r1: Priority level 0~7
NVIC_Priority PROC
PUSH {r4, LR} ;Push context onto stack
AND r2, r0, #0x03 ;Bitoffset for TBB (case index)
LDR r3, =NVIC_BASE
LDR r4, =NVIC_PRIn
ADD r3, r3, r4
LSR r4, r0, #2 ;
LSL r4, r4, #2
TBB [PC, r2]
BranchTable
DCB (Case_0 - BranchTable)/2 ;index 0: Case_0
DCB (Case_0 - BranchTable)/2 ;index 1: Case_1
DCB (Case_0 - BranchTable)/2 ;index 2: Case_2
DCB (Case_0 - BranchTable)/2 ;index 3: Case_3
ALIGN
Case_0
LSL r1, r1, #5 ;Shift to [7:5]
B exit
Case_1
LSL r1, r1, #13 ;Shift to [15:13]
B exit
Case_2
LSL r1, r1, #21 ;Shift to [23:21]
B exit
Case_3
LSL r1, r1, #29 ;Shift to [31:29]
B exit
exit
STR r1, [r3, r4]
POP {r4,LR}
BX LR
ENDP
GPIO_Init PROC
;Save context
PUSH {LR}
;select APB. GPIOHBCTL
LDR r0, =SYS_CONTROL
LDR r1,[r0, #GPIOHBCTL]
ORR r1, r1, #(1<<1) ;Enable port B AHB instead. "Note that GPIO can only be accessed through the AHB aperture
STR r1,[r0, #GPIOHBCTL]
;set to output. GPIODIR
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODIR]
ORR r1, r1, #(1<<5);pin5
STR r1,[r0,#GPIODIR]
;set mode to GPIO (nor alternate function). GPIOAFSEL
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIOAFSEL]
BFC r1,#0,#8 ;clears fields. 0 = GPIO
STR r1,[r0,#GPIOAFSEL]
;to drive strength to 2mA. GPIODR2R
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODR2R]
ORR r1, r1, #(1<<5);pin5
STR r1,[r0,#GPIODR2R]
;set to pull up. GPIOPUR
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIOPUR]
ORR r1, r1, #(1<<5) ;pin5
STR r1,[r0,#GPIOPUR]
;enable digital output. GPIODEN
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODEN]
ORR r1,r1, #(1<<5);pin 1 = digital output enable
STR r1,[r0,#GPIODEN]
;write "high" to data register for port B pin 5 to turn on red LED. GPIODATA
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODATAPB5]
LDR r2, =PB5_MASK ;get RAM address of PB5 mask (pointer)
LDR r3,[r2] ;get the value of PB5 mask
ORR r1, r1, r3 ;Set PB5 to 'high'
STR r1,[r0,#GPIODATAPB5]
;Restore context
POP {LR}
BX LR
ENDP
;Initializes RCGC for GPIO and Timer0 at run-time
RCGC_Init PROC
;Save context
PUSH {LR}
;Initialize Timer0 for run-time via RCGC
LDR r0, =SYS_CONTROL
LDR r1,[r0, #RCGCTIMER]
BFC r1,#0,#6 ;clear fields [5:0]
ORR r1, r1, #1 ;R0 = 1: enable Timer0
STR r1,[r0, #RCGCTIMER]
;Initialize GPIO PortB for run-time via RCGC
;Enable clock. RCGCGPIO
LDR r0, =SYS_CONTROL
LDR r1,[r0,#RCGCGPIO]
ORR r1, r1, #(1<<1) ;enable port B clock(bit 5)
STR r1,[r0,#RCGCGPIO]
;Restore context
POP {LR}
BX LR
ENDP
;Specifically for Timer0. Generalize this function
TIMER_Init PROC
;Save context
PUSH {LR}
;Disable Timer0A
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#0,#1 ;clear TAEN to disable Timer0A
STR r2,[r1, #GPTMCTL]
;Seperate timers A & B for 16 bit timers
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCFG]
BFC r2,#0,#2 ;Clear bits
ORR r2, r2, #0x4 ;Seperate timers
STR r2,[r1, #GPTMCFG]
;Set timer mode to periodic
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAMR]
BFC r2,#7,#1 ;No snapshot mode
BFC r2,#5,#1 ;Disable interrupts when counter == CCR
;ORR r2,r2,#(1<<5);Enable interrupts when counter == CCR
BFC r2,#4,#1 ;count down
BFC r2,#0,#2
ORR r2, r2,#(0x02);Set periodic mode
STR r2,[r1, #GPTMTAMR]
;Set ARR value
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAILR]
BFC r2,#0,#32 ;
MOV r2,#0x3E42
STR r2,[r1, #GPTMTAILR]
;Set Prescale value
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAPR]
BFC r2,#0,#8
ORR r2,r2,#0xFF
STR r2,[r1, #GPTMTAPR]
;Set interrupts at timeout
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMIMR]
BFC r2,#0,#1
ORR r2,r2,#1;Enable interrupts at timeout
STR r2,[r1, #GPTMIMR]
;Prevents Timer0A from freezing during debug
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#9,#1
ORR r2,r2,#(1<<9) ;Set TASTAL to 1 to prevent stopping during debug
BFC r2,#4,#1
ORR r2,r2,#(1<<4) ;Set RCTEN to 1 to prevent stopping during debug
STR r2,[r1, #GPTMCTL]
;Enable Timer0A
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#0,#1
ORR r2,r2,#1 ;Set TAEN to enable Timer0A
STR r2,[r1, #GPTMCTL]
;Restore context
POP {LR}
BX LR
ENDP
__main PROC
;Setup clocks for GPIO and GPTM at run-time
BL RCGC_Init
;Setup GPIO first
BL GPIO_Init
;Enable Timer0A interrupt
MOV r0, #19; Timer0A is IRQn = 19
MOV r1, #1; r1 = 1: Enable
BL NVIC_Init
;Setup priority level for Timer0A
MOV r0, #19; Timer0A is IRQn = 19
MOV r1, #1 ;priority #1
BL NVIC_Priority
;Setup Timer0A
BL TIMER_Init
while
;Read interrupt bit to see if it's working...
LDR r1, =NVIC_BASE
LDR r2,[r1, #GPTMRIS]
BFC r2,#1,#31 ;shows only TATORIS bit in r2. If 1 = interrupt. If 0 = no interrupt
;Clear RIS bit
LDR r0, =NVIC_BASE
LDR r1,[r0, #GPTMICR]
BFC r1,#0,#1
ORR r1,r1,#1
STR r1,[r0, #GPTMICR]
B while
ENDP
END
;包括我定义到main的常量
包括我的_常量
导入PB5_掩码
区域|。文本|,代码,只读
拇指
导出主
进入
;输入参数:
; r0:IRQn
; r1:1=启用,0=禁用
NVIC_初始化程序
推动{r4,LR};将上下文推送到堆栈上
r2,r0,#0x1F;位偏移
MOV r3#1
LSL r3,r3,r2;将启用/禁用位移到正确的位位置
LDR r4=NVIC_基地;NVIC基址
CMP r1#0;要启用或禁用?
LDRNE r1,=NVIC_ENn
LDREQ r1,=NVIC\U DISn
加上r1、r4、r1;向基址添加偏移量
LSR r2,r0,#5;查找寄存器号。IRQn/32
LSL r2,r2,#2;扩展为0的字偏移量。查找寄存器n地址
STR r3[r1,r2]
POP{r4,LR}
BX-LR
ENDP
;输入参数:
; r0:IRQn
; r1:优先级0~7
NVIC_优先程序
推动{r4,LR};将上下文推送到堆栈上
r2,r0,#0x03;TBB的位偏移量(大小写索引)
LDR r3,=NVIC_基地
LDR r4,=NVIC\u PRIn
加上r3,r3,r4
LSR r4,r0,#2;
LSL r4,r4,#2
TBB[PC,r2]
分支
DCB(案例0-分支表)/2;索引0:案例0
DCB(案例0-分支表)/2;索引1:案例1
DCB(案例0-分支表)/2;索引2:案例2
DCB(案例0-分支表)/2;索引3:案例3
排列
案例0
LSL r1,r1,#5;切换到[7:5]
B出口
案例1
LSL r1,r1,#13;切换到[15:13]
B出口
案例2
LSL r1,r1,#21;切换到[23:21]
B出口
案例3
LSL r1,r1,#29;切换到[31:29]
B出口
出口
STR r1[r3,r4]
POP{r4,LR}
BX-LR
ENDP
GPIO_初始化程序
;保存上下文
推送{LR}
;选择APB。GPIOHBCTL
LDR r0,=系统控制
LDR r1,[r0,#GPIOHBCTL]
ORR r1,r1,#(1所以我找到了解决方案。我在使用NVIC的基址时犯了一个错误(两次)。分支表也错了,GPTMICR的基址也错了。下面是更正
my_Constants.S:
AREA My_Constants, CODE, READONLY
THUMB
;defining addresses here for practice
;general base addresses
AHB_PORTB EQU 0x40059000
SYS_CONTROL EQU 0x400FE000
NVIC_BASE EQU 0xE0000000
SYS_PERIPH EQU 0xE000E000
TIMER16_0 EQU 0x40030000
;offsets
;RCGC Run-time offsets
RCGCGPIO EQU 0x608
RCGCTIMER EQU 0x604
;GPIO offsets
GPIOHBCTL EQU 0x06C
GPIOCTL EQU 0x52C
GPIODIR EQU 0X400
GPIOAFSEL EQU 0X420
GPIODR2R EQU 0X500
GPIOPUR EQU 0X510
GPIODEN EQU 0X51C
GPIODATAPB5 EQU 0x3FC;0X080
;SysTick offsets
STCTRL EQU 0X010
STRELOAD EQU 0X014
STCURRENT EQU 0X018
SYSPRI3 EQU 0XD20
;NVIC offsets
NVIC_ENn EQU 0x100
NVIC_DISn EQU 0x180
NVIC_PRIn EQU 0x440
;Timer offsets
GPTMCTL EQU 0x00C
GPTMCFG EQU 0x000
GPTMTAMR EQU 0x004
GPTMTBMR EQU 0x008
GPTMTAILR EQU 0x028
GPTMTBILR EQU 0x02C
GPTMTAPR EQU 0x038
GPTMTBPR EQU 0x03C
GPTMIMR EQU 0x018
GPTMRIS EQU 0x01C
GPTMICR EQU 0x024
END
NVIC_基本设备0xE0000000
启动\u rvmdk.S:
;...
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NmiSR ; NMI Handler
;...
DCD IntDefaultHandler ; ADC Sequence 3
DCD IntDefaultHandler ; Watchdog timer
DCD Timer0A_Handler ; Timer 0 subtimer A
DCD IntDefaultHandler ; Timer 0 subtimer B
;...
;I added the Timer0A_Handler here.
Timer0A_Handler PROC
EXPORT Timer0A_Handler
;write "high" to data register for port F pin 1 to turn on red LED. GPIODATA
LDR r0, =AHB_PORTB
LDR r1, =PB5_MASK ;Get RAM address of PB5 mask value
LDR r2,[r1] ;Grab value of PB5 mask
EOR r2, r2, #0xF0 ;Toggle mas to toggle PB5
STR r2,[r1] ;Store the toggled mask to properly toggle next time
STR r2,[r0,#GPIODATAPB5]
;LDR r2,[r0,#GPIODATAPB5]
;Clear RIS bit
LDR r0, =NVIC_BASE
LDR r1,[r0, #GPTMICR]
BFC r1,#0,#1
ORR r1,r1,#1
STR r1,[r0, #GPTMICR]
;return to __main
BX LR
ENDP
;...
LDR r0,=NVIC_基地
主要议题:
;Include constants I define to main
INCLUDE my_Constants.s
IMPORT PB5_MASK
AREA |.text|, CODE, READONLY
THUMB
EXPORT __main
ENTRY
;Input arguments:
; r0: IRQn
; r1: 1 = Enable, 0 = Disable
NVIC_Init PROC
PUSH {r4, LR} ;Push context onto stack
AND r2, r0, #0x1F ;Bitoffset
MOV r3, #1
LSL r3, r3, r2 ;Shift enable/disable bit to correct bit position
LDR r4, =NVIC_BASE ;NVIC base address
CMP r1, #0 ;Want to enable to disable?
LDRNE r1, =NVIC_ENn
LDREQ r1, =NVIC_DISn
ADD r1, r4, r1 ;add offset to base address
LSR r2, r0, #5 ;find register number n. IRQn/32
LSL r2, r2, #2 ;Wordoffset with 0 extend. Finds register n address
STR r3, [r1, r2]
POP {r4,LR}
BX LR
ENDP
;Input Arguments:
; r0: IRQn
; r1: Priority level 0~7
NVIC_Priority PROC
PUSH {r4, LR} ;Push context onto stack
AND r2, r0, #0x03 ;Bitoffset for TBB (case index)
LDR r3, =NVIC_BASE
LDR r4, =NVIC_PRIn
ADD r3, r3, r4
LSR r4, r0, #2 ;
LSL r4, r4, #2
TBB [PC, r2]
BranchTable
DCB (Case_0 - BranchTable)/2 ;index 0: Case_0
DCB (Case_0 - BranchTable)/2 ;index 1: Case_1
DCB (Case_0 - BranchTable)/2 ;index 2: Case_2
DCB (Case_0 - BranchTable)/2 ;index 3: Case_3
ALIGN
Case_0
LSL r1, r1, #5 ;Shift to [7:5]
B exit
Case_1
LSL r1, r1, #13 ;Shift to [15:13]
B exit
Case_2
LSL r1, r1, #21 ;Shift to [23:21]
B exit
Case_3
LSL r1, r1, #29 ;Shift to [31:29]
B exit
exit
STR r1, [r3, r4]
POP {r4,LR}
BX LR
ENDP
GPIO_Init PROC
;Save context
PUSH {LR}
;select APB. GPIOHBCTL
LDR r0, =SYS_CONTROL
LDR r1,[r0, #GPIOHBCTL]
ORR r1, r1, #(1<<1) ;Enable port B AHB instead. "Note that GPIO can only be accessed through the AHB aperture
STR r1,[r0, #GPIOHBCTL]
;set to output. GPIODIR
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODIR]
ORR r1, r1, #(1<<5);pin5
STR r1,[r0,#GPIODIR]
;set mode to GPIO (nor alternate function). GPIOAFSEL
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIOAFSEL]
BFC r1,#0,#8 ;clears fields. 0 = GPIO
STR r1,[r0,#GPIOAFSEL]
;to drive strength to 2mA. GPIODR2R
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODR2R]
ORR r1, r1, #(1<<5);pin5
STR r1,[r0,#GPIODR2R]
;set to pull up. GPIOPUR
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIOPUR]
ORR r1, r1, #(1<<5) ;pin5
STR r1,[r0,#GPIOPUR]
;enable digital output. GPIODEN
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODEN]
ORR r1,r1, #(1<<5);pin 1 = digital output enable
STR r1,[r0,#GPIODEN]
;write "high" to data register for port B pin 5 to turn on red LED. GPIODATA
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODATAPB5]
LDR r2, =PB5_MASK ;get RAM address of PB5 mask (pointer)
LDR r3,[r2] ;get the value of PB5 mask
ORR r1, r1, r3 ;Set PB5 to 'high'
STR r1,[r0,#GPIODATAPB5]
;Restore context
POP {LR}
BX LR
ENDP
;Initializes RCGC for GPIO and Timer0 at run-time
RCGC_Init PROC
;Save context
PUSH {LR}
;Initialize Timer0 for run-time via RCGC
LDR r0, =SYS_CONTROL
LDR r1,[r0, #RCGCTIMER]
BFC r1,#0,#6 ;clear fields [5:0]
ORR r1, r1, #1 ;R0 = 1: enable Timer0
STR r1,[r0, #RCGCTIMER]
;Initialize GPIO PortB for run-time via RCGC
;Enable clock. RCGCGPIO
LDR r0, =SYS_CONTROL
LDR r1,[r0,#RCGCGPIO]
ORR r1, r1, #(1<<1) ;enable port B clock(bit 5)
STR r1,[r0,#RCGCGPIO]
;Restore context
POP {LR}
BX LR
ENDP
;Specifically for Timer0. Generalize this function
TIMER_Init PROC
;Save context
PUSH {LR}
;Disable Timer0A
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#0,#1 ;clear TAEN to disable Timer0A
STR r2,[r1, #GPTMCTL]
;Seperate timers A & B for 16 bit timers
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCFG]
BFC r2,#0,#2 ;Clear bits
ORR r2, r2, #0x4 ;Seperate timers
STR r2,[r1, #GPTMCFG]
;Set timer mode to periodic
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAMR]
BFC r2,#7,#1 ;No snapshot mode
BFC r2,#5,#1 ;Disable interrupts when counter == CCR
;ORR r2,r2,#(1<<5);Enable interrupts when counter == CCR
BFC r2,#4,#1 ;count down
BFC r2,#0,#2
ORR r2, r2,#(0x02);Set periodic mode
STR r2,[r1, #GPTMTAMR]
;Set ARR value
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAILR]
BFC r2,#0,#32 ;
MOV r2,#0x3E42
STR r2,[r1, #GPTMTAILR]
;Set Prescale value
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAPR]
BFC r2,#0,#8
ORR r2,r2,#0xFF
STR r2,[r1, #GPTMTAPR]
;Set interrupts at timeout
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMIMR]
BFC r2,#0,#1
ORR r2,r2,#1;Enable interrupts at timeout
STR r2,[r1, #GPTMIMR]
;Prevents Timer0A from freezing during debug
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#9,#1
ORR r2,r2,#(1<<9) ;Set TASTAL to 1 to prevent stopping during debug
BFC r2,#4,#1
ORR r2,r2,#(1<<4) ;Set RCTEN to 1 to prevent stopping during debug
STR r2,[r1, #GPTMCTL]
;Enable Timer0A
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#0,#1
ORR r2,r2,#1 ;Set TAEN to enable Timer0A
STR r2,[r1, #GPTMCTL]
;Restore context
POP {LR}
BX LR
ENDP
__main PROC
;Setup clocks for GPIO and GPTM at run-time
BL RCGC_Init
;Setup GPIO first
BL GPIO_Init
;Enable Timer0A interrupt
MOV r0, #19; Timer0A is IRQn = 19
MOV r1, #1; r1 = 1: Enable
BL NVIC_Init
;Setup priority level for Timer0A
MOV r0, #19; Timer0A is IRQn = 19
MOV r1, #1 ;priority #1
BL NVIC_Priority
;Setup Timer0A
BL TIMER_Init
while
;Read interrupt bit to see if it's working...
LDR r1, =NVIC_BASE
LDR r2,[r1, #GPTMRIS]
BFC r2,#1,#31 ;shows only TATORIS bit in r2. If 1 = interrupt. If 0 = no interrupt
;Clear RIS bit
LDR r0, =NVIC_BASE
LDR r1,[r0, #GPTMICR]
BFC r1,#0,#1
ORR r1,r1,#1
STR r1,[r0, #GPTMICR]
B while
ENDP
END
分支
DCB (Case_0 - BranchTable)/2 ;index 0: Case_0
DCB (Case_1 - BranchTable)/2 ;Case_0->Case_1
DCB (Case_2 - BranchTable)/2 ;Case_0->Case_2
DCB (Case_3 - BranchTable)/2 ;Case_0->Case_3
ALIGN
用SYS_PERIPH替换NVIC_BASE的每个实例。因此我找到了解决方案。我在使用NVIC的基址时犯了一个错误(两次)。分支表也错误,GPTMICR的基址也错误。以下是更正
my_Constants.S:
AREA My_Constants, CODE, READONLY
THUMB
;defining addresses here for practice
;general base addresses
AHB_PORTB EQU 0x40059000
SYS_CONTROL EQU 0x400FE000
NVIC_BASE EQU 0xE0000000
SYS_PERIPH EQU 0xE000E000
TIMER16_0 EQU 0x40030000
;offsets
;RCGC Run-time offsets
RCGCGPIO EQU 0x608
RCGCTIMER EQU 0x604
;GPIO offsets
GPIOHBCTL EQU 0x06C
GPIOCTL EQU 0x52C
GPIODIR EQU 0X400
GPIOAFSEL EQU 0X420
GPIODR2R EQU 0X500
GPIOPUR EQU 0X510
GPIODEN EQU 0X51C
GPIODATAPB5 EQU 0x3FC;0X080
;SysTick offsets
STCTRL EQU 0X010
STRELOAD EQU 0X014
STCURRENT EQU 0X018
SYSPRI3 EQU 0XD20
;NVIC offsets
NVIC_ENn EQU 0x100
NVIC_DISn EQU 0x180
NVIC_PRIn EQU 0x440
;Timer offsets
GPTMCTL EQU 0x00C
GPTMCFG EQU 0x000
GPTMTAMR EQU 0x004
GPTMTBMR EQU 0x008
GPTMTAILR EQU 0x028
GPTMTBILR EQU 0x02C
GPTMTAPR EQU 0x038
GPTMTBPR EQU 0x03C
GPTMIMR EQU 0x018
GPTMRIS EQU 0x01C
GPTMICR EQU 0x024
END
NVIC_基本设备0xE0000000
启动\u rvmdk.S:
;...
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NmiSR ; NMI Handler
;...
DCD IntDefaultHandler ; ADC Sequence 3
DCD IntDefaultHandler ; Watchdog timer
DCD Timer0A_Handler ; Timer 0 subtimer A
DCD IntDefaultHandler ; Timer 0 subtimer B
;...
;I added the Timer0A_Handler here.
Timer0A_Handler PROC
EXPORT Timer0A_Handler
;write "high" to data register for port F pin 1 to turn on red LED. GPIODATA
LDR r0, =AHB_PORTB
LDR r1, =PB5_MASK ;Get RAM address of PB5 mask value
LDR r2,[r1] ;Grab value of PB5 mask
EOR r2, r2, #0xF0 ;Toggle mas to toggle PB5
STR r2,[r1] ;Store the toggled mask to properly toggle next time
STR r2,[r0,#GPIODATAPB5]
;LDR r2,[r0,#GPIODATAPB5]
;Clear RIS bit
LDR r0, =NVIC_BASE
LDR r1,[r0, #GPTMICR]
BFC r1,#0,#1
ORR r1,r1,#1
STR r1,[r0, #GPTMICR]
;return to __main
BX LR
ENDP
;...
LDR r0,=NVIC_基地
主要议题:
;Include constants I define to main
INCLUDE my_Constants.s
IMPORT PB5_MASK
AREA |.text|, CODE, READONLY
THUMB
EXPORT __main
ENTRY
;Input arguments:
; r0: IRQn
; r1: 1 = Enable, 0 = Disable
NVIC_Init PROC
PUSH {r4, LR} ;Push context onto stack
AND r2, r0, #0x1F ;Bitoffset
MOV r3, #1
LSL r3, r3, r2 ;Shift enable/disable bit to correct bit position
LDR r4, =NVIC_BASE ;NVIC base address
CMP r1, #0 ;Want to enable to disable?
LDRNE r1, =NVIC_ENn
LDREQ r1, =NVIC_DISn
ADD r1, r4, r1 ;add offset to base address
LSR r2, r0, #5 ;find register number n. IRQn/32
LSL r2, r2, #2 ;Wordoffset with 0 extend. Finds register n address
STR r3, [r1, r2]
POP {r4,LR}
BX LR
ENDP
;Input Arguments:
; r0: IRQn
; r1: Priority level 0~7
NVIC_Priority PROC
PUSH {r4, LR} ;Push context onto stack
AND r2, r0, #0x03 ;Bitoffset for TBB (case index)
LDR r3, =NVIC_BASE
LDR r4, =NVIC_PRIn
ADD r3, r3, r4
LSR r4, r0, #2 ;
LSL r4, r4, #2
TBB [PC, r2]
BranchTable
DCB (Case_0 - BranchTable)/2 ;index 0: Case_0
DCB (Case_0 - BranchTable)/2 ;index 1: Case_1
DCB (Case_0 - BranchTable)/2 ;index 2: Case_2
DCB (Case_0 - BranchTable)/2 ;index 3: Case_3
ALIGN
Case_0
LSL r1, r1, #5 ;Shift to [7:5]
B exit
Case_1
LSL r1, r1, #13 ;Shift to [15:13]
B exit
Case_2
LSL r1, r1, #21 ;Shift to [23:21]
B exit
Case_3
LSL r1, r1, #29 ;Shift to [31:29]
B exit
exit
STR r1, [r3, r4]
POP {r4,LR}
BX LR
ENDP
GPIO_Init PROC
;Save context
PUSH {LR}
;select APB. GPIOHBCTL
LDR r0, =SYS_CONTROL
LDR r1,[r0, #GPIOHBCTL]
ORR r1, r1, #(1<<1) ;Enable port B AHB instead. "Note that GPIO can only be accessed through the AHB aperture
STR r1,[r0, #GPIOHBCTL]
;set to output. GPIODIR
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODIR]
ORR r1, r1, #(1<<5);pin5
STR r1,[r0,#GPIODIR]
;set mode to GPIO (nor alternate function). GPIOAFSEL
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIOAFSEL]
BFC r1,#0,#8 ;clears fields. 0 = GPIO
STR r1,[r0,#GPIOAFSEL]
;to drive strength to 2mA. GPIODR2R
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODR2R]
ORR r1, r1, #(1<<5);pin5
STR r1,[r0,#GPIODR2R]
;set to pull up. GPIOPUR
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIOPUR]
ORR r1, r1, #(1<<5) ;pin5
STR r1,[r0,#GPIOPUR]
;enable digital output. GPIODEN
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODEN]
ORR r1,r1, #(1<<5);pin 1 = digital output enable
STR r1,[r0,#GPIODEN]
;write "high" to data register for port B pin 5 to turn on red LED. GPIODATA
LDR r0, =AHB_PORTB
LDR r1,[r0,#GPIODATAPB5]
LDR r2, =PB5_MASK ;get RAM address of PB5 mask (pointer)
LDR r3,[r2] ;get the value of PB5 mask
ORR r1, r1, r3 ;Set PB5 to 'high'
STR r1,[r0,#GPIODATAPB5]
;Restore context
POP {LR}
BX LR
ENDP
;Initializes RCGC for GPIO and Timer0 at run-time
RCGC_Init PROC
;Save context
PUSH {LR}
;Initialize Timer0 for run-time via RCGC
LDR r0, =SYS_CONTROL
LDR r1,[r0, #RCGCTIMER]
BFC r1,#0,#6 ;clear fields [5:0]
ORR r1, r1, #1 ;R0 = 1: enable Timer0
STR r1,[r0, #RCGCTIMER]
;Initialize GPIO PortB for run-time via RCGC
;Enable clock. RCGCGPIO
LDR r0, =SYS_CONTROL
LDR r1,[r0,#RCGCGPIO]
ORR r1, r1, #(1<<1) ;enable port B clock(bit 5)
STR r1,[r0,#RCGCGPIO]
;Restore context
POP {LR}
BX LR
ENDP
;Specifically for Timer0. Generalize this function
TIMER_Init PROC
;Save context
PUSH {LR}
;Disable Timer0A
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#0,#1 ;clear TAEN to disable Timer0A
STR r2,[r1, #GPTMCTL]
;Seperate timers A & B for 16 bit timers
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCFG]
BFC r2,#0,#2 ;Clear bits
ORR r2, r2, #0x4 ;Seperate timers
STR r2,[r1, #GPTMCFG]
;Set timer mode to periodic
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAMR]
BFC r2,#7,#1 ;No snapshot mode
BFC r2,#5,#1 ;Disable interrupts when counter == CCR
;ORR r2,r2,#(1<<5);Enable interrupts when counter == CCR
BFC r2,#4,#1 ;count down
BFC r2,#0,#2
ORR r2, r2,#(0x02);Set periodic mode
STR r2,[r1, #GPTMTAMR]
;Set ARR value
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAILR]
BFC r2,#0,#32 ;
MOV r2,#0x3E42
STR r2,[r1, #GPTMTAILR]
;Set Prescale value
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMTAPR]
BFC r2,#0,#8
ORR r2,r2,#0xFF
STR r2,[r1, #GPTMTAPR]
;Set interrupts at timeout
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMIMR]
BFC r2,#0,#1
ORR r2,r2,#1;Enable interrupts at timeout
STR r2,[r1, #GPTMIMR]
;Prevents Timer0A from freezing during debug
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#9,#1
ORR r2,r2,#(1<<9) ;Set TASTAL to 1 to prevent stopping during debug
BFC r2,#4,#1
ORR r2,r2,#(1<<4) ;Set RCTEN to 1 to prevent stopping during debug
STR r2,[r1, #GPTMCTL]
;Enable Timer0A
LDR r1, =TIMER16_0
LDR r2,[r1, #GPTMCTL]
BFC r2,#0,#1
ORR r2,r2,#1 ;Set TAEN to enable Timer0A
STR r2,[r1, #GPTMCTL]
;Restore context
POP {LR}
BX LR
ENDP
__main PROC
;Setup clocks for GPIO and GPTM at run-time
BL RCGC_Init
;Setup GPIO first
BL GPIO_Init
;Enable Timer0A interrupt
MOV r0, #19; Timer0A is IRQn = 19
MOV r1, #1; r1 = 1: Enable
BL NVIC_Init
;Setup priority level for Timer0A
MOV r0, #19; Timer0A is IRQn = 19
MOV r1, #1 ;priority #1
BL NVIC_Priority
;Setup Timer0A
BL TIMER_Init
while
;Read interrupt bit to see if it's working...
LDR r1, =NVIC_BASE
LDR r2,[r1, #GPTMRIS]
BFC r2,#1,#31 ;shows only TATORIS bit in r2. If 1 = interrupt. If 0 = no interrupt
;Clear RIS bit
LDR r0, =NVIC_BASE
LDR r1,[r0, #GPTMICR]
BFC r1,#0,#1
ORR r1,r1,#1
STR r1,[r0, #GPTMICR]
B while
ENDP
END
分支
DCB (Case_0 - BranchTable)/2 ;index 0: Case_0
DCB (Case_1 - BranchTable)/2 ;Case_0->Case_1
DCB (Case_2 - BranchTable)/2 ;Case_0->Case_2
DCB (Case_3 - BranchTable)/2 ;Case_0->Case_3
ALIGN
用SYS_PERIPH替换NVIC_BASE的每个实例。您是先轮询然后再中断的吗?还是一路潜入?您好,感谢您再次回复!我跳过了轮询,直接进入了中断。它没有进入ISR,所以我试着在while循环中轮询RIS位,以查看发生了什么ng。即使我用GPTMICR清除它,它也总是设置为1。答案应该在答案中,而不是作为问题的一部分。允许自答。你是先从轮询开始,然后再中断?还是你只是一路潜入?你好,谢谢你再次回复!我跳过了轮询,直接进入了中断。它没有进入ISR,所以我试着在_____________________________________________________。