Looping in PIC 18F Assembler?

Discussion in 'Embedded Systems and Microcontrollers' started by spinnaker, Jan 26, 2011.

  1. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,884
    1,002
    I am trying to learn assembler so I can incorporate a bit of assembler code in my C code.

    I wrote a simple loop to loop through a 16bit word:

    Code ( (Unknown Language)):
    1.  
    2. unsigned int delay_ms= 10;
    3.  
    4. void main()
    5. {
    6.    
    7.  
    8.     _asm       loop:             decfsz delay_ms,1,1
    9.                             goto loop
    10.                             decfsz delay_ms+1,1,1
    11.                             goto loop    
    12.                                          
    13.                              
    14.                  _endasm
    15.    
    16.     while(1);
    17.  
    18. }
    19.  
    I quickly realized there is a flaw in my code. It works fine if delay_ms is 256 or greater but if it is 255 or less, the value in decfsz delay_ms+1 gets decremented to FF . How do I test if FF is zero before decrementing it?
     
  2. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    you are only working on one byte, not both in the assembly routine. Check your compiler's help guide on accessing 16 bit variables through inline assembly (if supported).

    Another option is it may be working fine, and the decrement is rolling over when the upper byte hits zero.
     
  3. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    You probably want to a normal dec followed by checking the carry bit in STATUS.

    <ed> This is just for the high byte. At the moment your loop will end at 0x0100 instead of 0x0000 </ed>
     
    Last edited: Jan 27, 2011
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    See how your C compiler solve this. It may give some ideas
     
  5. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
  6. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    As the PIC 10/12/16/18 series of processors are 8 bit devices they don't have any instructions for dealing with 16 bit numbers so you will have to do it all yourself.

    I have not tested the following code so it might fall down in a screaming heap but give it a go and see if it works. In any case it gives you the general idea.
    Code ( (Unknown Language)):
    1. unsigned int delay_ms= 10;
    2.  
    3. void main()
    4. {
    5.    
    6.  
    7.     _asm    
    8.         loop:       movf,  delay_ms, f        ;test low byte and set Z and N bit of status register
    9.                     bz, hi_test               ;if low byte is zero check high byte
    10.         low_dec:    decf, delay_ms, f         ;decrement low byte
    11.                     goto loop                
    12.         hi_test:    movf, delay_ms+1, f       ;test high byte
    13.                     bz, finish                ;if both low and high bytes = 0 go to finish
    14.                     decf delay_ms+1, f        ;else decrement high byte
    15.                     goto low_dec               ;jump back and decrement low byte so it rolls over to 0xFF
    16.         finish:     _endasm
    17.    
    18.     while(1);
    19.  
    20.  
     
    Last edited: Jan 27, 2011
  7. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,884
    1,002
    Thanks everyone.

    AlexR,

    I was just about to try something similar to what you posted. Thanks
     
Loading...