装配程序不起作用

时间:2018-01-09 13:24:25

标签: assembly arduino avr

我在汇编时遇到了程序问题。该计划应该执行以下操作:

说"欢迎" >等一秒>说"按2到(Str_roll_1)roll(Str_roll_2)" >如果按下2,则开始滚动骰子,直到键被释放为止>显示价值并存储它>回到"按2滚动" >重复

但出于某种原因,我无法绕过头脑,代码几乎跳过" roll_dice"部分并绕着循环显示"滚动......" > "价值:0" > "滚动..." > "价值:0" > ......等等

我使用arduino leonardo电路板,如果有任何帮助的话。我不知道这些信息是否足够,但如果您需要更多信息,请询问。谢谢:))

代码的主要部分:(我希望我所包含的子程序非常不言自明)

main: 
PRINTSTRING Str_welcome
RCALL delay_1_s
RCALL lcd_clear_display

PRINTSTRING Str_roll_1
LDI RVAL, 0xC0
RCALL lcd_write_instr
PRINTSTRING Str_roll_2

loop:
CALL read_keyboard
LDI R25, 0x04
CP R25, RVAL
BREQ two

RJMP loop

two:
RCALL lcd_clear_display
PRINTSTRING Str_rolling
RCALL delay_1_s
RCALL roll_dice
RCALL store_stat
RCALL lcd_clear_display
PRINTSTRING Str_value
SUBI R24, -48
RCALL lcd_write_chr
RCALL delay_1_s

RJMP cont

cont:
RCALL lcd_clear_display
PRINTSTRING Str_roll_1
LDI RVAL, 0xC0
RCALL lcd_write_instr
PRINTSTRING Str_roll_2
RJMP loop

roll_dice:
    LDI R16, 6
test:   
    NOP
    NOP
    RCALL read_keyboard
    CPI RVAL, 0x04
    BREQ roll
    RET
roll:   
    DEC R16
    BREQ roll_dice
    RJMP test

键盘文件//////////

map_table: .DB "147*2580369#"

read_keyboard:
LDI R18, 0      ; reset counter
LDI ZH, high(map_table <<1) ;Initialize Z pointer
LDI ZL, low(map_table <<1)
ADD ZL, RVAL ;Add index
LDI RVAL, 0x00
ADC ZH, RVAL ;Add 0 to catch Carry, if present
LPM RVAL, Z

scan_key:
MOV R19, R18
LSL R19
LSL R19
LSL R19
LSL R19
OUT PORTB, R19      ; set column and row

在此处插入22条NOP线

SBIC PINE, 6
RJMP return_key_val
INC R18
CPI R18, 12
BRNE scan_key
LDI R18, NO_KEY     ; no key was pressed!

return_key_val:
MOV RVAL, R18
RET

2 个答案:

答案 0 :(得分:2)

您的问题很可能不是软件,而是硬件。我敢打赌,如果你把一个示波器放在钥匙上,你会看到它有接触反弹。开关将暂时关闭,但随后重新打开并重新关闭几次,然后才能变为稳定值。

这意味着,由于您在第一次反弹发生后立即离开延迟循环,它似乎永远不会发生(尽管非常短暂地)。如果您调用read_keyboard并打开一个引脚(或调试LED),如果键2处于活动状态,如果键2处于非活动状态,则将其关闭,您将看到后面的键2正在工作,但您赢了&#39;当它改变状态时,看到快速的眨眼。触点反弹通常在毫秒级,但在非常糟糕的开关上可能会更长。

通常,最好的解决方案是持续监控计时器中按钮的状态,并且只有在引脚稳定后才更新全局状态变量。然后,您的主要代码只会查看已正确过滤且稳定的状态。有硬件方法可以做到这一点,因此您选择的确切解决方案是一个工程问题,取决于整个系统设计

答案 1 :(得分:0)

通过做这样的事情,我发现开发过程要复杂得多,因为汇编可以很容易地演变成意大利面条代码。

; ============================================================================================
; This pair of complimentary routines controls function of watchdog timer.

;   ENTER:  R24 = Bits 5 & 2:0 deliniate prescaler value WDP3:0 (11-2 pg 55)
; --------------------------------------------------------------------------------------------

    .equ    WDT_Change_Enable = (1 << WDCE) | (1 << WDE)

  WDT_Enable:
        in      R20, SREG               ; So I flag bit 7 will be returned in original state.

    ; During this process, we do not want interrupts or an inadvertant timeout of WDT.

        cli                             ; Disable interrupts
        wdr                             ; To be sure we have at least 16ms to setup

  WDT_Set:
        lds     R25, WDTCSR             ; 11.9.2 pg 54 Control Register
        sbr     R25, WDT_Change_Enable
        sts     WDTCSR, R25             ; Begin timmed sequence
        sts     WDTCSR, R24             ; Write desired parameters

    ; A change to watchdog can happen anywhere, so if global interrupts are already
    ; disabled, we do not want to change the flags state.

        out     SREG, R20               ; In order to not modify "I" flag.
        ret

; ---------------------------------------------------------------------------------------------

  WDT_Disable:
        in      R20, SREG               ; See comments @ WDT_Enable
        cli
        wdr

    ; See note a bottom of page 52 ATMEL 8271I-AVR-10/2014

        in      R25, MCUSR              ; 7.3.1 pg 11
        cbr     R25, WDRF               ; Clear watchdog reset bit
        out     MCUSR, R25

    ; Reset watchdog enable, but retain prescaler.

        lds     R24, WDTCSR
        cbr     R24, RSET               ; Clear bit so watchdog will be disabled.
        rjmp    WDT_Set

这有两件事。 (1)它强化了一个概念,因为一旦你写了评论,仔细检查代码将做什么,(2)其他阅读不必猜测任何部分正在做什么和为什么。

Jester写道:

  

这对我没有任何意义。

我很确定他并不是故意暗示你的代码是荒谬的,而是对你来说直观的不是我们。我愿意打赌,如果你花费更多的时间记录,问题就会突然出现在你面前,如果没有,那么对于那些你要求帮助的人来说,理解你的逻辑就会容易得多。 / p>

你可能是对的,但我也发现了,假设你没有包含的东西没有问题,可以放肆。