|
|
View previous topic :: View next topic |
Author |
Message |
osu1177
Joined: 10 Feb 2011 Posts: 14
|
using pointers to display characters from arrays |
Posted: Tue Nov 29, 2011 3:35 pm |
|
|
Hi All,
I have spent quite a bit of time trying to educate myself on pointers and how they can be used to display characters from large arrays. I even have (presumably) working code for the screen I am working with. However, the compiler gives me a syntax error, and when I try to simplify things, I only get more errors.
I hate to ask such easy questions, but I am having trouble finding the answers on my own. I am posting here the entirety of the code I am trying to get working, without showing what modifications I have made. Perhaps it is just one thing wrong that I am overlooking.
here is the first line of code which gives me problems:
Code: | unsigned char *FontTable[] = {(unsigned char *)(FONT6x8, (unsigned char *)FONT8x8, (unsigned char *)FONT8x16}; |
the error I receive is "bad expression syntax."
Here is the entire code:
Code: | void LCDPutChar(char c, int x, int y, int size, int fColor, int bColor) {
int i,j;
unsigned int nCols;
unsigned int nRows;
unsigned int nBytes;
unsigned char PixelRow;
unsigned char Mask;
unsigned int Word0;
unsigned int Word1;
unsigned char *pFont;
unsigned char *pChar;
unsigned char *FontTable[] = {(unsigned char *)FONT6x8, (unsigned char *)FONT8x8,
(unsigned char *)FONT8x16};
// get pointer to the beginning of the selected font table
pFont = (unsigned char *)FontTable[size];
// get the nColumns, nRows and nBytes
nCols = *pFont;
nRows = *(pFont + 1);
nBytes = *(pFont + 2);
// get pointer to the last byte of the desired character
pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
// Row address set (command 0x2B)
WriteSpiCommand(PASET);
WriteSpiData(x);
WriteSpiData(x + nRows - 1);
// Column address set (command 0x2A)
WriteSpiCommand(CASET);
WriteSpiData(y);
WriteSpiData(y + nCols - 1);
// WRITE MEMORY
WriteSpiCommand(RAMWR);
// loop on each row, working backwards from the bottom to the top
for (i = nRows - 1; i >= 0; i--) {
// copy pixel row from font table and then decrement row
PixelRow = *pChar--;
// loop on each pixel in the row (left to right)
// Note: we do two pixels each loop
Mask = 0x80;
for (j = 0; j < nCols; j += 2) {
// if pixel bit set, use foreground color; else use the background color
// now get the pixel color for two successive pixels
if ((PixelRow & Mask) == 0)
Word0 = bColor;
else
Word0 = fColor;
Mask = Mask >> 1;
if ((PixelRow & Mask) == 0)
Word1 = bColor;
else
Word1 = fColor;
Mask = Mask >> 1;
// use this information to output three data bytes
WriteSpiData((Word0 >> 4) & 0xFF);
WriteSpiData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
WriteSpiData(Word1 & 0xFF);
}
}
// terminate the Write Memory command
WriteSpiCommand(NOP);
} |
I would be happy to explain all of the modifications I have made, if necessary, but at this point, I think it'd be easier to get this code running with as little changes as possible. I can also post the entirety of the given code (James Lynch Nokia 6100 tutorial).
I apologize for the lack of formatting, and give a great thanks for your time in helping me. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Tue Nov 29, 2011 3:55 pm |
|
|
The line as posted, has an extra bracket in front of the FONT6x8 declaration, which probably causes the current error.
However there are other probable problems/limitations.
First question is how the fonts themselves are declared?.
FONT6x8 etc....
Limitation of the PIC, is that it is more complex than a conventional linear address map chip, if it comes to addressing data stored in the ROM. It has two separate memory 'spaces', not a single linear memory space like most chips. This means that if the tables are stored as 'const', you can't simply generate pointers to this. You need to use the ROM declaration, which adds code to handle the extra addressing, and declare the pointers as pointers to ROM.
Second point is that you need to declare the table, and then load the values separately. So (if the tables are in RAM):
Code: |
unsigned char *FontTable[3];
FontTable[0] = (unsigned char *)FONT6x8;
FontTable[1] = (unsigned char *)FONT8x8;
FontTable[2] = (unsigned char *)FONT8x16;
|
This is down to not being able to construct the required addresses at compile time.
Best Wishes |
|
|
osu1177
Joined: 10 Feb 2011 Posts: 14
|
|
Posted: Tue Nov 29, 2011 4:43 pm |
|
|
Hi Ttelmah,
I removed the first bracket but it still gave me a syntax error...but lets skip that for a moment and perhaps fix the other problems.
I am declaring my fonts before the function declaration. Here is exactly how it appears (
I have omitted two of the font tables):
Code: | const unsigned char FONT6x8[97][8] = {
0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, // !
0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00, // "
0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00, // #
0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00, // $
0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00, // %
0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00, // &
0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00, // '
0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00, // (
0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00, // )
0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00, // *
0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, // +
0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, // ,
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, // -
0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00, // .
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, // / (forward slash)
0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00, // 0 0x30
0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, // 1
0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00, // 2
0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00, // 3
0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00, // 4
0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00, // 5
0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00, // 6
0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00, // 7
0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00, // 8
0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00, // 9
0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00, // :
0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00, // ;
0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00, // <
0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00, // =
0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00, // >
0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00, // ?
0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00, // @ 0x40
0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00, // A
0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00, // B
0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00, // C
0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00, // D
0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00, // E
0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00, // F
0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00, // G
0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00, // H
0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, // I
0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00, // J
0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00, // K
0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00, // L
0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00, // M
0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00, // N
0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00, // O
0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00, // P 0x50
0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00, // Q
0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00, // R
0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00, // S
0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00, // T
0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, // U
0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00, // V 0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00, // W
0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00, // X
0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, // Y
0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00, // Z
0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00, // [
0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00, // \ (back slash)
0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00, // ]
0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00, // ^
0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, // _
0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00, // ` 0x60
0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00, // a
0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00, // b
0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00, // c
0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00, // d
0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00, // e
0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00, // f
0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70, // g
0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00, // h
0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, // i
0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00, // j
0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00, // k
0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, // l
0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00, // m
0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00, // n
0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00, // o
0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80, // p 0x70
0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08, // q
0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00, // r
0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00, // s
0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00, // t
0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00, // u
0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00, // v
0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00, // w
0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00, // x
0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70, // y
0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00, // z
0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00, // {
0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, // |
0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00, // }
0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00, // ~
0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00}; // DEL
void LCDPutChar(char c, int x, int y, int16 fColor, int16 bColor) {
int16 i,j;
unsigned int nCols;
unsigned int nRows;
unsigned int nBytes;
unsigned char PixelRow;
unsigned char Mask;
unsigned int Word0;
unsigned int Word1;
unsigned char *pFont;
unsigned char *pChar;
unsigned char *FontTable[] = {(unsigned char *)(FONT6x8, (unsigned char *)FONT8x8, (unsigned char *)FONT8x16;
|
..etc.
So you are correct, I have used the wrong declarations for the font tables. I will do a bit more research tonight to find how to change them from constants to ROMs, and see if it affects my output.
Thanks so far! |
|
|
osu1177
Joined: 10 Feb 2011 Posts: 14
|
|
Posted: Tue Nov 29, 2011 4:44 pm |
|
|
I forgot to mention, your second piece of advice regarding how to declare the font tables is working fine. Thank you! |
|
|
osu1177
Joined: 10 Feb 2011 Posts: 14
|
|
Posted: Wed Nov 30, 2011 2:48 pm |
|
|
Ttelmah,
I have been trying a few things with not too much luck, and now I am trying to make sure I understand you correctly. Correct me if I am wrong, but pointer operations require that the elements of the array be stored in one consecutive, uninterrupted sequence. If a PIC splits this into two locations, than the pointers may produce errors, unless the arrays are declared in such a way as to compensate for this.
So, if that is the case, how can I fix this error, exactly? What kind of declarations do I have to make? Will it also involve redoing some of the pointer-related code?
Right now, I am declaring my arrays, in the same location as before (right before the routine), with this Code: | static rom byte FONT6x8[97][8] = ... |
is that correct?
Here is the entire routine, please see earlier code example to see where I stored my arrays:
Code: |
void LCDPutChar(char c, int x, int y, int size, int fColor, int bColor) {
int16 i,j;
unsigned int nCols;
unsigned int nRows;
unsigned int nBytes;
unsigned char PixelRow;
unsigned char Mask;
unsigned int Word0;
unsigned int Word1;
unsigned char *pFont;
unsigned char *pChar;
unsigned char *FontTable[3];
FontTable[0] = (unsigned char *)FONT6x8;
FontTable[1] = (unsigned char *)FONT8x8;
FontTable[2] = (unsigned char *)FONT8x16;
//unsigned char *FontTable[] = {(unsigned char *)FONT6x8, (unsigned char *)FONT8x8, (unsigned char *)FONT8x16};
// get pointer to the beginning of the selected font table
pFont = (unsigned char *)FontTable[size];
// get the nColumns, nRows and nBytes
nCols = *pFont;
nRows = *(pFont + 1);
nBytes = *(pFont + 2);
// get pointer to the last byte of the desired character
pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
// Row address set (command 0x2B)
WriteSpiCommand(PASET);
WriteSpiData(x);
WriteSpiData(x + nRows - 1);
// Column address set (command 0x2A)
WriteSpiCommand(CASET);
WriteSpiData(y);
WriteSpiData(y + nCols - 1);
// WRITE MEMORY
WriteSpiCommand(RAMWR);
// loop on each row, working backwards from the bottom to the top
for (i = nRows - 1; i >= 0; i--) {
// copy pixel row from font table and then decrement row
PixelRow = *pChar--;
// loop on each pixel in the row (left to right)
// Note: we do two pixels each loop
Mask = 0x80;
for (j = 0; j < nCols; j += 2) {
// if pixel bit set, use foreground color; else use the background color
// now get the pixel color for two successive pixels
if ((PixelRow & Mask) == 0)
Word0 = bColor;
else
Word0 = fColor;
Mask = Mask >> 1;
if ((PixelRow & Mask) == 0)
Word1 = bColor;
else
Word1 = fColor;
Mask = Mask >> 1;
// use this information to output three data bytes
WriteSpiData((Word0 >> 4) & 0xFF);
WriteSpiData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
WriteSpiData(Word1 & 0xFF);
}
}
// terminate the Write Memory command
WriteSpiCommand(NOP);
} |
I am eternally grateful for any help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Wed Nov 30, 2011 4:52 pm |
|
|
Unfortunately, pointers to ROM, are one of those features that only approximately 50% works. It works find, if you just 'read' a pointer, or if you use a single pointer to something, but arrays of these pointers, or complex usage with arrays pointing to arrays, requires you to be 'sneaky'.
Now, yes, a _single_ pointer to an object, needs to point to an object that is consecutive in memory, _but_ if you are using multiple pointers in an array, these can point to objects scattered all over memory.
I've found that where you have an array of rom* pointers, the system just goes screwy. However if you jast save them as integers, and then cast them to pointers or transfer them one by one into a simple pointer, this then works fine.
So:
Code: |
//Your chip defines and fuses here
#use rs232(baud=9600,parity=N,UART1,ERRORS)
char rom array1[10] = {1,2,3,4,5,6,7,8,9,10};
int8 rom extraval = 10; //Here to show the arrays do _not_ have to be together
char rom array2[10] = {4,5,6,7,8,9,10,11,12,13};
char rom array3[10] = {10,11,12,13,14,15,16,17,18,19};
void dummy(void) { //Dummy routine - never used prevents compiler error on RS232_ERRORS
int8 i; //Optimiser removes this, so no RAM/ROM wasted....
i=RS232_ERRORS;
}
void main()
{
char cval;
int8 i,n;
int16 ptr_array[3];
char rom* ptr;
ptr_array[0]=array3;
ptr_array[1]=array2;
ptr_array[2]=array1; //Arrays in reverse order for demo
do {
for (n=0;n<3;n++) {
ptr=ptr_array[n]; //de-reference from the array
for (i=0;i<10;i++) {
cval=*(ptr+i);
printf("%u ",cval);
}
printf("\n\r");
}
delay_ms(1000);
} while (TRUE);
}
|
Merrily produces:
Code: |
10 11 12 13 14 15 16 17 18 19
4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10
|
From the three separate arrays stored in ROM. Not elegant, and 'kludge upon kludge' to get it to work, but it does work.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|