本文介绍了中断IQR和XIRQ-组装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力解决与IRQ(中断本身)有关的话题.我正在使用旧的 MC68HC11

I've been struggling with a topic related to IRQ (interrupts itself); i'm using an old MC68HC11

练习了一段时间;我决定继续学习本章中显示的最困难的练习,这就是为什么我找到了一个有趣的练习(还有一些棘手的问题)

Been practicing for a while; i decided to move on and check the hardest exercises showed in this chapter that's why i found an interesting one (and a little tricky tbh)

看看这个:

这是我到目前为止尝试过的(这只是概述):

FLAGNMI表示XIRQ

FLAGNMI means XIRQ

FLAGIQR表示IRQ

FLAGIQR means IRQ

IRQ                 EQU     $FFF2
XIRQ                EQU     $FFF4
RESET               EQU     $FFFE
RWM                 EQU     $0000
ROM                 EQU     $C000
LEDS                EQU     $1004
VARIABLE            EQU     $1003
MECHANICAL_SEAL     EQU     $0080
CONFIG              EQU     $1039


                    CLR     VALUE
                    CLR     BALANCE
                    CLR     PRICE_SODA
                    TPA
                    ANDA    #(MASKNMI&MASKIRQ)
                    TAP
                    LDAA    CONFIG
                    ORAA    #MASKEDGE
                    STAA    CONFIG
                    CLR     FLAGIRQ
                    CLR     FLAGNMI
                    LDAA    #$00
                    STAA    REMAINING_MONEY
                    LDAA    #$FF
                    STAA    LEDS
                    
                    
Main                
                    LDAA    FLAGNMI
                    BNE     COINS   
                    CLR     FLAGNMI
                    LDAA    FLAGIRQ
                    BEQ     Main
                    CLR     FLAGIRQ 
                    JSR     DRINKS
                    BRA     Main

我被困在这里;我可以想象有几种方法可以使用C来解决它,但这对我没有多大帮助(不在汇编中).

I got stuck right here; i can imagine a few ways to solve it using C but that's not gonna help me a lot (not in assembly).

能帮帮我吗?

;*******************************************************************************
; MCU specific
;*******************************************************************************

REGS                equ       $1000               ;register base
PORTB               equ       REGS+$04            ;port B (output only)
PORTC               equ       REGS+$03            ;port C
OPTION              equ       REGS+$39            ;System Configuration Options
STACKTOP            equ       $01FF               ;Top of Stack
RAM                 equ       $0040               ;beginning of RAM
ROM                 equ       $F800               ;beginning of ROM

Virq                equ       $FFF2               ;IRQ vector
Vxirq               equ       $FFF4               ;XIRQ vector
Vreset              equ       $FFFE               ;reset vector

X.                  equ       %01000000           ;XIRQ disable
IRQE.               equ       %00100000           ;IRQ Edge sensitive

;*******************************************************************************
; Application specific
;*******************************************************************************

LED                 equ       PORTB               ;bitmap of LED
COIN                equ       PORTC               ;coin value is here
SODA_CHOICE         equ       PORTC               ;drink choice as bitmap
SODA_PULSES         equ       $0080               ;bitmap of soda pulses

INITIAL_DRINKS      equ       4                   ;number of initial drinks
DRINK_COST          equ       20                  ;drink cost in dollars

NOT                 equ       $FF                 ;XOR value to invert bits
;*******************************************************************************
                    org       RAM
;*******************************************************************************

soda_counters       rmb       8                   ;array of soda counters
money_total         rmb       2                   ;keeps money in machine

;*******************************************************************************
                    org       ROM
;*******************************************************************************

Start               
                    lds       #STACKTOP
                    bsr       InitMachine

                    tpa
                    anda      #X.^NOT             ;enable XIRQ interrupts
                    tap

                    ldaa       OPTION
                    oraa       #IRQE.              ;make IRQ edge sensitive
                    staa       OPTION

Loop_a              cli                           ;enable interrupts
                    wai                           ;low power mode until interrupt
                    bra       Loop_a              ;endless loop (all work is done in interrupt handlers)

