PLP:定时器和按钮中断服务程序

时间:2018-04-02 00:16:36

标签: assembly timer mips interrupt-handling isr

因此,我无法弄清楚如何触发定时器中断(每200个周期)和按钮中断。当我按下按钮中断时,它似乎暂时暂停计数器一瞬间,然后继续计数。然后它永远不会注册另一个按钮中断,无论我在PLP上单击它的频率如何。按钮中断的作用是将寄存器$ a1设置为1(或非零数字),这可能会使计数器复位。定时器中断假设每200个周期闪烁一次LED,然后在另外200个周期后关闭等等。已经提供了七段显示代码,因此它的作用是从0-9然后从A-F开始计数,然后从10s重新开始。所以11,12,......,19,1A,1B,......,1F,20等。

.org 0x10000000
li $sp, 0x10fffffc  # Stack pointer initialization
li $s0, sseg_lut    # Lookup table address used by sseg_display
lui $s1, 0xf070 # Interrupt controller register
lui $s2, 0xf0a0 # Seven segment display


# TODO: enable interrupts here:
# ************************************************************
# Interrupt Initialization
li $t2, 0b1011 #value used to enable the used interrupts
li $t4, 0b00000000 #value used to check if LEDs are off
li $t5, 0b11111111 #value used to check if LEDs are on
li $t6, 0xf0600000 #address of the Timer
li $t7, 0xC8 #number of cycles we want the timer interrupt to be triggered 
sw $t7, 0($t6) #Store value onto timer in order to trigger interrupt????????????????
li $t8, 0xf0200000 #address of LEDs
sw $t2, 0($s1) #set mask register to enable the used interrupts including Global Interrupt Enable 
li $iv, isr #interrupt vector 

# ************************************************************

main:
    jal sseg_display
    nop
    addiu $a0, $a0, 1
    beq $a1, $0, no_counter_reset
        nop
        move $a0, $0
        move $a1, $0
    no_counter_reset:
    j main
    nop


# TODO: add interrupt service routine here:
# ************************************************************
# Interrupt Service Routine

isr: 
    save
    li $t0, 0b0011 #value used to check for timer interrupt
    li $t1, 0b1001 #value used to check for button interrupt
    lw $i0, 0($t8) #check what is stored currently on LEDs
    lw $i1, 4($s1) #load what value is in the status register
    j mainISR
    nop
    mainISR:
        beq $i1, $t0, timerInterrupt #check if the interrupt was triggered by timer
        nop
        beq $i1, $t1, buttonInterrupt #check if interrupt was triggered by button
        nop
        timerInterrupt: 
            beq $t4, $i0, turnOnLEDs #If the LEDs are off, go to the loop to turn them on
            nop
            bne $t4, $i0, turnOffLEDs #If the LEDs are on, go to the loop to turn them off 
            nop
            turnOnLEDs:
                sw $t5, 0($t8) #Stores the value to the LEDs to turn them all on 
                li $i1, 0b1001 #Bits used to clear interrupt in status register 
                j endISR #Jump to the end of the isr 
                nop
            turnOffLEDs:
                sw $t4, 0($t8) #Stores the value to the LEDs to turn them all off 
                li $i1, 0b1001 #Bits used to clear interrup in status register 
                j endISR #Jump to the end of the isr 
                nop
        buttonInterrupt: 
            li $a1, 1 #Set $a1 to 1, per the instructions to reset counter 
            li $i1, 0b0011 #Bits used to clear interrupt in status register 
            j endISR #Jump to end of isr 
            nop
    j mainISR #possibly unnecessary isr loop 
    nop
    endISR:
        sw $i1, 4($s1) #clear handled interrupts
        lw $i1, 0($s1) #get the mask register
        ori $i1, $i1, 1 #set Global Interrupt Enable
        restore
        jr $ir
        sw $i1, 0($s1) #resets all interrupts

# ************************************************************

1 个答案:

答案 0 :(得分:0)

定时器在发生溢出时触发。 它是32位定时器,因此当您超过值0xffff ffff时,将调用isr。

在0xC8周期内执行此操作的方法是

li $t7,0xffff ffff
li $t8,0xC8
subu $t7,$t7,$t8
sw $t7,0($t6)