Delay loop problem

Thread Starter

ShaunManners

Joined Feb 16, 2008
72
Hi All,

I am working on a project, I asked for help with in the projects forum, and consequently have been working on a 3 phase inverter using the PIC18F4431.

This is described in Microchips document A900. I learnt the machine code and went through the code that was provided to make sure I understood it... but it doesn't work. So I thought it best to start with the basics and made an LED flash, and made it flash faster when a button was pressed.. I did it using interrupts, and all is great..

my problem is that I can create a loop that just counts down from 255 to 0 to waste time... but when I copy the loop used in the inverter program (a loop within a loop) the program seems to get caught in an infinite loop, I know this because I turn the LED on before the delay and turn it off after - it never goes off (I have put an oscilloscope on the output to make sure of this)

The WDT is turned off...

The other thing is, the code works fine when I use MPLAB sim...

can anybody see whats wrong?

Cheers
Shaun


MainProg code
Start:
movlw b'11111100'
movwf TRISD
bsf PORTD, 1


;=======================================================================
MainLoop
bsf PORTD, 1
call DELAY
bcf PORTD, 1
call DELAY
goto MainLoop


;=======================================================================
DELAY
movlw 0xFF
movwf COUNTER
loop1
movlw 0xFF
movwf COUNTER1
loop
decfsz COUNTER1, F
goto loop
decfsz COUNTER,1
goto loop1

return
;=======================================================================
 

SgtWookie

Joined Jul 17, 2007
22,230
When posting source code, you should use the "go advanced" button and click the "#" sign on the menu to surround your program with CODE tokens.

I've taken the liberty to reformat your source so that it's more readable.

Rich (BB code):
MainProg code
Start:
         movlw    b'11111100'	
	 movwf    TRISD
	 bsf      PORTD, 1

;=============================================
MainLoop
	 bsf      PORTD, 1
	 call     DELAY
	 bcf      PORTD, 1
	 call     DELAY
	 goto     MainLoop

;=============================================
DELAY
	 movlw    0xFF
	 movwf    COUNTER
loop1
	 movlw    0xFF
	 movwf    COUNTER1
loop
	 decfsz   COUNTER1, F
	 goto     loop
	 decfsz   COUNTER,1     
         goto     loop1 
          
	 return	
;=============================================
I'm not familiar with your implementation of Assembler. However, it appears that most of your labels such as "loop" don't have colons. Aren't they required?

I don't see a test instruction with a label branch to enable you to exit the loop1/loop code. However, you also don't have any comments in your code, so that makes it really tough for someone else to decipher.
 

hgmjr

Joined Jan 28, 2005
9,027
Here is a link to a LED flash routine written in MPASM. Maybe you can glean an answer to your question from reviewing it.

hgmjr
 

Thread Starter

ShaunManners

Joined Feb 16, 2008
72
When posting source code, you should use the "go advanced" button and click the "#" sign on the menu to surround your program with CODE tokens.

I've taken the liberty to reformat your source so that it's more readable.


I'm not familiar with your implementation of Assembler. However, it appears that most of your labels such as "loop" don't have colons. Aren't they required?

I don't see a test instruction with a label branch to enable you to exit the loop1/loop code. However, you also don't have any comments in your code, so that makes it really tough for someone else to decipher.
Thanks for replying!... yes you are correct, I didn't put any comments in, rather bad practice sorry.. I have added some in now... also thanks for pointing out the code formatting in the advanced settings... when i posted it I hadn't seen that and also it appears to have stripped out the tabs too...

As for the test instruction, that is decfsz, this decrements the COUNTER variable and if it is 0 then it skips the next instruction... thus exiting the loop.

I'm not sure about the colons, some people seem to use them, some don't.. I tried both, so it is a bit inconsitant .. I'll try adding them in for all labels.

Cheers
Shaun

Rich (BB code):
MainProg code
Start:
         movlw    b'11111100'	; Setup the port
	 movwf    TRISD
	 bsf      PORTD, 1      ; turn LED on

;=============================================
MainLoop
	 bsf      PORTD, 1     ; Turn LED on
	 call     DELAY         ; Add a delay
	 bcf      PORTD, 1    ; Turn LED off
	 call     DELAY         ; Add a delay
	 goto     MainLoop

;=============================================
DELAY
	 movlw    0xFF
	 movwf    COUNTER ; Moves FF into COUNTER (decimal 255)
loop1
	 movlw    0xFF
	 movwf    COUNTER1 ;Moves FF into COUNTER1 (decimal 255)
loop
	 decfsz   COUNTER1, F ; Decrement COUNTER1, if 0 skip "goto loop" instruction
	 goto     loop ;Loop until COUNTER1 is 0

	 decfsz   COUNTER,1     ; Outer loop, repeats the above loop 255 times
         goto     loop1 
          
	 return	
;=============================================
 

SgtWookie

Joined Jul 17, 2007
22,230
Ok, I see:
Rich (BB code):
         decfsz   COUNTER1,F
and then later:
Rich (BB code):
         decfsz   COUNTER,1
I don't see a definition anywhere for "F" - is that legal for an implied hex 15, or an error?
Since I see no definition for F, the assembler may be interpreting it as zero. So, you're subtracting zero from COUNTER1, which will keep it from becoming zero for quite a long time. Until you run out of power, perhaps. ;)

Consistency in programming style is very important. "Sloppy" code is hard to read. Try to use meaningful names for everything, and put documentation throughout your code. It might seem to be a waste of time now, but when you run across that piece of code a few years later, you will have to take it apart piece by piece to figure out what the heck you were doing - and you will have far less time to make the changes than you had to write it in the first place.