;*******************************************************************************

InitMachine         
          ;-------------------------------------- ;assume INITIAL_DRINKS of each type
                    ldx       #soda_counters      ;X -> drink counters
                    ldaa      #INITIAL_DRINKS     ;A = number of drinks initially
Loop_1              staa      ,x                  ;update current counter
                    inx                           ;X -> next drink counter
                    cpx       #soda_counters+8
                    blo       Loop_1              ;repeat for all drink counters
                    bsr       AdjustLeds          ;adjust LED indicators
          ;--------------------------------------
                    clra
                    clrb
                    std       money_total         ;zero initial money balance
                    rts

;*******************************************************************************

AdjustLeds          
                    ldx       #soda_counters      ;X -> soda counters
                    clra                          ;bit mask of soda LED
Loop_2             tst       ,x                  ;test current soda counter
                    clc                           ;assume a zero
                    beq       Cont_1              ;if zero, go put a zero in the mask
                    sec                           ;else we'll put a one in the mask
Cont_1             rora                          ;shift in zero/one bit for this LED
                    inx                           ;X -> next soda counter
                    cpx       #soda_counters+8
                    blo       Loop_2              ;repeat for all counters
                    staa      LED                 ;update the LED accordingly
                    rts

;*******************************************************************************

AllowOneDrinkOnly   
                    pshx
                    pshb
                    psha

                    ldx       #8                  ;number of bits in a byte
                    clrb                          ;initialize bit counter
Loop_3              lsra                          ;drink choice into CCR[C]
                    bcc       Cont_2              ;skip zeros
                    incb                          ;count this choice
Cont_2              dex                           ;one less bit to ess
                    bne       Loop_3              ;repeat for all bits

                    cmpb      #1                  ;do we have only one drink?
                    bls       Done_1             ;if so, we're done

                    pula
                    clra                          ;else zero caller's RegA (drinks)
                    psha

Done_1              pula
                    pulb
                    pulx
                    rts

;*******************************************************************************

PulseDelay          
                    psha
                    clra
Loop_4              deca
                    bne       Loop_4
                    pula
                    rts

;*******************************************************************************

IRQ_Handler         
                    ldd       money_total         ;D = available money
                    cpd       #DRINK_COST         ;is it enough for a drink?
                    blo       Done_2             ;if less, ignore request

                    ldaa      SODA_CHOICE         ;A = drink choice
                    bsr       AllowOneDrinkOnly   ;A = validated drink choice (zero if more than one)
                    bita      LED                 ;is the drink available (LED on)?
                    beq       Done_2              ;if not, ignore request
          ;-------------------------------------- ;deliver drink
                    staa      SODA_PULSES         ;start selected drink pulse
                    bsr       PulseDelay          ;arbitrary delay for the pulse
                    clr       SODA_PULSES         ;stop all drink pulses
          ;-------------------------------------- ;count down the available drinks
                    ldx       #soda_counters
Loop_5             lsra                          ;move choice into CCR[C]
                    bcc       Cont_3             ;if not this one, continue
                    dec       ,x                  ;one less drink
                    ldd       money_total         ;D = previous money balance
                    subd      #DRINK_COST         ;less the drink value
                    std       money_total         ;update money balance
                    ldx       #soda_counters+8 ;will cause termination of loop (by making X too large)
Cont_3              inx
                    cpx       #soda_counters+8
                    blo       Loop_5
                    bsr       AdjustLeds          ;adjust LED indicators
          ;--------------------------------------
Done_2              rti

;*******************************************************************************

XIRQ_Handler        
                    ldab      COIN                ;B = value of inserted coin

                    cmpb      #1                  ;1 is allowed value
                    beq       Accept_1

                    cmpb      #2                  ;2 is allowed value
                    beq       Accept_1

                    cmpb      #5                  ;5 is allowed value
                    beq       Accept_1

                    cmpb      #10                 ;10 is allowed value
                    beq       Accept_1

          ; What do we do with all other coins?

                    bra       Done_3              ;get out of here
          ;-------------------------------------- ;update money in machine
