PLP:计时器和按钮中断服务程序 [英] PLP: Timer and Button Interrupt Service Routine

查看:159
本文介绍了PLP:计时器和按钮中断服务程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在弄清楚如何触发定时器中断(每200个周期)和按钮中断时遇到了麻烦.当我按下按钮中断时,似乎要做的只是暂时暂停计数器一秒钟,然后继续计数.然后,无论我在PLP上单击它的频率如何,它都永远不会注册另一个按钮中断.假定按钮中断要做的是将寄存器$ a1设置为1(或非零数字),该寄存器用于复位计数器.假定计时器中断每200个周期使LED闪烁一次,然后在另外200个周期后熄灭,依此类推.已经提供了七段显示代码,因此它的工作只是从0-9到A-F递增,然后从10s重新开始.因此11、12,...,19、1A,1B,...,1F,20等

So I'm having trouble figuring out how to trigger a Timer interrupt (Every 200 cycles) and a button interrupt. When I hit the button interrupt all it seems to do is temporarily pause the counter for a split second and then continue counting. Then it never registers another button interrupt no matter how often I click it on PLP. What the button interrupt is suppose to do is set the register $a1 to 1 (or a non zero number) which is suppose to reset the counter. The Timer interrupt is suppose to flash the LEDs on every 200 cycles and then off after another 200 cycles and so forth. The seven segment display code is already provided for so what it does is just count up from 0-9 then A-F, and then starts over with the 10s. So 11, 12, ... , 19, 1A, 1B, ... , 1F, 20, etc.

.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

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

推荐答案

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

The timer triggers when overflow occurs. It is 32 bit timer so when you go past value 0xffff ffff your isr will be called.

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

The way to do it for 0xC8 cycles is

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

这篇关于PLP:计时器和按钮中断服务程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