如何修复PIC组装程序以指定次数(即10次)闪烁LED?

时间:2016-03-10 19:48:13

标签: assembly pic led light blink

我正在尝试编写一个程序,使模式中的LED闪烁。模式是P0,P0和P1,P1和P2等......直到它到达P6和P7。每组LED应闪烁10次,然后继续前进到模式中的下一组。它第一次工作正常,但是当它在P6和P7之后返回到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 

1 个答案:

答案 0 :(得分:0)

你的最后一次眨眼

    call    LOOP8

LOOP1: 

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

    call    LOOP8
    goto    Loop

LOOP1: