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

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



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Mon May 02, 2005 7:52 am     Reply with quote

If all the squares are filled black, I would say you need to adjust the contrast. Put a pot in the contrast circuit. The spec sheet mentioned before has a 10k to 20k pot. Use it.
Mark



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

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

PostPosted: Mon May 02, 2005 10:02 pm     Reply with quote

treitmey wrote:
If all the squares are filled black, I would say you need to adjust the contrast. Put a pot in the contrast circuit. The spec sheet mentioned before has a 10k to 20k pot. Use it.

That is usually how the display looks when powered up. A 4 line display usually has 2 rows of squares
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Wed May 04, 2005 10:36 pm     Reply with quote

I am baffled because I recently got in my new LCD displays and wired them up correctly, yet I get almost no output. Once powered up, the display flickers with some random lines around the screen momentarily then stays blank (I don't even get the full row of black filled in squares anymore). If I use the lcd.c driver provided by CCS, do I need to specify my display size (In my case it is 24x2 line)? I haven't modified their driver at all except to uncomment the line so I can use port b.

I have also seen people use lcd_putc("message") as well as printf(lcd_putc,"message") in their code after lcd_init(). What is the diference here, and should I get output to the lcd if I just use the former?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 04, 2005 10:46 pm     Reply with quote

Post your current test program and make it as simple possible.
It should be just a little "Hello World" program for the LCD.

One thing that bothers me is that you said you made changes
to the lcd.c file, such as enabling port b. What if you re-install
the compiler ? Then lcd.c gets restored back to the default state.
Ideally, you should put the #define use_portb_lcd TRUE
statement right above the #include <lcd.c> statement in your main file.
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Wed May 04, 2005 10:52 pm     Reply with quote

I am using this code as a test program:

Code:

#include <18F1320.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,INTRC_IO// CCPB0
#use delay(clock=8000000)
#include <lcd.c>

void main()
{
output_a(0x00);
output_b(0x00);
lcd_init();
output_high(PIN_A0);
lcd_putc("\fHello World!");
output_low(PIN_A0);
}


Also, here is the modified lcd.c file (their commented instructions said to modify the code in this way to use port b, so I was assuming it would work ok unless I misunderstood):

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,2003 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.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     D0  enable
//     D1  rs
//     D2  rw
//     D4  D4
//     D5  D5
//     D6  D6
//     D7  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
#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);
}


Where they list the portD as D0,D1,D2 etc, I just connected the proper LCD pins to my port B equivalents ENABLE=B0,RS=B1,RW=B2,etc.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 04, 2005 11:12 pm     Reply with quote

Before we go any farther, I have a couple questions.

What is the location of this modified LCD.C file ?

Did you modify the LCD.C file that's in this folder:
c:\Program Files\Picc\Drivers

Or, did you make a copy of it, and put the modified copy into your
local project folder ?

If you did the later, then you need to #include it with quotes,
so the compiler will search the local project folder. Example:

#include "lcd.c"

----------
2nd question:
When you wired up the LCD, did you take care to skip over Pin B3,
and put the data on B4-B7 ? Did you make sure that you wired
up the upper four bits of the LCD data bus to those pins (and not
the lower four) ?
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Thu May 05, 2005 12:55 am     Reply with quote

Yes, I just edited the one in c:\Program Files\Picc\Drivers. As for your second question, as the spec sheet says, to use the LCD in 4-bit mode you must use the upper nibble DB4-DB7 which correspond to pins 11-14 on the LCD. I connected these to pins B4-B7 on the PIC and connected enable to pin B0, RS to pin B1 and RW to pin B2. Pin 3 from the LCD is not connected to anything on the pic, and pin B3 on the PIC is likewise unconnected. It seems like everything should be in order, yet there is no output. Leaving pin B3 unconnected creates maximum contrast, so I would at least see something if the LCD were responding. From my code, you can see that I was using an LED to test if the init sequence completed successfully. It baffles me how it used to come on, and now it doesn't anymore without me changing the code or wiring at all.
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Thu May 05, 2005 1:13 am     Reply with quote