Accept_1            clra
                    addd      money_total         ;add inserted money to total
                    bcs       Done_3              ;on (unlikely) overflow, ignore
                    std       money_total
          ;--------------------------------------
Done_3              rti

;*******************************************************************************
                    org       Virq
                    dw        IRQ_Handler

                    org       Vxirq
                    dw        XIRQ_Handler

                    org       Vreset
                    dw        Start
;*******************************************************************************

错误:

推荐答案

好的,这是完全未测试的,但应该可以给您带来启发!

OK, here it is, TOTALLY UNTESTED but should give you the idea!

假设:IRQ输入被去抖动,IRQ被边沿触发(因此对于相同的按键操作将不会重复),并且XIRQ脉冲将比执行相应处理程序所需的时间短以避免计数相同的钱两次或更多次.

Assumptions: IRQ input is debounced, IRQ is edge triggered (so it won't repeat for the same key press), and XIRQ pulse will be shorter than the time it takes to execute the corresponding handler to avoid counting the same money twice or more.

就像我在评论中说的那样,设计存在一定的缺陷,但是如果我们忽略这一点并假设不会发生极端情况,那么这是一种可能性:

Like I said in the comment, the design is somewhat flawed as given, but if we ignore this and assume corner cases won't happen, here's one possibility:

    ;*******************************************************************************
; MCU specific
;*******************************************************************************

REGS                equ       $1000               ;register base
PORTB               equ       REGS+$04            ;port B (output only)
PORTC               equ       REGS+$03            ;port C
OPTION              equ       REGS+$39            ;System Configuration Options
STACKTOP            equ       $01FF               ;Top of Stack
RAM                 equ       $0040               ;beginning of RAM
ROM                 equ       $F800               ;beginning of ROM

Virq                def       $FFF2               ;IRQ vector
Vxirq               def       $FFF4               ;XIRQ vector
Vreset              equ       $FFFE               ;reset vector

X.                  equ       %01000000           ;XIRQ disable
IRQE.               equ       %00100000           ;IRQ Edge sensitive

;*******************************************************************************
; Application specific
;*******************************************************************************

LED                 equ       PORTB               ;bitmap of LED
COIN                equ       PORTC               ;coin value is here
SODA_CHOICE         equ       PORTC               ;drink choice as bitmap
SODA_PULSES         equ       $0080               ;bitmap of soda pulses

INITIAL_DRINKS      equ       4                   ;number of initial drinks
DRINK_COST          equ       20                  ;drink cost in dollars

NOT                 equ       $FF                 ;XOR value to invert bits
;*******************************************************************************
                    org       RAM
;*******************************************************************************

soda_counters       rmb       8                   ;array of soda counters
money_total         rmb       2                   ;keeps money in machine

;*******************************************************************************
                    org       ROM
;*******************************************************************************

Start               proc
                    lds       #STACKTOP
                    bsr       InitMachine

                    tpa
                    anda      #X.^NOT             ;enable XIRQ interrupts
                    tap

                    lda       OPTION
                    ora       #IRQE.              ;make IRQ edge sensitive
                    sta       OPTION

Loop@@              cli                           ;enable interrupts
                    wai                           ;low power mode until interrupt
                    bra       Loop@@              ;endless loop (all work is done in interrupt handlers)

;*******************************************************************************

InitMachine         proc
          ;-------------------------------------- ;assume INITIAL_DRINKS of each type
                    ldx       #soda_counters      ;X -> drink counters
                    ldaa      #INITIAL_DRINKS     ;A = number of drinks initially
Loop@@              staa      ,x                  ;update current counter
                    inx                           ;X -> next drink counter
                    cpx       #soda_counters+::soda_counters
                    blo       Loop@@              ;repeat for all drink counters
                    bsr       AdjustLeds          ;adjust LED indicators
          ;--------------------------------------
                    clra
                    clrb
                    std       money_total         ;zero initial money balance
                    rts

;*******************************************************************************

AdjustLeds          proc
                    ldx       #soda_counters      ;X -> soda counters
                    clra                          ;bit mask of soda LED
Loop@@              tst       ,x                  ;test current soda counter
                    clc                           ;assume a zero
                    beq       Cont@@              ;if zero, go put a zero in the mask
                    sec                           ;else we'll put a one in the mask
Cont@@              rora                          ;shift in zero/one bit for this LED
                    inx                           ;X -> next soda counter
                    cpx       #soda_counters+::soda_counters
                    blo       Loop@@              ;repeat for all counters
                    staa      LED                 ;update the LED accordingly
                    rts

;*******************************************************************************

AllowOneDrinkOnly   proc
                    pshx
                    pshb
                    psha

                    ldx       #8                  ;number of bits in a byte
                    clrb                          ;initialize bit counter
Loop@@              lsra                          ;drink choice into CCR[C]
                    bcc       Cont@@              ;skip zeros
                    incb                          ;count this choice
Cont@@              dex                           ;one less bit to process
                    bne       Loop@@              ;repeat for all bits

                    cmpb      #1                  ;do we have only one drink?
                    bls       Done@@              ;if so, we're done

                    pula
                    clra                          ;else zero caller's RegA (drinks)
                    psha

Done@@              pula
                    pulb
                    pulx
                    rts

;*******************************************************************************

PulseDelay          proc
                    psha
                    clra
Loop@@              deca
                    bne       Loop@@
                    pula
                    rts

;*******************************************************************************

IRQ_Handler         proc
                    ldd       money_total         ;D = available money
                    cpd       #DRINK_COST         ;is it enough for a drink?
                    blo       Done@@              ;if less, ignore request

                    ldaa      SODA_CHOICE         ;A = drink choice
                    bsr       AllowOneDrinkOnly   ;A = validated drink choice (zero if more than one)
                    bita      LED                 ;is the drink available (LED on)?
                    beq       Done@@              ;if not, ignore request
          ;-------------------------------------- ;deliver drink
                    staa      SODA_PULSES         ;start selected drink pulse
                    bsr       PulseDelay          ;arbitrary delay for the pulse
                    clr       SODA_PULSES         ;stop all drink pulses
          ;-------------------------------------- ;count down the available drinks
                    ldx       #soda_counters
Loop@@              lsra                          ;move choice into CCR[C]
                    bcc       Cont@@              ;if not this one, continue
                    dec       ,x                  ;one less drink
                    ldd       money_total         ;D = previous money balance
                    subd      #DRINK_COST         ;less the drink value
                    std       money_total         ;update money balance
                    ldx       #soda_counters+::soda_counters ;will cause termination of loop (by making X too large)
Cont@@              inx
                    cpx       #soda_counters+::soda_counters
                    blo       Loop@@
                    bsr       AdjustLeds          ;adjust LED indicators
          ;--------------------------------------
Done@@              rti

;*******************************************************************************

XIRQ_Handler        proc
                    ldab      COIN                ;B = value of inserted coin

                    cmpb      #1                  ;1 is allowed value
                    beq       Accept@@

                    cmpb      #2                  ;2 is allowed value
                    beq       Accept@@

                    cmpb      #5                  ;5 is allowed value
                    beq       Accept@@

                    cmpb      #10                 ;10 is allowed value
                    beq       Accept@@

          ; What do we do with all other coins?

                    bra       Done@@              ;get out of here
          ;-------------------------------------- ;update money in machine
Accept@@            clra
                    addd      money_total         ;add inserted money to total
                    bcs       Done@@              ;on (unlikely) overflow, ignore
                    std       money_total
          ;--------------------------------------
Done@@              rti

;*******************************************************************************
                    org       Virq
                    dw        IRQ_Handler

                    org       Vxirq
                    dw        XIRQ_Handler

                    org       Vreset
                    dw        Start
;*******************************************************************************

现在,我要一份免费的苏打水:)

Now, I want a free soda for my work :)

这篇关于中断IQR和XIRQ-组装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 09:32