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

PIC16F877A and LCD 16x2 problem
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
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PIC16F877A and LCD 16x2 problem
PostPosted: Fri Jan 21, 2011 5:31 am     Reply with quote

Hello, I'm testing my LCD 16x2 (ABC016002A07-GHY) with PIC16F877A and flex_led.c driver but it's not work (appear black square in first line). I try these method below but it's not work.

1. Increase the initial delay to a much larger value, such as 50 ms.

2. Check the +5v power supply. Make sure it stays at a constant +5v.

3. If those two things don't help, then configure the LCD and driver
for Write-only mode. Instructions:

A. Break the connection between the LCD_RW pin and pin A2 on
the PIC.

B. Connect the LCD_RW pin to ground.

C. Don't connect anything to pin A2 on the PIC.

D. In the Flex_lcd.c driver, comment out #define statement for
USE_RW_PIN. Example:

Code:
// #define USE_RW_PIN 1


E. Re-compile the program.

F. Re-program the PIC and test it.



This is LCD datasheet :
http://www.mediafire.com/?io9zpabz4itz6ao



This is define word :

// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.

#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7

#define LCD_E PIN_D0
#define LCD_RS PIN_D1
#define LCD_RW PIN_D2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

//#define USE_LCD_RW 1

//========================================

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


-------------------------------------------------------------------------------------

This is the main program that I compile :

#include <16F877A.h> // Standard Header file for the PIC16F877A
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT // Configuration word
#use delay(clock=20000000) // oscillator
#include "flex_led.c"

//----------------------------------------------------------//


void main(void)
{

lcd_init();

while(TRUE)
{

// LCD Display //

lcd_putc("\f"); //Clear display
lcd_gotoxy(1,1);
lcd_putc("Champ");
delay_ms(1000);
}

}


please help me, thank you.
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Fri Jan 21, 2011 6:16 am     Reply with quote

I compile with PCWHD 4.068
demonspells



Joined: 06 Jan 2011
Posts: 26

View user's profile Send private message Yahoo Messenger MSN Messenger

PostPosted: Fri Jan 21, 2011 7:44 am     Reply with quote

Quote:
C. Don't connect anything to pin A2 on the PIC.


I think you meant pin D2. right?

did you try the default <lcd.c> routine? is it working?
your code looks fine, try re-checking your connections
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Fri Jan 21, 2011 7:47 am     Reply with quote

In addition to the comment above on D2, make sure you have power and ground to the display correctly (favorite trick is to hook up data/control lines and forget power and ground ... very odd things happen that way).

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Fri Jan 21, 2011 10:08 pm     Reply with quote

demonspells wrote:
Quote:
C. Don't connect anything to pin A2 on the PIC.


I think you meant pin D2. right?

did you try the default <lcd.c> routine? is it working?
your code looks fine, try re-checking your connections


Yes, I connect RW at D2. I change driver to LCD.c but not work.
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Fri Jan 21, 2011 10:41 pm     Reply with quote

gpsmikey wrote:
In addition to the comment above on D2, make sure you have power and ground to the display correctly (favorite trick is to hook up data/control lines and forget power and ground ... very odd things happen that way).

mikey


connection of power and ground is correct
Code:

LCD         
PIN 1 --> Ground
PIN 2 --> +5V
PIN 3 --> POT 20K
PIN 4 - RS --> RD1
PIN 5 - R/W --> RD2
PIN 6 - E --> RD0
PIN 7 --> GND
PIN 8 --> GND
PIN 9 --> GND
PIN 10 --> GND
PIN 11 --> RD4
PIN 12 --> RD5
PIN 13 --> RD6
PIN 14 --> RD7
PIN 15 --> +5V
PIN 16 --> GND



This is flex_led.c that I compile :
Code:

// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7

#define LCD_E     PIN_D0
#define LCD_RS    PIN_D1
#define LCD_RW    PIN_D2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

//#define USE_LCD_RW   1     

//========================================

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


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };
                             

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2)); 
 output_bit(LCD_DB6, !!(nibble & 4));   
 output_bit(LCD_DB7, !!(nibble & 8));   

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.     

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;
   
output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
 
output_low(LCD_E);
   
return(retval);   
}   
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);             
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);
     
 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;


output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);     
delay_ms(15);           

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);
   
    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 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;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7)); 

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Fri Jan 21, 2011 10:57 pm     Reply with quote

That is basically the way I have my LCD (CrystalFontz in this case) connected although D0-D3 are not connected. Just out of curiosity, how did you count the pin numbers on the connector ? They alternate back and forth, not down one side and up the other like an IC. See the connector pin-out of mine - I expect yours uses the same connector ?



mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 12:04 am     Reply with quote

gpsmikey wrote:
That is basically the way I have my LCD (CrystalFontz in this case) connected although D0-D3 are not connected. Just out of curiosity, how did you count the pin numbers on the connector ? They alternate back and forth, not down one side and up the other like an IC. See the connector pin-out of mine - I expect yours uses the same connector ?



mikey


Thank you Mikey,

