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

cannot use PIC16F877 with LCD

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



Joined: 06 Oct 2004
Posts: 8

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

cannot use PIC16F877 with LCD
PostPosted: Fri Oct 08, 2004 11:23 pm     Reply with quote

I'm using PIC16F877 with crystal 20MHz
and connect it to LCD with the following pin outs
RB4-RB7 --> D4-D7
RB0 --> E
RB1 --> RS
RB2 --> RW
and connect Vo (brightness) to ground without variable resistor

here is my code :

Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)

#include <lcd.c>

void main()
{
char a[11]="teststring";

lcd_init();

while(TRUE)
 {
  lcd_gotoxy(1,1);
  printf(lcd_putc,"%s",a);
  delay_ms(500);           
 }
}


but it doesn't work
i don't know why it is

thanks in advance
saroch



Joined: 06 Oct 2004
Posts: 8

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

PostPosted: Fri Oct 08, 2004 11:25 pm     Reply with quote

here is my LCD.C

Code:

As defined in the following structure the pin connection is as follows:
//     B0  enable
//     B1  rs
//     B2  rw
//   B3  bus_rw   0= gate external bus
//     B4  D4
//     B5  D5
//     B6  D6
//     B7  D7
//
//   LCD pins D0-D3 are not used and PIC B3 is not used.

struct lcd_pin_map {                 // This structure is overlayed
          BOOLEAN enable;           // on to an I/O port to gain
          BOOLEAN rs;               // access to the LCD pins.
          BOOLEAN rw;      // nu   // The bits are allocated from
          BOOLEAN bus_rw;           // low order up.  ENABLE will
          int     data : 4;         // be pin B0.
       } lcd;
// bus_rw controls drive state of
// extern bus through 74125
// 0 gates bus

#byte lcd = 6                        // This puts the entire structure
                                    // on to port B (at address 6)

#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.


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

// changed following to make RB2 always input -- bit for init mode
STRUCT lcd_pin_map const LCD_WRITE = {0,0,1,0,0}; // For write mode all pins are out
STRUCT lcd_pin_map const LCD_READ = {0,0,1,0,15}; // For read mode data pins are in



byte lcd_read_bus() {
     byte low,high;

     set_tris_b(LCD_READ);
     lcd.bus_rw = 0; // gate bus
     delay_cycles(1);
     low = lcd.data;
     lcd.bus_rw = 1; // block bus
 delay_cycles(1);
     set_tris_b(LCD_WRITE);
     return(low);
}


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


void lcd_send_byte( byte address, byte n ) {
// address: 0=command, 1=data

     lcd.enable = 0;
     lcd.rs = address;
     delay_cycles(1);
     lcd_send_nibble(n >> 4);
     lcd_send_nibble(n & 0xf);
 delay_us(2);
}


void lcd_init() {
   byte i;

   set_tris_b(0xff); // all inputs
   lcd.bus_rw = 1; // block bus
delay_cycles(2);
   lcd.rs = 0;
   lcd.enable = 0;
   set_tris_b(LCD_WRITE);
   delay_ms(15);
   for(i=1;i<=3;++i) {
      lcd_send_nibble(3);
      delay_ms(5);
   }
   lcd_send_nibble(2);
   for(i=0;i<=3;++i)
      lcd_send_byte(0,LCD_INIT_STRING[i]);
}


void lcd_gotoxy( byte x, byte y) {
  byte address;
  // y = line; 1 = 1st line, 2 = 2nd

  if(y==1)
    address=0;
  else
    address=lcd_line_two;
  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;
  }
}

#if 0
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);
}
#endif
Ttelmah
Guest







PostPosted: Sat Oct 09, 2004 6:27 am     Reply with quote

Obvious comment, is are you sure your display supports having the bias voltage taken to GND?. This voltage adjusts the contrast, not the 'brightness', and on most displays a voltage below about 0.4v, makes the display invisible. The behaviour does vary between display makes. It may simply be that you cannot see the data on the display.

Best Wishes
Mark



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

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

PostPosted: Sat Oct 09, 2004 9:33 am     Reply with quote

Why are you using a 74125?? Doesn't this prevent you from reading from the LCD? Why not drive the LCD directly? Your biggest problem is that the LCD is busy and that you are not waiting until it is ready. Refer to the CCS driver file LCD.C to see what I mean. Without this, you are going to have to add delays at just the right spots. Search the forum, I am sure others have done this. Personally I would never do it. It doesn't make for a very robust system IMHO. Also, if you are using a 20MHz osc then don't use XT in the fuses, use HS instead.
saroch



Joined: 06 Oct 2004
Posts: 8

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

PostPosted: Sat Oct 09, 2004 11:38 am     Reply with quote

Quote:
Why are you using a 74125??


I'm not using 74125. I use only PIC and LCD ???

Quote:
if you are using a 20MHz osc then don't use XT in the fuses, use HS instead.


I'm using #fuses HS instead but it still doesn't work !!!

pls help me Rolling Eyes
Mark



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

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

PostPosted: Sat Oct 09, 2004 10:26 pm     Reply with quote

Then use the CCS lcd.c file

Code:

#define use_portb_lcd TRUE


struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;


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

#if defined use_portb_lcd
   #define set_tris_lcd(x) set_tris_b(x)
#else
   #define set_tris_lcd(x) set_tris_d(x)
#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.


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

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,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);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    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);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}
saroch



Joined: 06 Oct 2004
Posts: 8

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

PostPosted: Sun Oct 10, 2004 2:59 am     Reply with quote

Got it !!
thanks very much for your help Very Happy
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