Arduino Leonardo汇编骰子程序故障:跳过roll_dice循环显示值为0
Arduino Leonardo Assembly: Roll Dice Routine Skipped, Stuck in "Rolling..." → "Value: 0" Loop
Hey folks, I'm troubleshooting an Arduino Leonardo assembly program for a dice rolling feature that's misbehaving badly. Here's what it should do:
- Display "Welcome"
- Wait 1 second
- Show the prompt: "Press 2 to(Str_roll_1) roll(Str_roll_2)"
- When the 2 key is pressed, keep rolling the dice until the key is released
- Display and store the final dice value
- Loop back to the initial prompt
Instead, it skips the actual dice rolling logic entirely and gets stuck in an infinite loop showing "Rolling..." → "Value: 0" → "Rolling..." → "Value: 0" nonstop.
Core Code Snippets
Main Program
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 Subroutine
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
Keyboard Handling Code
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 insert 22 NOP lines here 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
Troubleshooting Breakdown & Fixes
Let's walk through the critical issues causing the failure:
Broken
read_keyboardLogic- The routine starts by trying to index into
map_tableusingRVAL—butRVALhasn't been initialized yet! This means you're using garbage data to look up a key, leading to unpredictable return values. - The actual keyboard scan (
scan_key) happens after this broken lookup, so the key state you're checking in the main loop androll_diceis unreliable. - Fix: Move the
map_tablelookup to after the keyboard scan. Since your main code checks for the key index (0x04 for the '2' key), you could even skip the map lookup entirely here and just returnR18directly.
- The routine starts by trying to index into
Backwards Logic in
roll_dice- Right now,
roll_dicereturns immediately if the 2 key is not pressed, and loops if it is pressed—this is the opposite of your intended behavior (you want to roll while the key is held, then return when released). - Additionally, when
R16hits 0, you jump back toroll_diceto reinitialize it, creating an infinite loop if the key stays held. - Fix: Rewrite the subroutine to loop while the key is pressed, generate a random dice value each iteration, and return only when the key is released.
- Right now,
No Dice Value Generation
- Nowhere in your code do you actually generate a random number between 1-6 and store it in
R24(which the main routine tries to print). That's why you're seeing "Value: 0"—R24is never set to a valid dice value. - Fix: Add logic to generate a random value (use an uninitialized register or timer tick as a seed, since AVRs lack hardware randomness) and store it in
R24before returning fromroll_dice.
- Nowhere in your code do you actually generate a random number between 1-6 and store it in
Main Loop Key Check Reliability
- The main loop checks if
RVALequals 0x04 (the index of '2' inmap_table), which is correct—but only ifread_keyboardis returning accurate index values. Fixing the keyboard routine will resolve this.
- The main loop checks if
内容的提问来源于stack exchange,提问作者Isac Oskarsson
相关产品推荐
相关产品推荐

