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

LCD problems

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



Joined: 25 Jun 2005
Posts: 2

View user's profile Send private message

LCD problems
PostPosted: Sat Jul 02, 2005 8:54 am     Reply with quote

Hello to all,

I'm trying to get a 2-line 20 character LCD to work with my old PicDem - 2 (not plus) board. It works with PicBasic but I can't make it work with CCS C. The LCD driver program I'm enclosing was written by Mark and I've made the necessary pin changes, correctly I think. Any help would be greatly appreciated!

Rod







Code:
////////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,1997 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////

// This structure is overlayed onto the data ports so that you may use
// whatever ports you desire
struct lcd_pin_map
{
  BOOLEAN dummy; // PinA0 is not used
  BOOLEAN enable; // PinA1
  BOOLEAN rw; // PinA2
  BOOLEAN rs; // PinA3
  int unusedA : 4; // The rest of portA
  int unusedB;     // portB is not used
  int unusedC;     // portC is not used
  int unusedD : 4;// \    Changed so lower nibble of portd is unused
  int data ;     //  /    and upper nibble is data
} lcd;
 
#if defined(__PCH__)
#locate lcd = 0xF80
#else
#locate lcd = 5
#endif
 
struct lcd_tris_map
{
 BOOLEAN dummy; // PinA0 is not used
 int control : 3;
 int unusedA : 4; // The rest of portA
 int unusedB: 8; // portB is not used
 int unusedC: 8; // portC is not used
 int unusedD: 4;    //  \
 int data : 4;//      /  Change to use the upper nibble of portd for data instead of the lower
 
} lcdtris;

#if defined(__PCH__)
#locate lcdtris = 0xF92
#else
#locate lcdtris = 0x85
#endif

#define set_tris_lcd(x) lcdtris.data = (x); lcdtris.control = 0;
#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] = {0x28, 0xd,1,6};
//BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0x0d, 1, 6};
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};// Cursor underlined and blinking

// These bytes need to be sent to the LCD
// to start it up.


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

#define LCD_WRITE 0 // For write mode all pins are out
#define LCD_READ 15 // For read mode data pins are in

BYTE lcd_read_byte() {
 
   BYTE low,high;
   set_tris_lcd(LCD_READ);
   lcd.rw = 1;
   delay_cycles(1);
   lcd.enable = 1;
   delay_cycles(1);
   high = lcd.data;
   lcd.enable = 0;
   delay_cycles(1);
   lcd.enable = 1;
   delay_us(1);
   low = lcd.data;
   lcd.enable = 0;
   set_tris_lcd(LCD_WRITE);
   return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
 
   lcd.data = n;
   delay_cycles(1);
   lcd.enable = 1;
   delay_us(2);
   lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

   lcd.rs = 0;
   while ( bit_test(lcd_read_byte(),7) ) ;
   lcd.rs = address;
   delay_cycles(1);
   lcd.rw = 0;
   delay_cycles(1);
   lcd.enable = 0;
   lcd_send_nibble(n >> 4);
   lcd_send_nibble(n & 0xf);
}


void lcd_init() {
 
   BYTE i;
   set_tris_lcd(LCD_WRITE);
   lcd.rs = 0;
   lcd.rw = 0;
   lcd.enable = 0;
   delay_ms(15);
   for(i=1;i<=3;++i) {
     lcd_send_nibble(3);// send 3 - threes
     delay_ms(5);
  }
   lcd_send_nibble(2);// 4 bit mode
   for(i=0;i<=3;++i)
     lcd_send_byte(0,LCD_INIT_STRING[i]);
     
}


void lcd_gotoxy( BYTE x, BYTE y) {
 
   BYTE address;

   if(y!=1)
     address=lcd_line_two;
   else
     address=0;
     address+=x-1;
     lcd_send_byte(0,0x80|address);
   
 }   

void lcd_putc( char c) {
   switch (c) {
   case '\f' : lcd_send_byte(0,1);
               delay_ms(2);
   break;
   case '\n' : lcd_gotoxy(1,2); break;
   case '\b' : lcd_send_byte(0,0x10); break;
   default : lcd_send_byte(1,c); break;
  }
}

char lcd_getc( BYTE x, BYTE y) {
 
   char value;

   lcd_gotoxy(x,y);
   lcd.rs=1;
   value = lcd_read_byte();
   lcd.rs=0;
   return(value);
}



PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 03, 2005 4:50 pm     Reply with quote

Quote:
and I've made the necessary pin changes, correctly I think

I see one problem in your modifications to the structure below.
You want to move the data bits onto the upper nybble of Port D,
but you haven't followed the motif. You've left off the " :4" on your
"int data" statement. By doing so, you've forced the data to go
onto the next byte address, which would be Port E.
Code:
struct lcd_pin_map
{
  BOOLEAN dummy; // PinA0 is not used
  BOOLEAN enable; // PinA1
  BOOLEAN rw; // PinA2
  BOOLEAN rs; // PinA3
  int unusedA : 4; // The rest of portA
  int unusedB;     // portB is not used
  int unusedC;     // portC is not used
  int unusedD : 4;//    Changed so lower nibble of portd is unused
  int data ;     //  /    <--- PROBLEM HERE
} lcd;
RodP



Joined: 25 Jun 2005
Posts: 2

View user's profile Send private message

Thanks PCM
PostPosted: Mon Jul 04, 2005 11:58 am     Reply with quote

Thank's to PCM for the help. Upon looking deeper into this I see changing the structures is only part of what needs to be done.

I really wish CCS would write a driver that could put the data lines on either the upper or lower 4 bits of a a selected port and the control lines on any pins of another port. PicBasic has this type setup and it works right out of the box!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Jul 04, 2005 2:20 pm     Reply with quote

Not really. I didn't have to change any of the code. That was my goal. Just the struct overlayment needs to be changed.
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