0

我正在尝试使用中断作为 6502 Teensy 微控制器上计时动作的一种方式。我设法创建了一个计数器,通过触发中断来更快地添加位:

%uasm65
; v.002
; Increment port 0A200h at a rate of once increment
; per second. Use the timer based interrupt handler
; to control the time delay.

T1LL:  equ B006h
T1LH:  equ B007h
IER:   equ B00Eh
ACR:   equ B00Bh
COUNTDOWN: equ 500d
IRQVect: equ 0002d
OutChar: equ 0e003h
PrntMess: equ 0e00ch

org 0200h

lda #0d

sta IER             ; Disable all interrupts.
lda #11000000b
sta ACR             ; Set to T1 free running mode;

lda #COUNTDOWN<
sta T1LL            ; Low byte of latch.
lda #COUNTDOWN>
sta T1LH            ; High byte of latch.


; Initialize the interrupt vector.
    lda #InterruptHandler<
    sta IRQVect
    lda #InterruptHandler>
    sta IRQVect+1d

    lda #01000000b
    sta IER        ; Enable all interrupts
    cli            ; Enable interrupts

MainLoop:
    nop
    jmp MainLoop



InterruptHandler:
;Save registers on the stack.
    php
    pha
    txa
    pha
    tya
    pha
    inc 0a200h

;Restore registers from the stack.
    pla
    tay
    pla
    tax
    pla
    plp

    cli    ; Enable interrupts.
    rti    ; Return from interrupt.

    end
%/uasm65

我要做的是每秒打印一次“你好”到控制台,并在按下 IRQ 时打印“那里”,触发中断。我会使用延迟循环,例如:

Delay:
;Save registers on the stack.
pha
txa
pha
tya
pha

;Change the number that is being loaded into the
; 'A' register in order to change the delay time.
lda 0a600h

OutLoop:
ldx #0dfh

InLoop1:
ldy #0ffh

InLoop2:
dey
bne InLoop2

dex
bne InLoop1

sec
sbc #1d
bne OutLoop

;Restore registers from the stack.
pla
tay
pla
tax
pla

rts

end

还是我需要一些由中断计时的东西?任何指导都会有所帮助。

4

1 回答 1

0

如果您的 6502 以 1MHz 运行,这意味着它在 1 秒内执行 1,000,000 个周期。一条指令可以占用的最小周期数是 2,最大周期数是 8(实际最大值是 7,但如果地址跨越一个页面,例如 22FF-2300,某些指令会有一个惩罚周期)。

因此,如果您不想依赖于等待计时器,您可以想出任何创造性的方法来消耗 100 万个周期。显然,您将依赖循环。任何好的 6502 指令参考都会为您提供每条指令的周期时间。

如果您正在控制工厂设备,那么不控制任何中断源(包括 NMI 和 RESET)的延迟循环是一个禁忌。但是你在这里很好。

所以,你的做法是正确的——但不是在正确的位置。

我假设您的主循环会每秒打印一次“Hello”,而 ISR 会打印“There”。所以你不想把你的延迟循环放在 ISR 中。通常,“延迟”和“中断服务程序”这两个词永远不会同时出现。

你可能也不希望它做类似打印的事情Hello Hello HeTherello Hello

因此,您需要构建您的 ISR 以设置一个标志,然后您的主循环将检查该标志。您的主循环可以在每个循环中检查此标志并在打印“Hello”之后打印“There”(如果已设置)。显然,它应该清除标志。

如果您希望它在触发 IRQ 的那一刻做出响应,您可能需要检查延迟循环中的标志,如果设置了标志,则终止循环。如果你这样做,你也必须实现去抖动——你要么需要一段时间来忽略标志,要么需要一些编程来仅在检测到按钮按下然后释放时才设置标志 - 除非你不这样做按下按钮时,请注意设备不断发送“Hello There”的垃圾邮件。

于 2017-05-02T18:58:24.400 回答