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 support@ccsinfo.com

Problem with character position on an LCD

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RatFink



Joined: 01 May 2004
Posts: 49

View user's profile Send private message

Problem with character position on an LCD
PostPosted: Wed May 19, 2004 2:36 am     Reply with quote

Well, after finally getting my LCD to work, I found another small problem, here's the code.

Code:
   while (T0IF == 0); /* Stay in loop until T0IF sets */
   
   lcd_gotoxy(0,2);
   lcd_putc("TEMP");

   /* Exit loop */

   T0IF = 0;   /* Clear the T0IF flag */
   GO = 1;   /* Start A/D conversion */

   
   do
   {;}
   while (ADIF == 0 );    /* Wait for conversion to complete */
   HEAT = ADRESH*(5.0/255)*100;      /* Load HEAT with A/D value converted to volts, then degrees*/
 
   
   lcd_gotoxy(5,2);
   printf(lcd_putc, "%d", HEAT);



I want to print the word "TEMP" at the first position on line 2, and the the value in "HEAT" at the 6th position of line 2 but for some reason The second value just keeps printing over the word TEMP. If I try it on line 1 it works fine.

I've looked though the driver I'm using but I just can't seem to find anything wrong. Here's the driver I'm using.

Code:
////////////////////   LCD   //////////////////////////////


// As defined in the following structure the pin connection is as follows:
//     A1  enable
//     A2  rw
//     A3  rs

//     D0  D4
//     D1  D5
//     D2  D6
//     D3  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.



//****************************************************************************************
#if defined(__PCH__)
   #byte lcd = 0xF83      // This puts the entire structure
#else
   #byte lcd = 8          // on to port D (at address 8)
#endif


//****************************************************************************************
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40    // LCD RAM address for the second line

BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                            // These bytes need to be sent to the LCD
                            // to start it up.
                     // for 2 lines lcd: {0x0a,0xc,1,6}
                     // for 5x10 lcd:   {0x06,0xc,1,6}   
                     // for 5x7 lcd:      {0x20,0xc,1,6}

                             // The following are used for setting
                             // the I/O port direction register.


//***** lcd command port  *******************************************************************
struct lcd_command{
   char none:1;
   char enable:1;
   char read_write:1;//rw
   char data_command:1;//rs
   };
struct lcd_command lcd_command_port;
#locate lcd_command_port=5
//---------------------------------------------------
struct lcd_data{
   char data:4;
   };
struct lcd_data lcd_data_port;
#locate lcd_data_port=8

//************  "COMMAND / DATA definition  ************************************************************
#define COMMAND0 0
#define DATA1 1

//************  "READ / WRITE definition  ************************************************************
#define WRITE0 0   //LCD <- MPU
#define READ1 1  //LCD -> MPU

//************  "E_UP / E_DOWN definition  ************************************************************
#define E_DOWN 0
#define E_UP 1

//**********eeprom or flash******************************************************************************
#define EEPROM0 0   ;eeprom - not the program  memory
#define FLASH1 1   ;program memory

//*********  set tris d  *********************************************************************
#define set_tris_lcd_read(){\
   set_tris_a(TRISA & 0xf1/*0b11110001*/);\
   set_tris_d(TRISD | 0x0f/*0b00001111*/);\
   }
#define set_tris_lcd_write(){\
   set_tris_a(TRISA & 0xf1/*0b11110001*/);\
   set_tris_d(TRISD & 0xf0/*0b11110000*/);\
   }

//***********   clear LCD  ************************************
#define clear_lcd   lcd_send_byte(0x1,COMMAND0);//clear lcd display

//****************************************************************************************

//************************************************************
char lcd_read_byte(void){
      char low,high;
      set_tris_lcd_read();
      lcd_command_port.read_write = READ1;
      delay_cycles(1);
     
      lcd_command_port.enable = E_UP;
      delay_cycles(1);
      high = lcd_data_port.data & 0x0f;
      lcd_command_port.enable = E_DOWN;
      delay_cycles(1);
     
      lcd_command_port.enable = E_UP;
      delay_us(1);
      low = lcd_data_port.data & 0x0f;
      lcd_command_port.enable = E_DOWN;
      set_tris_lcd_write();
      return( (high << 4) | low);
}

