CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Graphic LCD
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

Graphic LCD
PostPosted: Tue Jul 25, 2017 2:36 am     Reply with quote

I'm using PIC18F2520, Internal oscillator: 1MHz trying to interface with Graphic LCD: EA DOGM128W-6 (128 x 64 DOTS).

Below is the sample program:
Code:
#include "18F2520.h"
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP      // Internal oscillator
#use delay(clock=1000000)

const unsigned char numbers_22[10][48] = {

{0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xF0, 0xFF, 0x03,  0xFC, 0xFF, 0x0F,
 0xFC, 0xFF, 0x0F, 0x3E, 0x00, 0x1F, 0x0E, 0x00, 0x1C,  0x0E, 0x00, 0x1C,
 0x0E, 0x00, 0x1C, 0x3E, 0x00, 0x1F, 0xFC, 0xFF, 0x0F,  0xFC, 0xFF, 0x0F,
 0xF0, 0xFF, 0x03, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00},      //   0

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x01, 0x00,
 0xE0, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0xFF, 0x1F,
 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   1

{0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x78, 0x00, 0x1E, 0x7C, 0x80, 0x1F,
 0x7C, 0xC0, 0x1F, 0x1E, 0xE0, 0x1F, 0x0E, 0xF0, 0x1D, 0x0E, 0xF8, 0x1C,
 0x0E, 0x7C, 0x1C, 0x1E, 0x3E, 0x1C, 0xFE, 0x1F, 0x1C, 0xFC, 0x0F, 0x1C,
 0xF8, 0x07, 0x1C, 0xF0, 0x01, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   2

{0x00, 0x00, 0x00, 0x30, 0x80, 0x01, 0x38, 0x80, 0x07, 0x3C, 0x80, 0x0F,
 0x3E, 0x80, 0x0F, 0x1E, 0x00, 0x1E, 0x0E, 0x07, 0x1C, 0x0E, 0x07, 0x1C,
 0x9E, 0x07, 0x1C, 0xFE, 0x0F, 0x1E, 0xFC, 0xFF, 0x1F, 0xF8, 0xFD, 0x0F,
 0xF0, 0xF8, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   3

{0x00, 0xF8, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xDE, 0x01, 0x00, 0xCF, 0x01,
 0x80, 0xC7, 0x01, 0xC0, 0xC3, 0x01, 0xE0, 0xC1, 0x01, 0xF0, 0xC0, 0x01,
 0xF8, 0xFF, 0x1F, 0xFC, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F,
 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   4

{0x00, 0x00, 0x00, 0x00, 0x07, 0x03, 0xF8, 0x07, 0x07, 0xFE, 0x07, 0x0F,
 0xFE, 0x07, 0x1F, 0x1E, 0x03, 0x1E, 0x8E, 0x03, 0x1C, 0x8E, 0x03, 0x1C,
 0x8E, 0x03, 0x1C, 0x8E, 0x07, 0x1E, 0x8E, 0xFF, 0x1F, 0x0E, 0xFF, 0x0F,
 0x0E, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   5

{0x00, 0x00, 0x00, 0x80, 0xFF, 0x00, 0xF0, 0xFF, 0x03, 0xF8, 0xFF, 0x07,
 0xFC, 0xFF, 0x0F, 0x3C, 0x0E, 0x1E, 0x0E, 0x07, 0x1C, 0x0E, 0x07, 0x1C,
 0x0E, 0x07, 0x1C, 0x1E, 0x0F, 0x1E, 0x3E, 0xFF, 0x0F, 0x3C, 0xFE, 0x0F,
 0x38, 0xFC, 0x07, 0x30, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   6

{0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x1E,
 0x0E, 0xE0, 0x1F, 0x0E, 0xFC, 0x1F, 0x0E, 0xFF, 0x1F, 0x8E, 0xFF, 0x01,
 0xEE, 0x1F, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x01, 0x00, 0x7E, 0x00, 0x00,
 0x3E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   7

{0x00, 0x00, 0x00, 0xF0, 0xE0, 0x03, 0xF8, 0xF1, 0x07, 0xFC, 0xFB, 0x0F,
 0xFE, 0xFF, 0x0F, 0x1E, 0x1F, 0x1E, 0x0E, 0x0E, 0x1C, 0x0E, 0x0E, 0x1C,
 0x0E, 0x0E, 0x1C, 0x1E, 0x1F, 0x1E, 0xFE, 0xFF, 0x0F, 0xFC, 0xFB, 0x0F,
 0xF8, 0xF1, 0x07, 0xF0, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},      //   8

{0x00, 0x00, 0x00, 0xE0, 0x03, 0x03, 0xF8, 0x0F, 0x0F, 0xFC, 0x1F, 0x0F,
 0xFC, 0x3F, 0x1F, 0x1E, 0x3C, 0x1E, 0x0E, 0x38, 0x1C, 0x0E, 0x38, 0x1C,
 0x0E, 0x38, 0x1C, 0x1E, 0x1C, 0x0F, 0xFC, 0xFF, 0x0F, 0xF8, 0xFF, 0x07,
 0xF0, 0xFF, 0x03, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}      //   9
};   

#include "st7565.h"
#include "st7565-config.h"
#include "st7565.c"

void clear_screen();
void temp_display(char address, char upper_address, char lower_address);
void fill_screen();

char temp_value[8];
unsigned int i = 0;
int16 k;

void main()
{
//   setup_oscillator(OSC_32MHZ); //This automatically selects the PLL
   setup_comparator (NC_NC_NC_NC);      // Disable comparator

   output_low(PIN_B3);
   
   glcd_init();
   clear_screen();
   glcd_command(0xAF);      // display ON
   glcd_contrast(7, 17);
   
   clear_screen();

   fill_screen();
   clear_screen();

   while(1)
   {   
      for(k = 0; k < 101; k++)
      {
         sprintf(temp_value, "%5lu", k);
         temp_display(0xB2, 0x11, 0x00);   
      }
   }
}

void fill_screen()
{
   unsigned int16 p = 0, c = 0;

   for(p = 0; p < 8; p++)
   {
      glcd_command(0xB0 | p);

      for(c = 0; c < 129; c++)
      {
         glcd_command(0x10 | (c & 0xf));
         glcd_command(0x00 | ((c >> 4) & 0xf));
         glcd_data(0xFF);
      }     
   }
}

// Function to clear the screen
void clear_screen()
{
   unsigned int16 p = 0, c = 0, q = 0;
   
   for(p = 0; p < 8; p++)
   {
      glcd_command(0xB0 | p);

      q = 16;         // in hex 0x10 - starting address
      for(q = 16; q < 25; q++)
      {
         glcd_command(q);
         c = 0;

         for(c = 0; c < 16; c++)
         {
            glcd_command(c);
            glcd_data(0x00);
         }   
      }
   }
}

void temp_display(char address, char upper_address, char lower_address)
{
   int x = 0;
   int m = 0;
   i = 0;
   x = 0;

   for(m = 0; m < 3; m++)
   {
      glcd_command(address+m);
      glcd_command(upper_address);
      glcd_command(lower_address);   // column shift
   
      for(i = 0; temp_value[i] != '\0'; i++)
      {
            for(x = m; x < 48; x = x+3)   
            {
               glcd_data(numbers_22[temp_value[i]-48][x]);
            }       
      }
   }
}


Display is updating at slower rate. How to display it in faster rate with same oscillator frequency? Please help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Tue Jul 25, 2017 3:01 am     Reply with quote

Realistically, increase the oscillator frequency.
Remember there is nothing to stop you changing it 'up' for the graphics, and then back down as soon as you have finished drawing.
Problem is the sheer amount of data involved when dealing with a graphics screen.....
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 25, 2017 4:48 am     Reply with quote

I have to agree with Mr. T !

Not only will it be very,very slow when using the graphics module but everything else lke serial I/O, SPI, I2C, etc. Even 'math' routines will be painfully slow.

Is there a specific need to run that powerful PIC at only 1MHz?

Jay
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Tue Jul 25, 2017 5:07 am     Reply with quote

I have to save the current consumption since it is battery operated :(

I thought my logic will be slow in displaying the value since I am not an expert. Need your help guys.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 25, 2017 5:29 am     Reply with quote

OK, that explains why.....
You should goto Microchip's website, find the 'application notes' section, then download the apnote about 'low power'. It'll be a low numbered apnote, probably 25 years old STILL valid today. They use an 8 pin PIC, A2D and several 'coin cell' batteries for the tests. It's really a 'must read', sorry I don't have my apnotes here,can't give you the #, but it is old....
In it they run PIC at several speeds (sleep, low speed, max,etc) and chart ACTUAL power usage with some surprises !!

Other options for battery powered devices...
Use a bigger battery. I know obvious but today you can get a LOT of power in a small package but you'll ALWAYS get more power in a bigger battery. I use 4 x AA sized batteries (series-parallel for 3V) for remote devices like data loggers.

Add a 'super cap' to your PC project. It'll help smooth the current demands nd prevent brownout resets

Be SURE to set every unused I/O pin to a '1' or '0' to reduce power.
Control the backlight of the LCD with PIC I/O pin.ONLY on when needed.

Also turn off every unused peripheral. ADC, Comp, UART, etc. All these internal peripherals take power, most can be turned off.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Tue Jul 25, 2017 7:28 am     Reply with quote

Yes.

The key point in that note, is that it often uses more power to clock slowly!.....
Problem is that current consumption is not linear, and the overheads are there all the time.

So (for instance), you have a job that takes 1 second at 1Mhz, or 1/16th second at 16Mhz. The PIC draws perhaps 1uA at 1Mhz, and 10uA at 16MHz. So the power that has to be delivered to do the job at 16MHz, is 10uA*0.0625*3.4 (assuming 3.4v supply) = 2.125uW. At 1MHz, the same job uses 1*1*3.4 = 3.4uW. So it actually draws 1.6* as much power to do the job at the slower rate!.....

Do the job quickly, and then suspend the PIC as much as possible. Perhaps putting it completely to sleep.

Understand that in most programs the chip spends far more of it's time 'doing nothing' (waiting), than anything else. Because this is the largest part of the processor's time, this is where most power can be saved....
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Sun Jul 30, 2017 9:44 pm     Reply with quote

Thanks for your valuable comments. I have increased the clock frequency. Now it displays at faster rate.

Below is the routine I used to display the data. It is working good.

Code:

const unsigned char negative_22[1][24] = {

 0x06, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06,
 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const unsigned char decimal_point_22[1][24] = {
 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00, 0x00, 0x1E,  0x00, 0x00, 0x1E,
 0x00, 0x00, 0x1E,  0x00, 0x00, 0x1E,  0x00, 0x00, 0x00,  0x00, 0x00, 0x00,
};

const unsigned char space_22[1][48] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void temp_display(char address, char upper_address, char lower_address)
{
   int x = 0, m = 0;
   i = 0; x = 0;
   
   for(m = 0; m < 3; m++)
   {
      glcd_command(address+m);
      glcd_command(upper_address);
      glcd_command(lower_address);   // column shift
      
      for(i = 0; temp_value[i] != '\0'; i++)
      {
         if(temp_value[i] == '-')
         {
            for(x = m; x < 24; x = x+3)   
            {
               glcd_data(negative_22[temp_value[i]-45][x]);
            }
         }
         
         if(temp_value[i] == '.')
         {
            for(x = m; x < 24; x = x+3)   
            {
               glcd_data(decimal_point_22[temp_value[i]-46][x]);
            }
         }
         
         else if((temp_value[i] >= '0') && (temp_value[i] <= '9'))
         {         
            for(x = m; x < 48; x = x+3)   
            {
               glcd_data(numbers_22[temp_value[i]-48][x]);
            }
         }
         
         else
         {
            for(x = m; x < 48; x = x+3)   
            {
               glcd_data(space_22[temp_value[i]-32][x]);
            }         
         }
      }
   }
}


Since I'm not an expert in C language. I think my logic is time consuming since many for loops are used. Can you suggest any ideas?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 4:03 am     Reply with quote

There are several strange things here:

A two dimensional array, with the first element declared as [1], should only be declared as a one dimensional array.

Why on earth have an array containing just zeros?. This wastes a huge amount of time, when you could get rid of the array accesses completely...
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Wed Aug 02, 2017 2:12 am     Reply with quote

How to write efficiently. Please help.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Wed Aug 02, 2017 3:15 am     Reply with quote

Facing another problem,

When i used to display like this, it works

Code:
      sprintf(temp_value, "0 BAR  ");
      display_data(0xB1, 0x10, 0x0B);


When I do,
Code:
const char MENU[] = {"0 BAR  "};

// main code

sprintf(temp_value, "%c", MENU[0]);
display_data(0xB1, 0x10, 0x0B);   

Its not working. How to print it?
oxo



Joined: 13 Nov 2012
Posts: 219
Location: France

View user's profile Send private message

PostPosted: Wed Aug 02, 2017 3:39 am     Reply with quote

Either

Code:
sprintf(temp_value, "%c", MENU);


or

Code:
sprintf(temp_value, "%c", &MENU[0]);
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Aug 02, 2017 4:30 am     Reply with quote

If you look he is declaring an array. So need %s not %c as well....

%c means 'print one character'. %s is the command to print a 'string' from a character array.

He also needs the compiler directive 'PASS_STRINGS="IN_RAM"', for this to work.
oxo



Joined: 13 Nov 2012
Posts: 219
Location: France

View user's profile Send private message

PostPosted: Wed Aug 02, 2017 5:02 am     Reply with quote

Gotta leave something for the student to do ;)
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Wed Aug 02, 2017 9:31 pm     Reply with quote

I tried as,
Code:
      strcpy(temp_value, MENU[0]);
      display_data(0xB1, 0x10, 0x0B);   


It works.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu Aug 03, 2017 1:23 am     Reply with quote

First the syntax only works by fluke....

MENU[0] is the physical element at the first location in the array.

&MENU[0] is the address of this element.
MENU (on it's own), is a C short-cut for this address of this element.

MENU[0] only works because CCS internally automatically turns this into the address, if used in a function expecting an address. This has been commented on before but it means it won't work in other languages, and is not guaranteed to work with future versions....

Then why bother?. Use the compiler #device PASS_STRINGS option.

This automatically does the copy from ROM to RAM for you, and does it using only a tiny buffer. Doing it manually means you have to have a large enough buffer for the whole string. Probably OK for now, but 'long term' as you use larger chips and larger strings, not practical....

The only real reason now to use the strcpy syntax, would be if you are using an old compiler (PASS_STRINGS has worked well now for many dozens of versions).

A search here will find the explanation of 'why' you have to do one or the other.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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