I am using a PIC16F628 PIC. I am programming it with ASM. I have an LED connected to each availible pin of the PIC - 13 LEDs total. I want to turn on the LEDs one by one with a short delay between each. I know that there is an error in this line of the code: bsf PORTA, TRISAPOS. PORTA holds the location of PORTA just like it sounds and TRISAPOS is the location for a register that holds the next bit to be set in the loop. What is happening is that the program reads 32h (the location of the register) not the value the register holds. The loop decrements this register so the value always changes. This is hard to explain but the source code is posted below. Hopefully it will clear up any questions. If not please ask. The two probelm lines are marked in the comments section.
;*****Set up the Constants****
STATUS equ 03h ;Address of the STATUS register
TRISA equ 85h ;Address of the tristate register for port A
TRISB equ 86h ;Address of the tristate register for port B
PORTA equ 05h ;Address of Port A
PORTB equ 06h
COUNT1 equ 30h ;First counter for our delay loops
COUNT2 equ 31h ;Second counter for our delay loops
COUNT3 equ 34h ;Third Delay Counter
TRISAPOS equ 32h ;port position in TRISA
TRISBPOS equ 33h ;port position in TRISB
TRISANUM equ 04h ;number of ports in TRISA
TRISBNUM equ 07h ;number of ports in TRISB
;****Set up the port****
bsf STATUS,5 ;Switch to Bank 1
movlw 00h ;Set the Port A pins
movwf TRISA ;to output.
movwf TRISB
bcf STATUS,5 ;Switch back to Bank 0
;****Turn the LED on****
Start
movlw 04h ;reset port positions
movwf TRISAPOS
movlw 07h
movwf TRISBPOS
;****************TRISA******************
TRISALOOP
bsf PORTA, TRISAPOS ;turn on the pin's LED ----- PROBLEM HERE ------
call Delay ;delay
decfsz TRISAPOS, 1 ;subtract one from TRISA position
goto TRISALOOP ;restart loop if not zero
TRISBLOOP
bsf PORTB, TRISBPOS ;turn on the pin's LED ----- PROBLEM HERE --------
call Delay ;delay
decfsz TRISBPOS, 1 ;subtract one from TRISB position
goto TRISBLOOP ;restart loop if not zero
;****Start of the delay ****
call Delay
;****Delay finished, now turn the LED off****
movlw 00h ;Turn the LED off by first putting
movwf PORTA ;it into the w register and then on ;the port
movwf PORTB
;****Add another delay****
call Delay
;****Now go back to the start of the program
goto Start ;go back to Start and turn LED ;on again
;****End of the program****
;********Delay*****************
Delay
movlw 0FFh
movwf COUNT1 ;reset counters
movwf COUNT2
movwf COUNT3
Loop
nop
nop
nop
nop
decfsz COUNT1,1
goto Loop ;actual delay
decfsz COUNT2,1 ;subtract one from each variable each pass
goto Loop
decfsz COUNT3, 1
goto Loop
return
end ;Needed by some compilers, ;and also just in case we miss ;the goto instruction.
For the two lines MP LAB gives this error:
Warning[202] G:\LED\LED2.ASM 38 : Argument out of range. Least significant bits used.
This is what leads me to beleive that the register location is being used, not the register value. Is there a way to turn on each LED with a loop? I would like to use a loop if possible to make the code as small as possible and easier to read.
Sorry if this is a simple question. This is only my second PIC project. I am used to programming high level languages like VB, C, C++, HTML, ASP etc. I am taking electrical engineering in the fall and I want to get a head start. Thanks for the help in advance.
;*****Set up the Constants****
STATUS equ 03h ;Address of the STATUS register
TRISA equ 85h ;Address of the tristate register for port A
TRISB equ 86h ;Address of the tristate register for port B
PORTA equ 05h ;Address of Port A
PORTB equ 06h
COUNT1 equ 30h ;First counter for our delay loops
COUNT2 equ 31h ;Second counter for our delay loops
COUNT3 equ 34h ;Third Delay Counter
TRISAPOS equ 32h ;port position in TRISA
TRISBPOS equ 33h ;port position in TRISB
TRISANUM equ 04h ;number of ports in TRISA
TRISBNUM equ 07h ;number of ports in TRISB
;****Set up the port****
bsf STATUS,5 ;Switch to Bank 1
movlw 00h ;Set the Port A pins
movwf TRISA ;to output.
movwf TRISB
bcf STATUS,5 ;Switch back to Bank 0
;****Turn the LED on****
Start
movlw 04h ;reset port positions
movwf TRISAPOS
movlw 07h
movwf TRISBPOS
;****************TRISA******************
TRISALOOP
bsf PORTA, TRISAPOS ;turn on the pin's LED ----- PROBLEM HERE ------
call Delay ;delay
decfsz TRISAPOS, 1 ;subtract one from TRISA position
goto TRISALOOP ;restart loop if not zero
TRISBLOOP
bsf PORTB, TRISBPOS ;turn on the pin's LED ----- PROBLEM HERE --------
call Delay ;delay
decfsz TRISBPOS, 1 ;subtract one from TRISB position
goto TRISBLOOP ;restart loop if not zero
;****Start of the delay ****
call Delay
;****Delay finished, now turn the LED off****
movlw 00h ;Turn the LED off by first putting
movwf PORTA ;it into the w register and then on ;the port
movwf PORTB
;****Add another delay****
call Delay
;****Now go back to the start of the program
goto Start ;go back to Start and turn LED ;on again
;****End of the program****
;********Delay*****************
Delay
movlw 0FFh
movwf COUNT1 ;reset counters
movwf COUNT2
movwf COUNT3
Loop
nop
nop
nop
nop
decfsz COUNT1,1
goto Loop ;actual delay
decfsz COUNT2,1 ;subtract one from each variable each pass
goto Loop
decfsz COUNT3, 1
goto Loop
return
end ;Needed by some compilers, ;and also just in case we miss ;the goto instruction.
For the two lines MP LAB gives this error:
Warning[202] G:\LED\LED2.ASM 38 : Argument out of range. Least significant bits used.
This is what leads me to beleive that the register location is being used, not the register value. Is there a way to turn on each LED with a loop? I would like to use a loop if possible to make the code as small as possible and easier to read.
Sorry if this is a simple question. This is only my second PIC project. I am used to programming high level languages like VB, C, C++, HTML, ASP etc. I am taking electrical engineering in the fall and I want to get a head start. Thanks for the help in advance.