Pseudocode is a great way to introduce the function of a subroutine. It's also a good way to start developing your program.

Write the pseudocode to describe what needs to be done, then write the actual program/subroutines to fit the pseudocode.

The equals sign and dashes are what I use to separate sections and pseudocode from the actual code itself. They're easy on the eyes (not overly busy) and can help you locate a section of code very quickly.

I also use a comment line as the very last line of the program, so that it's apparent right away if the file has been damaged or chopped off.

Rich (BB code):
PROGNAME: ORG    0000H
;================================================================
; Program name: (fill it in)           Revised: (the date)
; Author: (whodunit)
; Function: (what the entire program is supposed to do)
;----------------------------------------------------------------
(initialization/housekeeping)
(branch to start of main routine)
(variables)
;================================================================
; Main routine
; (pseudocode describing main routine)
;----------------------------------------------------------------
MAIN:
            (do stuff)
             CALL     Subrtn1:
             GOTO     MAIN:
;================================================================
; Subroutine 1
; (pseudocode describing subroutine)
;----------------------------------------------------------------
Subrtn1:
             (do stuff)
             RETURN
;----------------------------- END ------------------------------
 

Thread Starter

ShaunManners

Joined Feb 16, 2008
72
Here is a link to a LED flash routine written in MPASM. Maybe you can glean an answer to your question from reviewing it.

hgmjr
Thanks for that, I may be able to adapt some of that... trouble with me is that I like to know why something wasn't working ;)

Cheers
Shaun
 

hgmjr

Joined Jan 28, 2005
9,027
Thanks for that, I may be able to adapt some of that... trouble with me is that I like to know why something wasn't working ;)

Cheers
Shaun
That is an admirable trait. You may find that working through an example program can be a learning experience as well. There are a number of ways to skin this cat. Once you get the example working, you can then experiment to see what happens when you tweak the original code.

After you get a bit more familiar with the processor and the assembly language, you will be able to return to your original program that gave you trouble and figure out where things went wrong.

hgmjr
 

Thread Starter

ShaunManners

Joined Feb 16, 2008
72
I don't see a definition anywhere for "F" - is that legal for an implied hex 15, or an error?
Since I see no definition for F, the assembler may be interpreting it as zero. So, you're subtracting zero from COUNTER1, which will keep it from becoming zero for quite a long time. Until you run out of power, perhaps. ;)

Consistency in programming style is very important. "Sloppy" code is hard to read. Try to use meaningful names for everything, and put documentation throughout your code. It might seem to be a waste of time now, but when you run across that piece of code a few years later, you will have to take it apart piece by piece to figure out what the heck you were doing - and you will have far less time to make the changes than you had to write it in the first place.

Pseudocode is a great way to introduce the function of a subroutine. It's also a good way to start developing your program.

Write the pseudocode to describe what needs to be done, then write the actual program/subroutines to fit the pseudocode.

The equals sign and dashes are what I use to separate sections and pseudocode from the actual code itself. They're easy on the eyes (not overly busy) and can help you locate a section of code very quickly.

I also use a comment line as the very last line of the program, so that it's apparent right away if the file has been damaged or chopped off.
Thanks SgtWookie,

The funny thing is that I am computing lecturer, and your comments above are exactly what I tell my students ;)... better practice what I preach!!

The incosistencies are where I have been playing with the code... the F or 1 means that it puts the result of the decrement back in the F register. F is a reserved word... I think it may be declared in the include file... however, if you are right and it is interpreting it as a 0 then that would indeed cause the infinite loop.. I'll look into it.

I also use dashes and equals to separate functions etc.. but this piece of code was so basic I hadn't bothered.. its a good idea to put that comment at the end.. also thanks for showing me the layout you use for your programs... thats something I'm still getting used to.

Cheers
Shaun
 

SgtWookie

Joined Jul 17, 2007
22,230
er, WHAT include file?
You didn't include the include statement in your program listing.
Include "PIC18F44x.inc" ; perhaps?

OK, I guess I'm just going to have to download MPLAB and play with it ;)
 

n9352527

Joined Oct 14, 2005
1,198
I don't see anything wrong in your code. This could be a hardware problem.

Do you have the schematic diagram of your circuit? Do you use enough decoupling capacitors across the supply and close to the PIC? Do you have a current limiting resistor in series with the LED?
 

a088008

Joined Apr 17, 2008
4
I agree with SgtWookie. I took the liberty of writing your algorithm in pseudocode. I put a '?' where the 'F' in your code is.

Rich (BB code):
Main()
{
 while( true )
 {
  LED = on
  Delay()
  LED = off
  Delay()
 }
}
Delay()
{
 counter = 255
 do
 {
  counter1 = 255
  do
  {
   counter1 = counter1 - ?
  }
  while( counter1 != 0 )
  counter = counter - 1
 }
 while( counter != 0 )
}
Ok, I see:
Rich (BB code):
         decfsz   COUNTER1,F
and then later:
Rich (BB code):
         decfsz   COUNTER,1
I don't see a definition anywhere for "F" - is that legal for an implied hex 15, or an error?
Since I see no definition for F, the assembler may be interpreting it as zero. So, you're subtracting zero from COUNTER1, which will keep it from becoming zero for quite a long time. Until you run out of power, perhaps.
 

atferrari

Joined Jan 6, 2004
5,012
Yes, F is EQUal to 1. Declared at the very beginning (or it is at the end?) of your .inc file.

Please DO incremental testing. I learnt that the hard way! Every testable portion of code should be tested before adding more.
 
Top