//*************** -   - *********************************************
void lcd_write_nibble(char temp_wr){
//Purpose:
      lcd_data_port.data = temp_wr;
      delay_cycles(1);
      lcd_command_port.enable = 1;
      delay_us(2);
      lcd_command_port.enable = 0;
}
//*************** -   - *********************************************
void lcd_send_byte(char data , char data_or_command ) {

      lcd_command_port.data_command = COMMAND0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd_command_port.data_command = data_or_command;
      delay_cycles(1);
      lcd_command_port.read_write = WRITE0;
      delay_cycles(1);
      lcd_command_port.enable = E_DOWN;
      lcd_write_nibble(data >> 4);
      lcd_write_nibble(data & 0xf);
}
//************************************************************
void lcd_gotoxy( char location, char line) {//location 0...
   char address;

   if(line!=1)
     address=40;//was80
   else
     address=0;
   address+=location;
   lcd_send_byte(0x80|address,COMMAND0);
}
//********** -  1 - **************************************************
void lcd_init(void){
//Purpose: initiate the lcd
   //turnning PORTA0=analog, PORTA1-7=digital
   ADCON1=0x0e;
   
   //turnning command pin of lcd to output
   set_tris_lcd_write();

   //delay 15msec
   delay_ms(15);   
   lcd_command_port.enable=0;
   lcd_command_port.data_command=0;
   lcd_command_port.read_write=0;
   lcd_data_port.data=0;
   delay_ms(2);
   lcd_write_nibble(0x03);//was 30  ddram address: 1:1bit,line:1bit,address:4bit
   delay_ms(10);//more then 4.1msec

   lcd_write_nibble(0x03);//was 30
   delay_us(150);//more then 100usec

   lcd_write_nibble(0x03);//was 30
   delay_us(100);

   lcd_write_nibble(0x02);//was 20
   while(bit_test(lcd_read_byte(),7));

   lcd_send_byte(0x28,COMMAND0);//was 0x28 portd[3:0]=x2 then portd[3:0]=x8
                     //  4 bit low nibble, ddram address=0 first line

   lcd_send_byte(0x0c,COMMAND0);//disp on

   clear_lcd;

   lcd_send_byte(0x6,COMMAND0);//entry inc

   lcd_gotoxy(1,1);
   
   
   

}
//************************************************************
void lcd_putc( char c) {//this function works good
   switch (c) {
     case '\f'   : lcd_send_byte(1,COMMAND0);   delay_ms(2);   break;   //Clear display
     case '\n'   : lcd_gotoxy(1,2);                        break;   //Go to start of second line
     case '\b'   : lcd_send_byte(0x10,COMMAND0);               break;   //Move back one position
     default     : lcd_send_byte(c,DATA1);                  break;   //send the actual character
   }
}
//*************** -   - *********************************************
char lcd_getc( char location, char line) {
      char value;

    lcd_gotoxy(location,line);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd_command_port.data_command=1;
    value = lcd_read_byte();
    lcd_command_port.data_command=0;
    return(value);
      return 1;
}
//************************************************************
//*************************----***********************************
void lcd_put_string(char *string){
//put string, starting  from the curren cursor position
//assume that string not excides from lcd displayed RAM
   char index=0;

   while(string[index]!=0){
      lcd_putc(string[index++]);
   
   }
}


//************************************************************
void lcd_put_string_xy(char *string, char pos, char line){
//assume that string not excides from lcd displayed RAM
   lcd_gotoxy(pos,line);
   lcd_put_string(string);
}
//************************************************************
void stan_char(long *ptr,char line,char eeprom_or_flash){
//Purpose: write 16 chars, given in ptr location(eeprom or flash)
//to line of lcd, from the begining of the line
   char c,i;
   lcd_gotoxy(1,line);
/*OR:   switch(line==1) {
      case 1:lcd_send_byte(0x80,COMMAND);   //initiate lcd to write to line 1
      case 2:lcd_send_byte(0xc0,COMMAND);   //initiate lcd to write to line 2
   }*/
   for (i=0;i<16;i++){
      if (eeprom_or_flash)
         c=read_program_eeprom(ptr+1);
      else
         c=read_eeprom((char)ptr+1);
      lcd_putc(c);ptr++;
   }
}


I'm using a PIC16F877A
and a crystalFontz LCD with a HD44780 compatible controller
The Data sheet can be found here http://www.crystalfontz.com/products/0802a-color/CFAH0802AYMCJP.pdf


Can anybody please see if they can see something I don't see?

Thank you.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed May 19, 2004 9:43 am     Reply with quote

Here is a bit of code that I have used for several years in driving these types of displays. It is set up for a 16x2 display but has remarked code that can be used for a 16x1 display. Just change it around a little if you want to use a different port.

Code:

#include <string.h>

// Pinout connections for a 4 wire interface
//////////////////////
// LCD      MCU
//////////////////////
// RS       PIN_A5
// R/W      PIN_E0
// E        PIN_A4 -- this pin will need a pull-up resistor
// DB4      PIN_A0
// DB5      PIN_A1
// DB6      PIN_A2
// DB7      PIN_A3


#define RS PIN_A5 // RS pin of the LCD display
#define ENB PIN_A4 // enable for the LCD display
#define RW PIN_E0   // R/W bit for the LCD display

char table1[6] = {'L','I','N','E','1','\0'};   // "LINE1"
char table2[6] = {'L','I','N','E','2','\0'};   // "LINE2"

char text[10];   // general variable used to display information to the LCD display

void pulse(unsigned int8 bits) // sends out the clock pulse to the LCD display
{
unsigned int8 pp;

   output_high(ENB);
   output_a(bits);
   for(pp = 0; pp < 10; pp++)
      ;
   output_low(ENB);
}

