Half a display? LCD Problem. [SORTED]

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've only been using AVRs for a matter of weeks so I apologise if any of this seems obvious to you guys. This is my first LCD project and I am driving a standard 16 x 1 line LCD display using a Mega 16. I am using Port A to drive the LCD (4 bit I/O mode) and am using the LCD libraries downloaded from Peter Fleury's web site for a HD44780 controller. I have altered the LCD.h file appropriately to set the Port and lines used appropriately.
OK, now for the problem - I'm using a very simple program (see code below) but can only get the left most 8 characters of the 16 character display to show. Any string of text sent to the display gets truncated to 8 characters maximum length. I send the string "test program" and the display shows "test pro" on the left hand side of the display.

// Program to test 16 x 1 LCD display
// Device = AtMega 16
// Clock = 8MHz internal RC

#include 
#include 
#include 
#include 
#include 
#include 
              
int main(void)
{
lcd_init(LCD_DISP_ON_CURSOR);
while(1)
	{
	lcd_clrscr();
	_delay_ms(1000);
	lcd_puts("test program");
		_delay_ms(1000);
	lcd_clrscr();
	lcd_puts("1234567890");
		_delay_ms(1000);

	}
}

I have tried changing the length of line etc in the LCD.h file and have tried porting the LCD display to different ports on the Mega 16 but I still only get the left half of the display.
I'm currently using Port A with the following connections:-
PA1 = LCD R/W
PA2 = LCD RS
PA3 = LCD EN
PA4 = LCD Data 0
PA5 = LCD Data 1
PA6 = LCD Data 2
PA7 = LCD Data 3
Text appears ok and is not corrupted so I guess I have the Port lines configured ok.
The relevant section of the LCD.h file is shown below:

#include 
#include 

/** 
 *  @name  Definitions for MCU Clock Frequency
 *  Adapt the MCU clock frequency in Hz to your target. 
 */
#define XTAL 8000000              /**< clock frequency in Hz, used to calculate delay timer */


/**
 * @name  Definition for LCD controller type
 * Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller.
 */
#define LCD_CONTROLLER_KS0073 0  /**< Use 0 for HD44780 controller, 1 for KS0073 controller */

/** 
 *  @name  Definitions for Display Size 
 *  Change these definitions to adapt setting to your display
 */
#define LCD_LINES           1     /**< number of visible lines of the display */
#define LCD_DISP_LENGTH    16     /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH  0x50     /**< internal line length of the display    */
#define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2  0x40     /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3  0x14     /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4  0x54     /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES      0     /**< 0: no wrap, 1: wrap at end of visibile line */

#define LCD_IO_MODE      1         /**< 0: memory mapped mode, 1: IO port mode */
#if LCD_IO_MODE
/**
 *  @name Definitions for 4-bit IO mode
 *  Change LCD_PORT if you want to use a different port for the LCD pins.
 *
 *  The four LCD data lines and the three control lines RS, RW, E can be on the 
 *  same port or on different ports. 
 *  Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
 *  different ports. 
 *
 *  Normally the four data lines should be mapped to bit 0..3 on one port, but it
 *  is possible to connect these data lines in different order or even on different
 *  ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
 *  
 */
#define LCD_PORT         PORTA        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    4            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    5            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    6            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    7            /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
#define LCD_RS_PIN       2            /**< pin  for RS line         */
#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
#define LCD_RW_PIN       1            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_PORT     /**< port for Enable line     */
#define LCD_E_PIN        3            /**< pin  for Enable line     */

I have plugged the display into a different AVR project, developed independantly by someone else and the display works fine - all 16 characters!
What am I missing? I've searched the forum but can find no mention of this particular problem. I have checked the board wiring for shorted or open tracks and all is ok. If anyone can shed any light on this I would be very grateful.

Last Edited: Fri. Aug 28, 2009 - 07:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I am driving a standard 16 x 1 line LCD display using a Mega 16.

Look at your LCD data sheet. I think you will find it calls position 1..8 line #1 and position 9..16 line#2 or something equally strange.

So you should call it a 8 x 2 display not a 16 x 1 display.

But it is your data sheet.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mmm.. I'm suprised if that is the case, but I'll check it out. Thanks for the response.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you tried the HD44780 code from the GCC manual?

http://www.nongnu.org/avr-libc/u...

Assuming that worked, if you single stepped that in the simulator you may be able to spot where it does something different to the code you are using.

Looking at the Fleury code I see his lcd_putc has these checks:

