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