void bf_check(void)
{
unsigned int8 pp;
int1 BF = 0;

   set_tris_a(0x0F);// set bits 0-3 as inputs
   output_low(RS);
   output_high(RW);
   for(pp = 0; pp < 5; pp++)
      ;

   do
   {
      output_high(ENB);
      for(pp = 0; pp < 10; pp++)
         ;
      if(input(PIN_A3))
      {
         BF = 1;
      }
      else
      {
         BF = 0;
      }

      output_low(ENB);
      for(pp = 0; pp < 5; pp++)
         ;
      output_high(ENB);
      for(pp = 0; pp < 10; pp++)
         ;
      output_low(ENB);

   }while(BF);

   set_tris_a(0x00);// set all bits to outputs
}

void ctlnib(int8 niblet) // sends a control command to the LCD display
{
int8 msn, lsn;

   bf_check();

   msn = niblet & 0xF0;
   msn = msn >> 4;
   msn = msn | 0x10;

   output_low(RW);
   output_low(RS);

   pulse(msn);
   lsn = niblet & 0x0F;
   lsn = lsn | 0x10;
   pulse(lsn);
}

void datnib(int8 niblet) // sends a data byte to the LCD display
{
int8 msn, lsn;

   bf_check();

   msn = niblet & 0xF0;
   msn = msn >> 4;
   msn = msn | 0x30;

   output_low(RW);
   output_high(RS);

   pulse(msn);
   lsn = niblet & 0x0F;
   lsn = lsn | 0x30;
   pulse(lsn);
}

void disline(char outstr[], int8 dline) // format is; string - line
{                                                            // displays a line of text on a 16 x 2 LCD display
int8 llg, dindex;
//int8 track; // add for a 16 x 1 display

//   track = dline; // add for a 16 x 1 display
   ctlnib(dline);
   llg = strlen(outstr);
   for(dindex = 0; dindex <= llg - 1; dindex++)
   {
//      if(track == 0x88) // add these 4 lines for a 16 x 1 display
//      {
//         ctlnib(0xC0);
//      }
      datnib(outstr[dindex]);
//      track++; // add for a 16 x 1 display
   }
}

void dischar(char outstr, int8 dline) // format is; character - position
{
  ctlnib(dline);
  datnib(outstr);
}

void clrdis(void) // clear the LCD display
{
   ctlnib(0x01);
}

void initdisp(void) // initialize the LCD display
{
   output_low(RW);
   delay_ms(50);
   pulse(0x03);
   delay_ms(30);
   pulse(0x03);
   delay_us(400);
   pulse(0x03);
   pulse(0x02);
   ctlnib(0x28);
   ctlnib(0x80);
   ctlnib(0x01);
   ctlnib(0x06);
   ctlnib(0x0C);
}// end of initdisp()



main()
{

   initdisp();

   // example commands to print text to display
   /////////////////////////////////////////////
   disline(table1, 0x80);// display on first line
   disline(table2, 0xC0);// display on second line

   sprintf(text, "%u", 100);   // convert a number to be displayed on LCD
   disline(text, 0x80); // now display that number on the display
   
}



Ronald
RatFink



Joined: 01 May 2004
Posts: 49

View user's profile Send private message

PostPosted: Wed May 19, 2004 10:54 am     Reply with quote

Thanks Ronald, I will check it out.

But can't one of you Ultra-Smart Coding Magicians see what could be causing the problem with the driver I'm using?


This seems like the part of the driver that applies



Code:
void lcd_gotoxy( char location, char line) {//location 0...
   char address;

   if(line!=1)
     address=40;//was80
   else
     address=0;
   address+=location;
   lcd_send_byte(0x80|address,COMMAND0);
}


And In my code

Code:
 lcd_gotoxy(0,2);
   lcd_putc("TEMP");

lcd_gotoxy(5,2);
   printf(lcd_putc, "%d", HEAT);


It seems like I'm doing it right, but the second value keeps printing on top of the first at (0,2) instead of where it should be at (5,2).
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed May 19, 2004 11:02 am     Reply with quote

Try using address 0x80 for the first line and 0xC0 for the second line. See what that does.

Ronald
RatFink



Joined: 01 May 2004
Posts: 49

View user's profile Send private message

PostPosted: Wed May 19, 2004 11:37 am     Reply with quote

Well, I got it to work using

Code:
lcd_gotoxy(0,2);
   printf(lcd_putc, "TEMP %d", HEAT);


I was just didn't want it to have to print the word TEMP through every loop.
Charlie U



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

PostPosted: Wed May 19, 2004 1:01 pm     Reply with quote

After just a quick scan, in your lcd_gotoxy() function, shouldn't the address be in hex not decimal:

address = 0x40;

Just a thought?!?!
RatFink



Joined: 01 May 2004
Posts: 49

View user's profile Send private message

PostPosted: Wed May 19, 2004 1:02 pm     Reply with quote

HMMM, I'll try that.

Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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