I'm fairly new to PIC programming, but was wondering what approach people use when storing text strings in PICs to take up the least amount of program area, but be easily accessible. The strings are mainly to be used in menus and messages to be displayed via a serial interface.

Any pointer will be greatfully received.


Posted on 2004-04-01 09:20:29 by Nick
Just use a retlw (return from call, literal in W). Place the character byte in the working (W) register. Efficient, uses 1 program instruction per byte.

If you use something like EEPROM (on pic or off), then a zero terminated string works nice. So would something akin to a BSTR or Pascal string (length prefixed string).

movlw (move literal to W) would also work if you inline the string with code and want the data for immediate processing.
Posted on 2004-04-01 14:19:21 by Ernie
Thanks, those are the methods I'd seen used in sample code, I was just curious if there were any other methods people used.

Posted on 2004-04-02 03:19:28 by Nick
With only 33 opcodes to choose from, you don't get many options. ;-)

My personal favorite weird string code example was in some sample code for USB stuff on a PIC. Strings returned during ewnumeration are speced to be in unicode, and sure enough, they were stored inside the PIC as long strings of pairs of retlw's.... every other one a zero byte!
Posted on 2004-04-02 21:38:07 by Ernie
The easiest way to store strings in the program memory is to use the Define Table directive.
It will generate the retlw instructions for you. If you include anything in quotation marks, it will place retlw instructions that return the ASCII characters you need. Without quotation marks, it places retlw value.

<label> dt "My message",0

This will assemblelike this:

retlw 'M'
retlw 'y'
retlw 'm'
retlw 0

This is exactly what you need and it's much easier to use. It takes less typing, too.
Posted on 2004-04-05 12:06:09 by VVV
Ya this is something i receintly learned about MPASM. I should have done this along ago, but its worth taking some time and snooping through the index of the help file for the assembler. This 'DT' command was something that surprised me as well, seing no one actually uses it! (Asside from VVV that is ;) ).
Posted on 2004-04-27 18:00:06 by NaN
I've now had quite a lot of success using the dt command. But does anyone have an easy way to make a generic string printing function or macro, that can return different strings depending on a parameter passed in?

e.g. PrintString szVersion
PrintString szAnotherString

Where szVersion and szAnotherString are the labels that point to the set of retlw instructions that contain each string.

Any ideas greatfully recieved


Posted on 2004-04-28 06:51:08 by Nick
If the strings are in the first 256 locations (to avoid problems), one approach you can try is this:

GetChar: movwf PCL ;transfer low byte of address to PCL, which causes a jump to that address, PCH is not altered
szVersion: dt 'Version', 0 ;these, of course assemble as retlw instructions, so it does not matter that the PC was altered,
szAnotherString: dt 'Another String', 0 ;since the return addr will be popped off the stack into PC and take you back to after the call GetChar

Your print routine will place the address of the string in W:

movlw szVersion ;load address of version string in W
call GetChar ;this saves the PC onto the HW stack and jumps to GetChar
Posted on 2004-04-28 12:01:00 by VVV
I'm sure I tried what you suggested, "movlw szVersion", and got a assembler error - maybe I didn't, and should try it again.


Posted on 2004-04-28 12:09:08 by Nick
Hi, Nick,

Here is an actual snipet from an older program of mine. I have deleted unimportant things.
I just ran this and it works.
Posted on 2004-04-28 19:05:19 by VVV
Hi, Nick,

I think the error you got was due to the fact that szVersion was not in the first 256 words of program memory. So the movlw szVersion generated the error, since it can only accept 8-bit values.

Therefore, you either place the strings in the first 256 words of program memory as I suggested in a previous post, or, if you place them in the first 256 locations of another page, then modify the movlw to read:

movlw szVersion-256 ;for example for Page1, or

movlw szVersion-512 ;for example for Page2

The point is that the expresion evaluates to an 8-bit value.

Note that the ENTIRE strings, including the terminating 0's, must be within the first 256 locations of the page, since the movwf PCL instruction clears bit 8 of the program counter.
Posted on 2004-04-29 11:51:08 by VVV
Thanks for that, you are probably right, I have put my string table in the last page of program memory.

I'll try your suggestion and see if I can get it to work, using your snippet as a guide.

The reason I want an easy, simple way to do this for many strings is that I need to return them either to a serial interface, or have them available for putting into network frames that are being generated by the PIC.

Posted on 2004-04-29 12:17:33 by Nick