ADDWF, PCL likes ZERO PAGE on pic16f887

Discussion in 'Embedded Systems and Microcontrollers' started by techristian, Sep 27, 2013.

  1. techristian

    Thread Starter New Member

    Aug 27, 2013
    26
    2
    I made a very small table for hex display...only 16 bytes long. I ORGed it at 0230 . It never worked. All I did was move it up to Zero page and it worked ????

    There was never any chance that the W register ever had a value any larger than 16 or any chance of the CALL creating a jump greater than 16 bytes ahead???So why does the display now work properly after moving to the Zero page?

    Anyway, it would be helpful if I could ever learn how to STEP through , one instruction at a time. I'm using the latest FREE version of MPLABX, and haven't figured out how to use the step debugger yet.

    Dan
     
  2. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    If you want to use another page you have to change PCLATH as well.
     
    Eric007 likes this.
  3. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,644
    759
    Talking about code that we do not know is difficult.
     
  4. techristian

    Thread Starter New Member

    Aug 27, 2013
    26
    2
    Thanks Mark

    Code ( (Unknown Language)):
    1.  hexTable  
    2.   ADDWF, PCL,1  
    3. RETLW   b'01011111' ;0  
    4. RETLW   b'00000101' ;1  
    5. RETLW   b'01111100' ;2  
    6. RETLW   b'00111101' ;3  
    7. RETLW   b'00100111' ;4  
    8. RETLW   b'00111011' ;5  
    9. RETLW   b'01111011' ;6  
    10. RETLW   b'00010101' ;7  
    11. RETLW   b'01111111' ;8  
    12. RETLW   b'00110111' ;9  
    13. RETLW   b'01110111' ;a  
    14. RETLW   b'01101011' ;b  
    15. RETLW   b'01011010' ;c  
    16. RETLW   b'01101101' ;d  
    17. RETLW   b'01111010' ;e  
    18. RETLW   b'01110010' ;f        
    Dan
     
    Last edited: Sep 28, 2013
  5. JohnInTX

    Moderator

    Jun 26, 2012
    2,339
    1,022
    Markd77 is correct. You also have a couple of other things to watch out for:
    1) If the table spans a ROM bank you'll have to compute the address with different values of PCLATH depending on the value of W. This is done using a scratch register for PCL, computing PCLATH and then moving the scratch reg to PCL, rather than adding W to PCL. The problem with addwf PCL,F is that once you do it, you are gone and can't propagate any carry (from spanning a bank) into PCLATH.
    2)You are limited to table sizes of 256 words less the lookup code unless you expressly calculate the fetch address as above.
    3)You should (must) qualify W before using it i.e. if W winds up pointing past the table end you jump into the weeds. Bye! With your case, ANDLW 0fh before using it would at least keep things in bounds. If your table size is not something you can mask i.e. 12 entries instead of 16, compare W to the actual table size and fix it if necessary before using it.
    4)If you use interrupts, you'll have to save/restore PCLATH in the service routine.

    You probably know that you have to CALL the table so that the retlw will find its way back to your lookup routine.

    I usually try to keep my midrange tables in the first 256 bytes of ROM page 0. The lookup routine can just clear PCLATH and get on with it. If they don't fit there, I at least don't allow them to span 256 word banks without special care. If the tables get really big, use something like 1) above shown in the code in this thread. It punts and just calculates the full 16 bit table address from the get go. Done!

    Finally, consider an 18F. Much easier to do this kind of thing.

    In MPLABX you can test your code using MPSIM.
    Right click the project name in the Projects window and click Properties. Click Conf:[name] where name is 'default' unless you've created a new configuration.
    Under Supported Debug Header select NONE.
    Under Hardware Tool: select Simulator.
    Rebuild for debugging by clicking DebugMainProject on the toolbar. It will build and you'll run/step etc buttons to play with.
    Click PAUSE (yellow circle) then you'll have buttons for RESET (violet) and various RUN, STEP, STEP OVER etc.
    Click RESET and commence to stepping.

    Sometimes, its useful to put a dummy goto from RESET to the code you want to test. Put a breakpoint there (right click the source line, select your breakpoint option) and run to it. In this case load W with what you want and step it through to make sure the table works. Try a few bogus values for W and see what happens.

    Have fun.
     
    techristian, absf and Eric007 like this.
  6. techristian

    Thread Starter New Member

    Aug 27, 2013
    26
    2
    Thanks John
     
  7. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,505
    2,367
    +1, I graduated to the 18f and do not miss the page switching, and I also like the method for RAM and ROM table addressing.
    Max.
     
  8. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,644
    759
    I agree. One problem less.
     
  9. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Even better to "graduate" to C, and just define a string of data. ;)
     
  10. techristian

    Thread Starter New Member

    Aug 27, 2013
    26
    2
    Two main things that I don't like about "C"....what I remember from my Amiga and 386 days.

    1) They make the program 10X larger...and with limited memory that is unacceptable. PRINT "Hello World" was over 1kb ....and larger also means slower as well.

    2) The libraries are massive. For Windows, I think that there were at least 20 different OpenWindow() commands , each with its own set of HOOKS.

    I don't know how this plays out on PIC devices, but I don't like inserting a whole library in to just do one simple thing.

    Dan
     
    Eric007 likes this.
  11. joeyd999

    AAC Fanatic!

    Jun 6, 2011
    2,673
    2,715
    I agree with you 100%. And for more reasons than you stated. But you won't find many takers here.
     
  12. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    My experience is different. I check the compiler output, and keep my code very small and fast even though it is written in C. In many cases the final amount of ROM used is similar to when I worked in assembler, small enough that it does not matter.

    For your specific example (a table read of X bytes) in C it will compile the string to become RETLW instructions, one per byte, which is exactly the same ROM usage as you get with assembler. So it's much much easier to handle data tables and the code is no larger.

    C compilers for 8bit micros are much tighter, and are not really comparable to the massively bloated Windows C compilers.
     
Loading...