如何修复 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:
我正在尝试编写一个使 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: