使用中断的6502微控制器的基本编程

时间:2016-04-06 23:26:59

标签: assembly microcontroller 6502

我正试图将中断用作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

我要做的是每秒向控制台打印一次“hello”,按下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

或者我需要通过中断计时的东西?任何指导都会有所帮助。

1 个答案:

答案 0 :(得分:0)

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

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

如果您正在控制工厂设备,则在不控制任何中断源(包括NMI和RESET)的情况下延迟循环是禁止的。但你在这里很好。

所以,你以正确的方式做到了 - 但不是在正确的位置。

我假设您的主循环会打印&#34;您好&#34;每秒一次,ISR会打印出#34;那里。&#34;所以你不想把你的延迟循环放在ISR中。单词&#34;延迟&#34;和&#34;中断服务程序&#34;通常不会永远在一起。

你可能不希望这件事做像打印Hello Hello HeTherello Hello这样的事情。

所以你需要构建你的ISR除了设置一个标志,然后你的主循环将检查。您的主循环可以在每个循环中检查此标记并打印&#34;在打印之后&#34; &#34; Hello&#34;,如果它已设置。然后它应该清除旗帜。

如果您希望在触发IRQ时响应,则可能需要检查延迟循环中的标志,并在设置标志时终止循环。如果你这样做,你也必须实现去抖 - 你要么需要一段时间来忽略标志,要么一些编程只是设置标志,如果一个按钮按下然后检测到释放 - 除非你没有&#39记住单位垃圾邮件&#34; Hello There&#34;按下按钮时不断。