Laurent Chouinard
Joined: 12 Sep 2003 Posts: 43
|
CODE SAMPLE: Using pointers to constants for string storage |
Posted: Wed Dec 12, 2007 12:19 pm |
|
|
After several hours of development, I finally came up with a half-decent solution to the famous problem of easily accessing strings stored in ROM via the use of pointers. Furthermore, my approach permits the use of the flexible array storage that compiler v4 now permits, which saves some considerable space when using a wide array of text strings.
I've decided to share my code with the community, by posting it here, in case it may be useful to someone.
Note that this is half a hack, but so far, it's working very nicely in my tests.
Oh, this is multilingual, too. You can have many languages and the code will chose the correct strings.
Code: |
#include <18F6722.h>
#include <string.h>
#define LCD_TYPE_WIDTH 20 //This lcd has 20 characters wide
#define ALIGN_LEFT 1
#define ALIGN_RIGHT 2
#define ALIGN_CENTER 3
//This is the buffer that LCD routines will use to output
int8 bufferLcdFinal[LCD_TYPE_WIDTH + 1];
//All messages go here
int8 const *msgGreet[] = {"Hello", "Bonjour", "Hola"};
void main(void) {
int8 currentLanguage;
currentLanguage = 1; //From now on, display in French.
MsgSend(&msgGreet, currentLanguage);
}
void MsgSend(int32 msgAddress, int8 language, int8 align) {
int8 buffer[LCD_TYPE_WIDTH + 1]; //Temp RAM storage
//Actual address of the text in the chosen language:
int32 languageMsgAddress;
int8 i, msgLength = 0, startPosition;
//Read the CCS compiled address of our sub-string
read_program_memory(address + (language * 2), &languageMsgAddress, 2);
//Copy the string into the temporary RAM buffer, for formatting
read_program_memory(languageMsgAddress, buffer, LCD_TYPE_WIDTH);
for (i = 0; i < LCD_TYPE_WIDTH; i++) { //Fills with spaces
bufferLcdFinal[i] = ' ';
}
msgLength = strlen(buffer);
switch (align) { //Picks the correct start position for alignment
case ALIGN_CENTER: startPosition = (LCD_TYPE_WIDTH - msgLength) / 2; break;
case ALIGN_LEFT: startPosition = 0; break;
case ALIGN_RIGHT: startPosition = LCD_TYPE_WIDTH - msgLength; break;
}
//We copy the message into the final buffer at the correct position.
//Note that we use strncpy instead of strcpy to avoid writing
//a terminating 0x00 at the end.
strncpy(bufferLcdFinal + startPosition, buffer, msgLength);
//Here, bufferLcdFinal is ready to be sent to your display device.
}
|
|
|