【问题标题】:Basic Programming of a 6502 Microcontroller using Interrupts使用中断对 6502 微控制器进行基本编程
【发布时间】:2016-04-06 23:26:59
【问题描述】:

我正在尝试使用中断作为 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

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

【问题讨论】:

  • 我使用的 6502 没有板载定时器或端口,您必须使用外围 IC,例如内存映射的 6522 VIA。如果您使用计时器,则必须通过读取data sheet 来清除 IRQ 请求。使用软件循环来延迟时间是一项学生实验室练习,它只会浪费宝贵的处理器时间。
  • 我正在使用一个控制 LED 的小型微型控制器。
  • 更有帮助:你能说出有问题的板子吗?它提供什么中断,如果不止一个,你如何区分它们?您可能可以设置一个每秒发生的计时器,并通过检查状态寄存器将其与按钮或其他操作区分开来,或者有一个固定频率的计时器并且必须计算滴答声,可能会在每个滴答声时轮询按钮,或者必须通过固定长度的循环仅在 CPU 上计时。
  • @user3050884 哪一个?请提供指向您正在使用的确切部分的链接。我在那里看不到 6502,除了一个使用 Teensy 运行 Linux 为 6502 制作逻辑分析仪的示例应用程序。
  • 可能是里面的模拟器。看起来像家庭作业。

标签: assembly microcontroller 6502


【解决方案1】:

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

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

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

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

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

您可能也不希望它执行 print Hello Hello HeTherello Hello 之类的操作。

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

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

【讨论】:

    猜你喜欢
    • 2020-01-12
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多