如何修复 PIC 汇编程序使 LED 闪烁指定次数(即 10 次)?

How to fix PIC assembly program to blink LEDs designated amount of times (i.e. 10 times)?

我正在尝试编写一个使 LED 以某种模式闪烁的程序。模式是 P0、P0 和 P1、P1 和 P2,等等……直到到达 P6 和 P7。每组 LED 应该闪烁 10 次,然后按照模式继续下一组。第一次通过没问题,但是在P6和P7之后returns到P0的时候,P0闪烁了20次。其余的 LED 闪烁 10 次,所以我很困惑为什么它对 P0 这样做。有人可以解释原因或帮助我解决问题吗?

在代码中,分号 (;) 表示它是注释。这是代码:

#include <p16F887.inc>
__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V

cblock  0x20            ;start of general purpose registers
    count1          ;used in delay routine
    counta          ;used in delay routine 
    countb          ;used in delay routine
    count2
    Num1
    Num2
    Num3
    Num4
    Num5
    Num6
    Num7
    Num8
endc

LEDPORT Equ PORTD       ;set constant LEDPORT = 'PORTB'
LEDTRIS Equ TRISD       ;set constant for TRIS register

org 0x0000          ;org sets the origin, 0x0000 for the 16F628,
                ;this is where the program starts running   
movlw   0x07

bsf     STATUS,     RP0 ;select bank 1
movlw   b'00000000'     ;set PortB all outputs
movwf   LEDTRIS
bcf STATUS,     RP0 ;select bank 0
clrf    LEDPORT         ;set all outputs low    

Loop    
    movlw   d'10'
    movwf   Num1
    movlw   d'10'
    movwf   Num2
    movlw   d'10'
    movwf   Num3
    movlw   d'10'
    movwf   Num4
    movlw   d'10'
    movwf   Num5
    movlw   d'10'
    movwf   Num6
    movlw   d'10'
    movwf   Num7
    movlw   d'10'
    movwf   Num8

    call    LOOP1
    call    LOOP2
    call    LOOP3
    call    LOOP4
    call    LOOP5
    call    LOOP6
    call    LOOP7
    call    LOOP8

LOOP1: 
     movlw  b'00000001'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num1,1
     goto   LOOP1
     clrf   Num1
     movlw  d'10'
     movwf  Num1
     return

LOOP2: 
     movlw  b'00000011'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num2,1
     goto   LOOP2
     ;clrf  Num2
     movlw  d'10'
     movwf  Num2
     return 

LOOP3: 
     movlw  b'00000110'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num3,1
     goto   LOOP3
     ;clrf  Num3
     movlw  d'10'
     movwf  Num3
     return 

LOOP4: 
     movlw  b'00001100'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num4,1
     goto   LOOP4
     movlw  d'10'
     movwf  Num4
     return     

LOOP5: 
     movlw  b'00011000'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num5,1
     goto   LOOP5
     movlw  d'10'
     movwf  Num5
     return     

LOOP6: 
     movlw  b'00110000'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num6,1
     goto   LOOP6
     movlw  d'10'
     movwf  Num6
     return   

LOOP7: 
     movlw  b'01100000'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num7,1
     goto   LOOP7
     movlw  d'10'
     movwf  Num7
     return   

LOOP8: 
     movlw  b'11000000'
     movwf  LEDPORT
     call   Delay           ;this waits for a while!
     movlw  b'00000000'
     movwf  LEDPORT
     call   Delay
     DECFSZ Num8,1
     goto   LOOP8
     movlw  d'10'
     movwf  Num8
     return     

Delay   ;movlw  d'4'
        ;movwf  count2
        movlw   d'250'          ;delay 250 ms (4 MHz clock)
        movwf   count1
    d1  movlw   0xC7
        movwf   counta
        movlw   0x01
        movwf   countb
Delay_0
        decfsz  counta, f
        goto    $+2
        decfsz  countb, f
        goto    Delay_0

        decfsz  count1  ,f
        goto    d1
        ;decfsz count2  ,f
        ;goto   d1
        retlw   0x00

end 

你最后一次 LED 闪烁

    call    LOOP8

LOOP1: 

落入 LOOP1: 但它应该跳回到 Loop。这导致执行到达 LOOP1: 函数末尾的 return,但由于内部调用堆栈上没有 return 地址,因此设备将 reset 地址放在程序计数器。因此,LOOP1 似乎执行了两次。你应该

    call    LOOP8
    goto    Loop

LOOP1: