Status
Not open for further replies.

Cantafford

Member
Hey,

I'm starting to learn assembly language for PICs. I wrote this following code that's supposed to blink the LED's of PORTA of a PIC16f877a. However the LEDS will stay off and won't blink at all. Please help me identify the issue in the following code if possible. Thank you.

Code:
; Program that adds a number to the working register

; you need to define where in memory program starts
; use the org directive to force program start at reset vector

;Register file map
ADCON1 equ 9fh ; in bank1
STATUS equ 03h ;  in bank0
TRISA equ 85h  ; in bank1
PORTA equ 05h
RP0 equ 05h
RP1 equ 06h

COUNT1 equ 20h; first counter for our delay loops(General Purpose register)
COUNT2 equ 21h;

org 00h ; set origin

; Program starts here
clrw ;clear working register

BCF STATUS, RP0 ; makes RP0 and RP1 0 to selectbank0(we equ'd 03h to STATUS maro)
BCF STATUS, RP1
CLRF PORTA ; Initialize PORTA by clearing output data latches

BSF STATUS, RP0 ;RP0=1, RP1=0 to select bank1
MOVLW 0x06
MOVFW ADCON1 ; make PORTA digital :D

MOVLW 0x00   ; make PORTA output(you know this ****)
MOVFW TRISA

BCF STATUS, RP0 ; transfer to bank 0
BCF STATUS, RP1

START MOVLW 0xFF ; turn all leds on move to Wreg
MOVWF PORTA ; put the value on the actual port

;delay
MOVLW 0xff
MOVWF COUNT1
MOVWF COUNT2

LOOP1 DECFSZ COUNT1, 1
GOTO LOOP1
DECFSZ COUNT2, 1
GOTO LOOP1

MOVLW 0x00 ; turn all leds on move to Wreg
MOVWF PORTA ; put the value on the actual port
GOTO START
end

House0Fwax

Member
Where you have 'DECFSZ COUNT1, 1' and 'DECFSZ COUNT2, 1' replace the end '1' with 'F'. That way you are decrementing the file, and putting the result back into the file. ie DECFSZ COUNT1, F

upand_at_them

Member
F is 1. Don't confuse the kid.

upand_at_them

Member
Steps that you should have taken to debug this:

1. Is everything connected properly?
2. Write a simpler program to only turn the LEDs on. Does that work?
3. Try PORT B. Does that work?

Ian Rogers

User Extraordinaire
Forum Supporter
If the LED's are connected to the port via the cathode... They will stay off..

You have a delay for off but not for on.... You need two delays as as soon as the port is 0 then you immediately make it 1 again..

Jon Wilder

Active Member
Code:
MAIN:
clrf     PORTA
comf     PORTA,F
call     Delay

Delay:
movlw    0xFF
movwf    COUNT1
movwf    COUNT2
decfsz   COUNT1,F
goto     $-1 decfsz COUNT2,F goto$-3
return

Cantafford

Member
If the LED's are connected to the port via the cathode... They will stay off..

You have a delay for off but not for on.... You need two delays as as soon as the port is 0 then you immediately make it 1 again..
I know that about the LEDs. I have connected them like this:

About the delay. I have added one after I turn off the LEDS. Like this:
Code:
;Register file map
ADCON1 equ 9fh ; in bank1
STATUS equ 03h ;  in bank0
TRISA equ 85h  ; in bank1
PORTA equ 05h
RP0 equ 05h
RP1 equ 06h

COUNT1 equ 20h; first counter for our delay loops(General Purpose register)
COUNT2 equ 21h
COUNT3 equ 22h
COUNT4 equ 23h
org 00h ; set origin

; Program starts here
clrw ;clear working register

BCF STATUS, RP0 ; makes RP0 and RP1 0 to selectbank0(we equ'd 03h to STATUS maro)
BCF STATUS, RP1
CLRF PORTA ; Initialize PORTA by clearing output data latches

BSF STATUS, RP0 ;RP0=1, RP1=0 to select bank1
MOVLW 0x06
MOVFW ADCON1 ; make PORTA digital :D

MOVLW 0x00   ; make PORTA output(you know this ****)
MOVFW TRISA

BCF STATUS, RP0 ; transfer to bank 0
BCF STATUS, RP1

START MOVLW 0xFF ; turn all leds on move to Wreg
MOVWF PORTA ; put the value on the actual port

;delay
MOVLW 0xFF
MOVWF COUNT1
MOVWF COUNT2

LOOP1 DECFSZ COUNT1, 1
GOTO LOOP1
DECFSZ COUNT2, 1
GOTO LOOP1

MOVLW 0x00 ; turn all leds on move to Wreg
MOVWF PORTA ; put the value on the actual port

LOOP2 DECFSZ COUNT3, 1
GOTO LOOP2
DECFSZ COUNT4, 1
GOTO LOOP2
end
The LED still stays off forever.

Code:
MAIN:
clrf     PORTA
comf     PORTA,F
call     Delay

Delay:
movlw    0xFF
movwf    COUNT1
movwf    COUNT2
decfsz   COUNT1,F
goto     $-1 decfsz COUNT2,F goto$-3
return
Thanks very much man but I would like to know my mistake in the code I wrote. I will try your solution as well. I'm guessing it works .

F is 1. Don't confuse the kid.
I'm not a kid I'm 23 years old.

Ian Rogers

User Extraordinaire
Forum Supporter
Your LED is the wrong way round, And so are the two movwf commands
Code:
  MOVLW 0x06
MOVFW ADCON1 ; make PORTA digital :D

MOVLW 0x00   ; make PORTA output(you know this ****)
MOVFW TRISA

Jon Wilder

Active Member
Thanks very much man but I would like to know my mistake in the code I wrote. I will try your solution as well. I'm guessing it works .
Ian explained that. My way is just a much more efficient way of doing it. Less instructions.
I'm not a kid I'm 23 years old.
Compared to most of us (even age-wise), you're a kid. Kid is also used as slang for a novice or amateur. Not a bad thing.

Cantafford

Member
Ian explained that. My way is just a much more efficient way of doing it. Less instructions.

Compared to most of us (even age-wise), you're a kid. Kid is also used as slang for a novice or amateur. Not a bad thing.
Haha yeah man I know I did not take it as an insult at all.

Cantafford

Member
Your LED is the wrong way round, And so are the two movwf commands
Code:
  MOVLW 0x06
MOVFW ADCON1 ; make PORTA digital :D

MOVLW 0x00   ; make PORTA output(you know this ****)
MOVFW TRISA
Ok you were right I misspelled that. It works now.
What do you mean by the led beiing the wrong way round tough?

Ian Rogers

User Extraordinaire
Forum Supporter
Ignore that.. my eyes are getting the worst of me these days... I have four pairs of glasses nowadays... electronics, reading, computer work and normal!!!

If I forget any pair I can just make out the screen!!

Cantafford

Member
Guys quick question if you don't mind I didn't wanna make a new thread for this because it's pretty much the same thing.
I have this piece of code which I got from a tutorial:

Code:
BANKSEL PORTB
decf PORTB
call _delay_1s
clrf PORTB
call _delay_1s
This basically blinks 5 LEDs on PORTB(all at once). So the 5 leds will be 1 second on and 1 second off.
I don't understand that decf PORTB thing. That is supposed to decrement my PORTB register by 1. At the beginning of the program I'm clearing PORTB. So how comes that decrementing the PORTB by 1 lights up all the 5 leds?
I have an ideea as why but I'm not sure if I'm right. I'm guessing that by substracting one from a null register(PORTB=0x00) makes the register PORTB = 0xFF. Is that correct?

Jon Wilder

Active Member
Yes. As PORTB is an 8 bit register, decrimenting PORTB at the time it is null causes it to roll over to 255 (0xFF).

Should've been decf PORTB,F as decf is a 2 operand instruction that needs to know where to store the result (whether in W or back in the source register File).

atferrari

Well-Known Member
I don't understand that decf PORTB thing. That is supposed to decrement my PORTB register by 1. At the beginning of the program I'm clearing PORTB. So how comes that decrementing the PORTB by 1 lights up all the 5 l
I have an ideea as why but I'm not sure if I'm right. I'm guessing that by substracting one from a null register(PORTB=0x00) makes the register PORTB = 0xFF. Is that correct?
Hola Cantafford

Now that you are learning the basics, get used to MPSIM. Simulate as much as you can and watch the registers appearing in the code being tested. What you ask above is easily seen in MPSIM.

Trust me; you can learn a lot simulating. Of course it is good for debugging well before implementing anything in a board.

One last suggestion: "Divide and conquer" was the first piece of advice I ever got, what means, add code one function at a time, test it and if OK then add the next. If something is wrong you know the last addition is most probably where to look at first. Start small and grow from there.

upand_at_them

Member
One last suggestion: "Divide and conquer" was the first piece of advice I ever got, what means, add code one function at a time, test it and if OK then add the next. If something is wrong you know the last addition is most probably where to look at first. Start small and grow from there.
Yes!

Jon Wilder

Active Member
Absolutely. Code is written and tested in stages. Never do they write the entire program in one shot. That's just asking for failure.