I check LCD PIN, it is correct (LCD PIN has one row its datasheet is http://www.mediafire.com/?io9zpabz4itz6ao). If someone have any idea, please suggest me
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 12:39 am     Reply with quote

LCD appears black squares when adjusting POT to maximum value (Vo=0V). In LCD datasheet, Vo value that LCD works properly is 4.2V. When I adjust POT to this value, It has no black square on screen. What is the problem ?
pieter



Joined: 16 Jan 2011
Posts: 27

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 1:49 am     Reply with quote

1. the lcd does not initialise at all, otherwise the black line will disappear.
in the lcd driver, place some delays between i/o activity like:

Code:
output_b (nibble);
 delay_us(1);
 output_high(LCD_E);
 delay_us(2);     //  <-------
 output_low(LCD_E);

but also on other places...

2. Change the main routine to

Code:
void main(void)
{

lcd_init();
delay_ms(5);   // <----- delays
lcd_putc("\f"); //Clear display
delay_ms(5);
lcd_gotoxy(1,1);
delay_ms(5);
lcd_putc("Champ");  // you want to send this to the lcd only once

while(TRUE)
{

// LCD Display //

delay_ms(1000);
}

}


3. see if using #use fast_io(D); makes any difference
4. once it works you may try to reduce the delays or remove them
pieter



Joined: 16 Jan 2011
Posts: 27

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 1:53 am     Reply with quote

This should display 2 lines
Code:
      printf(lcd_putc, "\f Champ 1234     ");
      printf(lcd_putc, "\n Champions 12345");
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 2:56 am     Reply with quote

Quote:
In LCD datasheet, Vo value that LCD works properly is 4.2V. When I adjust POT to this value, It has no black square on screen.

This is wrong. You should adjust the LCD Vo voltage on Pin 3 to
about 0.5v to 0.8v initially. This will allow you to see something on
the LCD, if it is working.
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 4:01 am     Reply with quote

pieter wrote:
1. the lcd does not initialise at all, otherwise the black line will disappear.
in the lcd driver, place some delays between i/o activity like:

Code:
output_b (nibble);
 delay_us(1);
 output_high(LCD_E);
 delay_us(2);     //  <-------
 output_low(LCD_E);

but also on other places...

2. Change the main routine to

Code:
void main(void)
{

lcd_init();
delay_ms(5);   // <----- delays
lcd_putc("\f"); //Clear display
delay_ms(5);
lcd_gotoxy(1,1);
delay_ms(5);
lcd_putc("Champ");  // you want to send this to the lcd only once

while(TRUE)
{

// LCD Display //

delay_ms(1000);
}

}


3. see if using #use fast_io(D); makes any difference
4. once it works you may try to reduce the delays or remove them


In the first method, where is the part of program I must add delay command ? I add them at the code below. Is it Correct ?
Code:

void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2)); 
 output_bit(LCD_DB6, !!(nibble & 4));   
 output_bit(LCD_DB7, !!(nibble & 8));   

 delay_cycles(1);
 
 output_d (nibble);        // add this
 delay_us(1);              // add this
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jan 22, 2011 1:27 pm     Reply with quote

You don't need to add delays to the Flex driver. You're running at 20 MHz.
It's fully tested and known to work at 20 MHz or even faster.

Here is your problem:
You are using the R/W line. You have it connected to the PIC.
It's not connected to Ground. You are using it.
Quote:

LCD
PIN 1 --> Ground
PIN 2 --> +5V
PIN 3 --> POT 20K
PIN 4 - RS --> RD1
PIN 5 - R/W --> RD2
PIN 6 - E --> RD0
PIN 7 --> GND
PIN 8 --> GND
PIN 9 --> GND
PIN 10 --> GND
PIN 11 --> RD4
PIN 12 --> RD5
PIN 13 --> RD6
PIN 14 --> RD7
PIN 15 --> +5V
PIN 16 --> GND


But here, in the code below, you have commented out the statement to
use the R/W line. That's the problem ! You need to un-comment it.
Quote:

// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.

#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7

#define LCD_E PIN_D0
#define LCD_RS PIN_D1
#define LCD_RW PIN_D2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

//#define USE_LCD_RW 1


Remove the comments, so the line looks like this:
Code:
#define USE_LCD_RW   1   
 


Also, you ignored my post on setting the correct Vo voltage for the LCD
contrast. You need to fix that, too.

I think you have another problem. You don't appear to have a series
resistor in your backlight LED connections to the LCD. Read this
thread, which explains how to calculate the size of the series resistor:
http://www.ccsinfo.com/forum/viewtopic.php?t=37646&start=10

And even one more thing: You have the unused pins on the LCD (which
are DB0 to DB3) connected to ground. You don't really need to do that.
The LCD has internal pull-ups on the data pins, so if you leave them
floating they will be pulled up to +5v.
champ720



Joined: 22 Dec 2010
Posts: 12

View user's profile Send private message

PostPosted: Sun Jan 23, 2011 1:02 am     Reply with quote

Thank you PCM,

I adjust Vo to 0.5V and leave DB0-DB3 floating but they aren't pulled up to +5v. Their voltage are about 0.25V

I notice that there are two resistors on LCD module connecting from Anode. I'm not sure that it must add any series resistor. However I'm asking maufacturer this problem and waiting for their reply.

Moreover, I'm not sure what LED parameter value is. I guess this is below

Code:

Total LEDs   LED voltage   LED current   Total Voltage       
  1              4.2             15 mA              5


PCM, could you read LCD datasheet below. Maybe, you help me about LED parameter value and LED series resistor.
(I can't enter LED series resistor calculation page http://www.bowdenshobbycircuits.info/led.htm)


This is LCD datasheet :
http://www.mediafire.com/?io9zpabz4itz6ao
and
http://www.mediafire.com/?0z5xlt61mo0u8rf
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