I have written some code (My main file is about 250 lines long) and I have been trying to test it. If I comment all except the first little bit of my code, it performs exactly as I expect when I test it on the LCD and keypad. Naturally then I uncomment a little bit more, and when I try to test it, part way through the operation, it reverts back to the beginning of the code. 
I was thinking there was an error in the code I had written, so I tried debugging it in a number of different ways but I could not find any problem with it. So I instead tried commenting out the beginning part of my code, and then testing it and it performed perfectly. This led me to believe the problem was something to do with the length of my code. To test my theory I tried putting blank spaces or "nop's" into my code and as the code got longer, it reverted back to the first line of code earlier and earlier through operation (what I mean by earlier through operation is that since I am dealing with the user interface, I am progressing screen by screen as a user would. As I include more nop statements, it gets through less screens before jumping back to the first line [the standby screen]). 
Any ideas?

Views: 405


You need to be a member of Personal Mechatronics Lab to add comments!

Join Personal Mechatronics Lab

Comment by Hollis Milroy on February 28, 2011 at 6:43pm

This is an old thread, but in case ppl still refer back to it:

I only have one org statement.

My code is in multiple files, and it compiles and loads my main.asm code and then my lcd.asm back to back in program memory.

Also, I had to put everything, including my definitions, equates, variables, and macros after my org 0x00 statement (and after my tables)

Comment by Matt Nejati on January 27, 2011 at 11:40pm
Thanks for the heads up
Comment by Valentin on January 27, 2011 at 10:20pm


I've researched this thoroughly and looked through a ton of code from my project last year.


There IS in fact a 256 byte boundary (in program memory) at the beginning of the code within which all tables must be stored. Note this isn't 256 lines, but bytes - best viewed after compiling and selecting View > Program Memory and making sure there are no tables after 256 bytes.


I remember having to cut down on my tables last year because of this.


I've also found a forum post where clever manipulation of the PCLATH register allows for larger tables. However this may be a little complicated and I would just suggest keeping the tables compact.



Comment by Matt Nejati on January 27, 2011 at 10:05pm

I tried rearranging my code to include my DT statements on top as you guys suggested and everything seems to be working fine. 


My LCD.asm still starts at 0x700 and it is still separate so it seems as the problem was the DT statements.


Thanks guys for the help 

Comment by Yifan Wang on January 27, 2011 at 9:21am
If there is a certain length of code coming before the DT (define table) directive, then characters/entries in the DT past a certain point will fail to return a value. Instead, upon reaching that character, the program will restart from the beginning.

Remember, or realize, that DT is actually a short form for a long list of retlw instructions. That means that having a DT holding a long string counts as many instructions.

This does NOT appear to be an issue of crossing the 2000 line limit, because I counted my lines and each character in the DTs, and I am still a good ways away from the next program memory page.

I spent hours working this out. Our book was not helpful at all. I had many theories and many false leads. Unless we hear official word from someone more experienced, my reccomendation would be to keep your DTs at or near the top of your code.
Comment by Yifan Wang on January 27, 2011 at 9:20am
also, you should keep the LCD.asm at the beginning of your program mem, say 0x0100, and your code can begin in some later time say 0x0150, so you have the rest of the program mem for your main code if you wish to separate your .asm files
Comment by Yifan Wang on January 27, 2011 at 9:18am

I've seen one of my student in my lab session came across the very same problem. The quickest way to fix this is just to have everything in the same .ASM file.


I haven't figured out exactly why the code is behaving this way, but the PC is set back to 0 in the function calls between the two .asm files, and thus making your code revert back to the beginning.


A good way to debug if you want to, is to find the register that store the return address of a function call, trace it, and see exactly at which point did your PC's value was erased. 

Comment by Valentin on January 27, 2011 at 1:05am

You shouldn't have to. Because tables take up a big chunk of program memory, they may also become a problem. I've looked over some of my code from last year and here is how it's structured:








org 0x00 ;reset vector (power on)

goto main

org 0x04 ;interrupt service routine

{ interrupt code here }

retfie ;return from interrupt



addwf PCL,f

dt "ABC",0


;main program


{your main code}




Unfortunately my code wasn't broken down into multiple source files (I had one huge one). But I remember that you have to be cautious with org statements in multiple source files.


A good way to debug would be to use the View Disassembly function in MPLAB as you step through the code with the debugger to see exactly when and where your program is jumping to another place. I have a feeling it never makes it to lcd.asm. Keep trying and updating!

Comment by Matt Nejati on January 26, 2011 at 11:20pm

I am using the LCD/Keypad sample code which I have just modified. I had already moved the LCD.asm code to begin at 0x500 and it wasn't working so I tried it at 0x700 and the same thing happened with no noticeable difference in how far the code went before jumping back to the beginning again. 


I am assuming this means I am going to have to move some of my code to a different page in memory for it to work?

Comment by Valentin on January 26, 2011 at 11:03pm

This problem has come up a number of times so I advise all microcontroller members to read the following.


From what I can tell:

You're using the LCD/Keypad sample code. In this code, your main.asm begins placing instructions at 0x000. However a number of subroutines are also outlined in lcd.asm. The key thing here is that lcd.asm begins at 0x100 (from what I can remember). Therefore, once the code in your main moves into this region, you have a conflict between the two source files trying to use the same program memory locations.


To fix this:

Try changing the "org 0x100" in lcd.asm to "org 0x300". This will move the LDC subroutines to 0x300 and on, and give you more space to write code in your main. 

Note: from what I can remember, lcd.asm takes up about 0x50 lines in total. So moving to 0x800-0x50 (length of one page minus length of lcd) will yield the most free space for main. I may be wrong in exact lengths so double check this.


Bottom line:

Be sure to organize your program memory and always keep an eye on its length, especially with multiple source files!

© 2024   Created by PML.   Powered by

Badges  |  Report an Issue  |  Terms of Service