void lcd_putc(char c)
{
    uint8_t pos;


    pos = lcd_waitbusy();   // read busy-flag and address counter
    if (c=='\n')
    {
        lcd_newline(pos);
    }
    else
    {
#if LCD_WRAP_LINES==1
#if LCD_LINES==1
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
        }

So I can only assume the 'pos' value being read back is not the expected or correct?

You could simply try removing this test and see if that helps.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dylan85:
David is correct so get ready to be surprised. The problem is here:

Quote:
#define LCD_LINES 1 /**< number of visible lines of the display */
The number of lines that you must specify is NOT the "number of visible lines of the display". You must specify the number of lines of DDRAM memory that are being used, as interpreted by the LCD controller. The only choices are 1 or 2.
Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestions so far guys.
David and Don - I have tried changing the LCD Lines in the lcd.h file as suggested and still no luck - I'm beginning to doubt my own sanity here!
Clawson - No I haven't tried the code from the GCC manual yet, I want to exhaust all possibilities here first(It is so close to working correctly). I have to say that some of your post has gone straight over my head - I'm afraid I am a long term analog guy who has only been dabbling with 'C' and AVRs for around 6 or 8 weeks now, so am very much at the novice end of the scale and although making progress, this lcd problem is really bogging me down. However, I will persist and any other suggestions will be welcome but please keep them simple for a poor simple analogue guy. :lol:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The data sheet for your actual module is the authoritative answer.

But you can do some simple checks like :

for (i = 'A'; i <= 'A' + 64; i++) lcd_putchar(i);

I would personally configure "lcd.h" for 8 x 2 and just try this. Then configure for 16 x 1 and see if you get a difference.

The other test is to just use the raw functions to set the write position, and write to the DRAM.

and see what you get.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That sounds like a sensible approach. Thanks, I'll give it a try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ther has been hints about a data sheet for the display earlier in this thread. Do you have access to a data sheet? Or do you at least have a make and model number of the display?

There are single line displays that have one simple sequence of DDRAM adresses for the character cells. But there also exists single line displays that has a more "esoteric" equence of DDRAM addresses for the character cells.

From Optrex' document on LCD modules:

Quote:
16 character x 1 line displays (1/16 duty)
In order to properly address these modules, they must be operated as 8 character x 2 line displays where the first 8
characters represent line 1 and the last 8 represent line 2.

Even with this, you'd think that the DDRAM address of the first character on "the second line" is the last address on "the first line" plus one, but no. The address sequence is (hex) 00, 01, 02, 03, 04, 05, 06, 07, 40, 41, 42, 43, 44, 45, 46, 47.

I have two favourite 44780 documents, which I have attached in a post here: https://www.avrfreaks.net/index.p... .

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dylan85:

This forum topic has helped spur me on to update some LCD Addressing information that I have been working on for a while. It should help you understand what David, Johan, and I have been trying to get across. You can find it at http://web.alfredstate.edu/weimandn. Look for the LCD Addressing link.

Since you are able to display text on your display it is obvious that you have the connections and the timing right. It looks like it's just an addressing problem which this information should help you understand.

Don't forget that you are really dealing with a 2-line display as far as the LCD controller is concerned.

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don!

I just quickly browsed that page of yours, and it looks excellent! The link to it will promptly be added to my "valuable links" repository so that I can refer similar discussions to it in the future.

Nice work, both in factual contents and style!

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don,
Thanks for that link, it has finally explained what I have been struggling to understand all this time i.e. why a so called simple single line lcd has been such a pig to drive correctly. That explanation of lcd addressing is excellent and I'm impressed that the author has taken the time to put that all together in such a clear and straightforward manner - first class. It seems my lcd is the type referred to as 'type 1'. Now that has taken away a lot of the mystery, it seems that what I need to do now is configure lcd.h correctly in order to address the display as described. The datasheet I have for the display is very basic and does not fully describe the display addressing, hence my lack of understanding.

As it happens it turns out that the display addressing is what Johan and David were saying all along but I couldn't grasp it in its entirety.

Thanks again for all the input and I'll try to implement this soon.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorted at last!!
The LCD display is working correctly and what's more I think I understand it now. That's got to be good. However, it still wasn't straight forward:-
After configuring the lcd.h file for a 2 x 8 display and setting the DDRAM addresses, it still had the same problem i.e. only half the display was working, this was really bugging me now :(
What I did notice though was that when I turned the contrast up I could see faintly in the background the second set of 8 character blocks which I couldn't previously see, so that suggested to me that the display was being initialised correctly. In addition, when I held the Mega16 in a reset condition I could see (very faintly) a cursor moving through all 16 display positions in a random manner. So, I reasoned things are close to working. I tried changing various line and display length settings to no avail until almost in desperation I changed the word wrap to 1. Voila! Now it was working. I assume that with the word wrap turned off, the text was overlapping into the next sequential block of DDRAM rather than the address area for the second line. In previous attempts to get the display working I was sure I had set word wrap to 1 but at that stage I hadn't appreciated the 2 x 8 requirement and the non contiguous DDRAM settings, so it made no difference. So, a hard lesson learned and I can almost hear you all saying "I told you so", but a lesson learned in this manner is a lesson that won't be forgotten in a hurry.
It turns out that Don's statement:-

Quote:
David is correct so get ready to be surprised.
was bang on.
I was suitably suprised.

This has proved to be an excellent forum for the exchange of ideas and information and I very much appreciate the input from all who responded. Keep up the good work.

Paul