I ran some more tests and determined that the "filled in" line of boxes is the result of using the "Hello World!" string on the putc command. I tried just initializing the lcd and got no output, then tried various strings of different length and various single characters of single lengths and got no output for single characters and got the full "filled in" line for longer strings like "Hello World!". I know the lcd_init() and lcd_putc() functions are at least executing because my LED turns on and off like it is supposed to, so it is some communication problem between PIC and LCD. I also tried using the lower nibble of the LCD as the data pins in case using the upper nibble was the problem, but this gives me no output in any case, so I am pretty sure that couldn't be it. Any clue what this points to as the problem?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 05, 2005 3:18 am     Reply with quote

What if it's working but the contrast is set too high ?

Take a 10K trimpot and wire it in, with +5v on one side
and GND on the other, and the center tap going to the
VO pin on the LCD. Then adjust it until the dark squares
become chars.
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Thu May 05, 2005 12:45 pm     Reply with quote

I actually tried that one too Smile. Although I only have an 8k trimpot at the moment, I wired it in as you described last night and there was no change whatsoever when I adjusted its resistance. The spec sheet says to use a 10-20k pot, so maybe the resistance is just still too low. I simulated a 10k trimpot using a voltage divider of 2 10k resistors with the Vo pin going to the center where they meet and Vdd and GND on the other two sides, but I got the same thing - no change. I'll go buy a bigger trimpot and see if that makes any difference... The reason I kind of doubt that it is the contrast is because when I tried just putting a single character in the putc command, such as 'c', I got no output whatsoever. Wouldn't I expect to see one completely filled in square, or at least the full filled in line if that is the way the LCD works when there is output on a particular line?
newguy



Joined: 24 Jun 2004
Posts: 1902

View user's profile Send private message

PostPosted: Thu May 05, 2005 1:12 pm     Reply with quote

If you have the port b pullups enabled, disable them. I had a problem wiring up an lcd to port A - turns out the bulk of my problem was pin A4, which is open drain and I didn't have a pullup.

I installed the pullup and it still didn't work. Then someone here pointed me to an obscure data sheet/tech note regarding the enable pin on the hitachi compatible lcds - you can't have a pullup on it. I swapped the enable and one of the other control lines so that the enable line was not pulled up - then it worked.

This may be part of the mystery you're seeing, maybe not.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 05, 2005 1:23 pm     Reply with quote

I just played around with a little Hantronix 8x2 LCD that I have,
and I tried to make it fail. I used a simple program like this:

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

#include <lcd.c>

void main()
{
lcd_init();

printf(lcd_putc,"\fHello");

while(1);
}   


If I comment out the call to lcd_init(), I get strange characters
displayed, such as: Oo_ooo

If the contrast is not adjusted properly, then instead of those chars,
I get 8 black boxes on the top row.

I think that your LCD is not being initialized properly.
I think you should contact the manufacturer and ask for a document
that shows how to initialize the LCD (also ask for sample code).

I also think you should buy a normal 16x2 LCD from a well-known
manufacturer -- PowerTip, Hantronix, MicroTip, CrystalFontz, etc.

We know that those work. Once you get a normal LCD working,
then try your LCD.
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Sat May 07, 2005 6:14 pm     Reply with quote

In your code, how does the printf(lcd_putc,"\fHello"); differ from just calling lcd_putc("\fHello");? Would both accomplish the same thing?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 07, 2005 11:37 pm     Reply with quote

There's not much difference. Compile both and look at the .LST file.
The one with the printf is one instruction longer. Both methods call
the same routines to fetch chars and to send them to lcd_putc().
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Fri May 13, 2005 4:47 pm     Reply with quote

I Just received my hantronix displays (I ordered 16x2 as you suggested PCM programmer and 24x2). I just wired up the 16x2 display and I get the same thing Mad. The first line is completely filled in (I made sure to connect the contrast pin to the center tap of a 10k pot with one end to vdd and one end to ground) and adjusting the contrast just makes the filled in character boxes dimmer or darker. I tested disabling the pullups on port b as newguy suggested but this didn't make any change. This leads me to believe that my previous LCD displays were not the problem, since the hantronix (known to work with this driver) gives the exact same output.
Code:

#include <18F1220.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 8000000)

#include <lcd.c>

void main()
{
port_b_pullups(false);

lcd_init();

printf(lcd_putc,"\fHello");

while(1);
}


Any more ideas why this might be happening?[/i]
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 Previous  1, 2, 3  Next
Page 2 of 3

 
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