STRINGS -
How to store and retrieve strings in Code Space
(for Picbasic Pro)
by Darrel Taylor
MPASM has a directive called "DA" that generates a packed 14-bit number representing two 7-bit ASCII characters. This allows you to put large strings in half the code space used by "DB" in PM or 1/8 the code space used when embedding strings in an Hserout statement. In a large program this can easily save several hundred words of code space.
I won't go into to much detail here because I think the program is pretty Self-Explanatory.
Using this routine requires MPASM as the compiler. It will NOT work with PM.
There are 2 versions shown here. The first example is for a 14-bit PIC such as a 16F877 or 12F675. The second example will work on 16-bit devices like the 18Fxxxx.
Many thanks to John Barrat for solving my biggest problem of Forward Declarations in a Macro. With the new GetAddress macro, strings can now be located anywhere in the program.
'**************************************************************** '* Name : STRINGS.PBP * '* Author : Darrel Taylor / John Barrat * '* Date : 5/30/2003 * '* Note: Strings must be NULL Terminated * '**************************************************************** DEFINE LOADER_USED 1 ' If using bootloader DEFINE OSC 4 DEFINE HSER_TXSTA 24h ' Use this for Higher Baud Rates DEFINE HSER_SPBRG 25 ' 9600 Baud at 4mhz Addr var word TwoChars var word Char var byte Clear goto StartLoop ' Required String1: @ da "This is a string",0 AnotherString: @ da "Here is another string",0 '------------GetAddress Macro - Location insensitive ------------------------- ASM GetAddress macro Label, Wout ; Returns the Address of a Label as a Word CHK?RP Wout movlw low Label movwf Wout movlw High Label movwf Wout + 1 endm ENDASM StartLoop ' This loop repeats continuously just as a test. @ GetAddress _String1, _Addr ' Get address of String gosub StringOut ' Send the String hserout [13,10] ' New Line @ GetAddress _AnotherString, _Addr ' Get address of String gosub StringOut ' Send the String hserout [13,10] ' New Line pause 500 goto StartLoop ' Repeat StringOut: ' Send the string out via Hserout Readcode Addr, TwoChars ' Get the 14 bit packed characters Char = TwoChars >> 7 ' Separate first char if Char = 0 then StringDone ' Look for Null char, Stop if found hserout [Char] ' Send first char Char = TwoChars & $7F ' Separate second char if Char = 0 then StringDone ' Look for Null char, Stop if found hserout [Char] ' Send the second char Addr = Addr + 1 ' Point to next two characters goto StringOut ' Continue with rest of the string StringDone: return end
For use with 16-bit PIC's
The 16-bit PIC's work with things as bytes instead of words, so it actually becomes easier to extract the strings. Instead of reading 2 characters at a time, you only have to get 1. Here is a modification to the strings program above for use with PIC18x chips.
The only real difference is in the StringOut routine.
'**************************************************************** '* Name : STRINGS-16.PBP * '* Author : Darrel Taylor * '* Date : 6/12/2005 * '* Note: Strings must be NULL Terminated * '**************************************************************** DEFINE LOADER_USED 1 ' If using bootloader DEFINE OSC 4 DEFINE HSER_TXSTA 24h ' Use this for Higher Baud Rates DEFINE HSER_SPBRG 25 ' 9600 Baud at 4mhz Addr var word Char var byte Clear goto StartLoop ' Required String1: @ da "This is a string",0 AnotherString: @ da "Here is another string",0 '------------GetAddress Macro - Location insensitive ------------------------- ASM GetAddress macro Label, Wout ; Returns the Address of a Label as a Word CHK?RP Wout movlw low Label movwf Wout movlw High Label movwf Wout + 1 endm ENDASM StartLoop ' This loop repeats continuously just as a test. @ GetAddress _String1, _Addr ' Get address of String gosub StringOut ' Send the String hserout [13,10] ' New Line @ GetAddress _AnotherString, _Addr ' Get address of String gosub StringOut ' Send the String hserout [13,10] ' New Line pause 500 goto StartLoop ' Repeat StringOut: ' Send the string out via Hserout Readcode Addr, Char ' Get a character if Char = 0 then StringDone ' Look for Null char, Stop if found hserout [Char] ' Send char Addr = Addr + 1 ' Point to next character goto StringOut ' Continue with rest of the string StringDone: return end
For more information about strings, and other approaches, see this thread see this thread