|
|
View previous topic :: View next topic |
Author |
Message |
Oli Guest
|
Optimising LCD routines. |
Posted: Fri Feb 12, 2010 9:36 am |
|
|
Hi All
I'm using a PIC24FJGB110 and a 128x 128 LCD. I have some animation going on the LCD and at the moment, it needs the core running at 32Mhz to be able to achieve the necessary frames per second. It is a battery powered application so any power savings would make a big difference - I am already aware of clock switching but want to optimise my code before taking this path
I have written all of the libraries and know they could run MUCH quicker, but I'm a bit lost on where to start.
The orientation of the display can be changed in the program, so I have performed transforms on each pixel before writing it to the buffer.
Firstly, the buffer is:
Code: | int8 glcd_buffer[GLCD_BYTES]; |
and
Code: | #define GLCD_WIDTH 128
#define GLCD_HEIGHT 128
#define GLCD_ROWS (LCD_HEIGHT/8)
#define GLCD_BYTES 2048 // 128 x 128 / 8; |
So to write a pixel to the buffer:
Code: | void glcd_pixel(int8 x, int8 y, int8 colour)
{
int8* p;
int8 position_temp; // temporarily stores
int16 temp;
if ((x >= GLCD_WIDTH) || (x < 0))
return;
#ifdef ROTATE_GLCD
position_temp = x;
switch (glcd_angle)
{
case 0: x = y;
y = GLCD_HEIGHT - position_temp - 1; break;
case 90: break;
case 180: x = GLCD_WIDTH - y - 1;
y = position_temp;
break;
case 270: break;
}
#endif
temp = y/8;
temp *= 128;
temp += x;
p = glcd_buffer + temp;
if(colour)
{
bit_set(*p, y%8);
}
else
{
bit_clear(*p, y%8);
}
} |
then to write from the buffer to the LCD, I use:
Code: | void glcd_update(void)
{
int16 i;
glcd_goto_position(0,0);
// Loop through the vertical pages
for(i = 0; i < GLCD_BYTES; i++)
{
glcd_data_write(glcd_buffer[i]); // Turn pixels on or off
}
} |
which uses:
Code: | void glcd_data_write(BYTE data)
{
WRITE_LCD_PORT(data);
output_bit(LCD_CSB, 0);
output_bit(LCD_WR, 0);
output_bit(LCD_WR, 1);
output_bit(LCD_CSB, 1);
} |
which then uses the following Macro:
Code: | #define WRITE_LCD_PORT(x) \
output_bit(LCD_D0, (x & 1)); \
output_bit(LCD_D1, ((x >> 1) & 1)); \
output_bit(LCD_D2, ((x >> 2) & 1)); \
output_bit(LCD_D3, ((x >> 3) & 1)); \
output_bit(LCD_D4, ((x >> 4) & 1)); \
output_bit(LCD_D5, ((x >> 5) & 1)); \
output_bit(LCD_D6, ((x >> 6) & 1)); \
output_bit(LCD_D7, ((x >> 7) & 1)); |
If you have any suggestions to optimise any of the above code, please let me know! (or any other general tips). Immediately, the WRITE_LCD_PORT comes to mind because of the number of bit shifts...but I'm not sure how to change it.
Many thanks in advance |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Feb 12, 2010 4:18 pm |
|
|
When intending optimization, it'a good idea to check, how the compiler treats particular C constructs.
In your WRITE_LCD_PORT(x) macro, each line with a bit shift is converted to not less than 10 machine
instructions by PCD. Code: | output_bit(LCD_D2, ((x >> 2) & 1)); |
Using bit_test() instead reduces the amount by four. Having ordered pins for the LCD interface only consumes two
instructions to write x to the port. So it's clear, what optimization means first - using appropriate hardware connections.
The next point is analysing which lines of code are executed most often and try to make them lightweight. |
|
|
|
|
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
|