Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
uidzer0
PostPosted: Dec 23, 2007 - 09:18 PM
Hangaround


Joined: Dec 03, 2007
Posts: 112
Location: Minneapolis, MN

Hey everyone,

I'm having a bit of trouble getting started with this 16x2 LCD (Seiko L1672). It uses the KS0066 interface and I've come up with the following code from what I was able to gather around the forums.

Code:

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 100000UL    // default speed for delay.h (1Mhz)
#include <util/delay.h>
   
int main(void) {   
    // Let LCD Boot up
    _delay_ms(4000);

    // Enable PB0, 1, and 2 for output (RS, RW, EN)
    DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2);

    // Enable PD0 - PD7 (D0 - D7 on LCD)
    DDRD = 0xFF;
    PORTD = 0x00;

    // Let LCD boot up
    _delay_ms(400);

    // Set RS to high
    PORTB = (1 << PB0);
    _delay_ms(40);

    // Set EN to high
    PORTB |= (1 << PB2);
    _delay_ms(40);

    // Turn Display ON
    PORTD = 0x0F;
    _delay_ms(40);          // datasheet specified at least 40us

    // Set EN to low
    PORTB &= ~(1 << PB2);

    while(1) {

    }   

    return 0;
}


I have RS, RW, and EN connected to PB0, 1 and 2 and the D0 - D7 lines connected to PD0 - PD7. The display comes on showing the first line full of squares (the same way it does when you just connect vcc, vlc, and gnd). Unfortunately, I can't seem to get a cursor - the datasheet specifies the command 0b00001111 to turn on the display and set the blinking cursor. I've added extra long delays just for testing. Can anyone point me in the right direction?

I'm using an ATMega16 with avr-gcc and I've attached the only datasheet I could find.

Any help would be great!

Thanks =]
 
 View user's profile Send private message  
Reply with quote Back to top
microcarl
PostPosted: Dec 23, 2007 - 09:25 PM
Raving lunatic


Joined: May 30, 2004
Posts: 7777
Location: Cincinnati, Ohio

Check out my recent post at:

http://www.avrfreaks.net/index.php?name ... mp;t=57816

_________________
Carl W. Livingston, KC5OTL
microcarl@roadrunner.com

It's a fundamental law of nature... All things gravitate toward total chaos!!!

The original Dragon Slayer !

Long live the AVR!!!
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
uidzer0
PostPosted: Dec 23, 2007 - 11:26 PM
Hangaround


Joined: Dec 03, 2007
Posts: 112
Location: Minneapolis, MN

Hey Carl - thanks for the code example. I attempted to change it a little bit to match your setup but I'm getting the same results (just 1 line of black squares).

Here is the modified code
Code:

#include <avr/io.h>

/*
 * Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the below copyright notice appears in all copies and that both the copyright notice and this permission notice appear in supporting documentation. Livingston Electronics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
 *
 *
 * 8 BIT LCD control program
 * Written by Carl W. Livingston
 * Modified in a attempt to get working by some other guy
 * Copyright Carl W. Livingston
 * microcarl@roadrunner.com
 * AVR Freaks member - microcarl
 * January 02, 2007
 * */

/*   //// From the LCD perspective \\\\
      LCD:R/W <-- PORTD:4
      LCD:RS <-- PORTD:5
      LCD:E <-- PORTD:6
      N/A <-> PORTD:7

      LCD:R/W <-- PORTD:4
      LCD:RS <-- PORTD:5
      LCD:E <-- PORTD:6
      LCD:Vee <-- CONTRAST
      LCD:DB0 <-- PORTB:0
      LCD:DB1 <-- PORTB:1
      LCD:DB2 <-- PORTB:2
      LCD:DB3 <-- PORTB:3
      LCD:DB4 <-- 4.7K Ohm <-- PORTx:4
      LCD:DB5 <-- 4.7K Ohm <-- PORTx:5
      LCD:DB6 <-- 4.7K Ohm <-- PORTx:6
      LCD:DB7 <-- 4.7K Ohm <-- PORTx:7

//// From the I/O PORTD perspective \\\\
      PORTD:4 --> LCD:R/W
      PORTD:5 --> LCD:RS
      PORTD:6 --> LCD:E
      PORTD:7 <-> N/A   
   
      PORTB:0 --> LCD:DB0
      PORTB:1 --> LCD:DB1
      PORTB:2 --> LCD:DB2
      PORTB:3 --> LCD:DB3
      PORTB:4 --> 4.7K Ohm --> LCD:DB4
      PORTB:5 --> 4.7K Ohm --> LCD:DB5
      PORTB:6 --> 4.7K Ohm --> LCD:DB6
      PORTB:7 --> 4.7K Ohm --> LCD:DB7
*/

/*************************************************************/
/*************************************************************/
// If you want to use a different I/O port for LCD control & data,
// do it here!!!
#define LCD_DATA_OUT PORTB
#define LCD_DATA_IN PINB
#define LCD_DATA_DDR DDRB

#define LCD_CONTROL_OUT PORTD
#define LCD_CONTROL_IN PIND
#define LCD_CONTROL_DDR DDRD

// Define LCD Read/Write as PORTx, 0x10;
#define LCD_RW 4
// Define LCD Register Select as PORTx, 0x20;
#define LCD_RS 5
// Define LCD Enable as PORTx, 0x40;
#define LCD_E 6
/*************************************************************/
/*************************************************************/

// LCD busy status bit
#define LCD_BUSY 7
// LED control bit
#define LED 1
// BAUD rate control bits
#define J_1 2
#define J_2 3
#define CGRAM 6

// Turn on power to the display, no cursor
#define   PWR_ON   0x0C
// Set 8 data bits
#define   DATA_8   0x30
// Set 8 data bits, 4 display lines
#define   LINE_8x4   0x38
// Clear display command     
#define CLR_DSP 0x01
// Character generator RAM command
#define REG_MODE 0xFE

#define NULL 0x00

void LCD_Delay (unsigned int);
void LCD_PutCmd (char);
void LCD_PutChar (char);
char LCD_BusyWait (void);
void IO_INIT (void);
void LCD_INIT (void);

int main (void) {
          // Initialize the Mega16 I/O
          IO_INIT ();
          // Initialize the HD44780 LCD controller
          LCD_INIT ();
   
          while (1) {
              LCD_PutChar('b');
          }         
}

// Clock cycle = 67nS @ 14.7456MHz   
// Delay resolution ~ 1uS @ 14.7456MHz
void LCD_Delay (unsigned int d) {
               while (d-- != 0)
               ;
               asm("nop"); // Make the delay time a bit closer to the predicted delay time.
                           // Experimentally setup with an Oscilloscope.
}

void LCD_PutCmd (char Cmd) {
    LCD_CONTROL_OUT &= ~(1<<LCD_RS);
    LCD_BusyWait();
    LCD_DATA_OUT = Cmd;   
    asm ("nop");   
    LCD_CONTROL_OUT |= (1<<LCD_E);
    asm ("nop"); // PWeh must be 230nS minimum
    asm ("nop"); // nop = 67nS @ 14.7456MHz   
    asm ("nop");
    asm ("nop"); // Here, E = 271nS @ 14.7456MHz   
    LCD_CONTROL_OUT &= ~(1<<LCD_E);
    asm ("nop");
    LCD_CONTROL_OUT |= (1<<LCD_RS);
}

void LCD_PutChar (char c) {
    LCD_CONTROL_OUT &= ~(1<<LCD_RS);
    LCD_BusyWait();
    LCD_CONTROL_OUT |= (1<<LCD_RS);
    LCD_DATA_OUT = c;
    asm ("nop");         
    LCD_CONTROL_OUT |= (1<<LCD_E);
    asm ("nop"); // PWeh must be 230nS minimum
    asm ("nop"); // nop = 67nS @ 14.7456MHz   
    asm ("nop");
    asm ("nop"); // Here, E = 271nS @ 14.7456MHz
    LCD_CONTROL_OUT &= ~(1<<LCD_E);
}

char LCD_BusyWait (void) {
    unsigned char LCDStatus;
    LCD_DATA_DDR = 0x00; // Set LCD data port to inputs
    LCD_CONTROL_OUT |= (1<<LCD_RW);
    asm ("nop");
    do {
       LCD_CONTROL_OUT |= (1<<LCD_E);   
      asm ("nop"); // PWeh must be 230nS minimum
      asm ("nop"); // nop = 67nS @ 14.7456MHz   
      asm ("nop");   
      asm ("nop"); // Here, E = 271nS @ 14.7456MHz
      LCDStatus = LCD_DATA_IN;
      LCD_CONTROL_OUT &= ~(1<<LCD_E);
    } while ((LCDStatus & (1<<LCD_BUSY)) == (1<<LCD_BUSY));
    LCD_CONTROL_OUT &= ~(1<<LCD_RW);   
    LCD_DATA_DDR |= 0xFF; // Set LCD data port to outputs     
    return (LCDStatus);
}         

void IO_INIT (void) {
    LCD_Delay (60000); // Wait for the LCD display to boot up
    // Set J_2:J_1 PULL-UPS active
    LCD_CONTROL_OUT = (1<<J_2) | (1<<J_1);
    // Set LCD_control J_2:J_1 to inputs   
    LCD_CONTROL_DDR = 0xF2;
    LCD_CONTROL_OUT |= (1<<LCD_RS); // Set LCD_RS HIGH   
    // Delay resolution ~ 1uS @ 14.7456MHz         
    LCD_Delay (15000); // Need 15mS delay for LCD to power up

    // Initialize the AVR controller I/O
    LCD_DATA_DDR = 0xFF; // Set LCD_DATA_OUT as all outputs
    LCD_DATA_OUT = 0x00; // Set LCD_DATA_OUT to logic low
}

void LCD_INIT (void) {
    // Initialize the LCD controller
    LCD_PutCmd (LINE_8x4); // Set 8 bit data, 4 display lines
    LCD_PutCmd (CLR_DSP); // Power up the display
    LCD_PutCmd (PWR_ON); // Power up the display
    LCD_Delay (30000);
    LCD_BusyWait();
}


I'm missing a basic step here, I just can't figure it out. Any help would be great.

Thanks!
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Dec 23, 2007 - 11:32 PM
Raving lunatic


Joined: Mar 27, 2002
Posts: 7755
Location: Lund, Sweden

Contrast adjustment?
 
 View user's profile Send private message  
Reply with quote Back to top
uidzer0
PostPosted: Dec 23, 2007 - 11:35 PM
Hangaround


Joined: Dec 03, 2007
Posts: 112
Location: Minneapolis, MN

JohanEkdahl wrote:
Contrast adjustment?


Sorry, didn't mention that - I have VLC connected to a 10K pot, I've adjusted up and down but still no cursor.
 
 View user's profile Send private message  
Reply with quote Back to top
microcarl
PostPosted: Dec 23, 2007 - 11:42 PM
Raving lunatic


Joined: May 30, 2004
Posts: 7777
Location: Cincinnati, Ohio

The line of black boxes indicate that the LCD hasn't been initialized properly.

You obviously have some sort of hardware error - Fosc other then what you think, or a wiring error.

The code that I gave you works as, several AVRFreaks members have used the My_LCD Serial Backpack and the code independently in their own projects. The code has been tested on about 20 different HD44780 LCD controller clones, as well. Only one HD44780 clone controller (an odd ball Optrex clone) model gave me problems, and that issue was corrected.

I'd be looking that you are running the controller at the Fosc that you think you are and, I'd also be checking for wiring errors.

One other thing...

If you are running the cMega16 controller faster the 14.7456MHz, the timing delays won't be long enough.

_________________
Carl W. Livingston, KC5OTL
microcarl@roadrunner.com

It's a fundamental law of nature... All things gravitate toward total chaos!!!

The original Dragon Slayer !

Long live the AVR!!!
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
uidzer0
PostPosted: Dec 23, 2007 - 11:49 PM
Hangaround


Joined: Dec 03, 2007
Posts: 112
Location: Minneapolis, MN

microcarl wrote:
The line of black boxes indicate that the LCD hasn't been initialized properly.

You obviously have some sort of hardware error - Fosc other then what you think, or a wiring error.

The code that I gave you works as, several AVRFreaks members have used the My_LCD Serial Backpack and the code independently in their own projects. The code has been tested on about 20 different HD44780 LCD controller clones, as well. Only one HD44780 clone controller (an odd ball Optrex clone) model gave me problems, and that issue was corrected.

I'd be looking that you are running the controller at the Fosc that you think you are and, I'd also be checking for wiring errors.

One other thing...

If you are running the cMega16 controller faster the 14.7456MHz, the timing delays won't be long enough.


Hey Carl - I'm sure you're code works so no need to defend it. I'm just trying to debug this... I've double checked the wiring - what does Fosc mean? Also, I set the speed on the mega16 to just 1mhz. Is there a way to manually test the LCD to see if it actually works?

Thanks again guys
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Dec 23, 2007 - 11:54 PM
Raving lunatic


Joined: Mar 27, 2002
Posts: 7755
Location: Lund, Sweden

Here's three things to do:

1) As Carl hints at, double check your wirings. Also check for shorts and broken connections like.

2) As a diagnostic, lower the frequency the AVR runs at to a ridicolously low value, eg 1 MHz or even lower. This is for trying to reveal timing problems where the AVR outruns the display modules controller.

3) Sleep on it...
 
 View user's profile Send private message  
Reply with quote Back to top
digitool
PostPosted: Dec 23, 2007 - 11:56 PM
Resident


Joined: Jul 02, 2003
Posts: 952
Location: Tricky Dicky City

If you have the black boxes shown and you can make them fade in and out by the contrast pot then that part of your hardware is correct.

If the black boxes remain after you try the initialization then that is not working correctly.

Pete
 
 View user's profile Send private message  
Reply with quote Back to top
microcarl
PostPosted: Dec 23, 2007 - 11:56 PM
Raving lunatic


Joined: May 30, 2004
Posts: 7777
Location: Cincinnati, Ohio

uidzer0 wrote:
...what does Fosc mean? Also, I set the speed on the mega16 to just 1mhz.

Well, if you were referring to the data-sheet you would see in the USART section that Fosc is the frequency at which the micro-controller is operating. We have been looking at the data-sheet, for both the Mega16 and the LCD, right?

uidzer0 wrote:
Is there a way to manually test the LCD to see if it actually works?

Actually, this is how I initially learned to control the HD44780 LCD displays - toggle switches and a lot of focus.

_________________
Carl W. Livingston, KC5OTL
microcarl@roadrunner.com

It's a fundamental law of nature... All things gravitate toward total chaos!!!

The original Dragon Slayer !

Long live the AVR!!!
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
uidzer0
PostPosted: Dec 24, 2007 - 12:14 AM
Hangaround


Joined: Dec 03, 2007
Posts: 112
Location: Minneapolis, MN

microcarl wrote:

Actually, this is how I initially learned to control the HD44780 LCD displays - toggle switches and a lot of focus.


Ok, I'll take this approach - just so I know that I understand this properly. To send a command I need to first set RS High, then send the command, then set E High, then set E to low?
 
 View user's profile Send private message  
Reply with quote Back to top
microcarl
PostPosted: Dec 24, 2007 - 12:17 AM
Raving lunatic


Joined: May 30, 2004
Posts: 7777
Location: Cincinnati, Ohio

uidzer0 wrote:
Ok, I'll take this approach - just so I know that I understand this properly. To send a command I need to first set RS High, then send the command, then set E High, then set E to low?
No! Bring RS and R/W low, wait about 50nS and the the LCD will accept a command, put the command data on the buss, bring E high for at least 270 nS, then bring E low. wait about 50nS and bring RS and R/W high

The same for sending ASCII text, except RS stays high R/W goes low and E toggles as in the above. The LCD will accept ASCII text.

_________________
Carl W. Livingston, KC5OTL
microcarl@roadrunner.com

It's a fundamental law of nature... All things gravitate toward total chaos!!!

The original Dragon Slayer !

Long live the AVR!!!
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
uidzer0
PostPosted: Dec 24, 2007 - 03:06 AM
Hangaround


Joined: Dec 03, 2007
Posts: 112
Location: Minneapolis, MN

Well manually initializing didn't seem to do the trick... I'm going to try to get another lcd and give that a shot. I managed to find a couple other datasheets for this thing and all of them are different, ugh. Thanks for the help guys.
 
 View user's profile Send private message  
Reply with quote Back to top
microcarl
PostPosted: Dec 24, 2007 - 03:51 AM
Raving lunatic


Joined: May 30, 2004
Posts: 7777
Location: Cincinnati, Ohio

uidzer0 wrote:
Well manually initializing didn't seem to do the trick... I'm going to try to get another lcd and give that a shot. I managed to find a couple other datasheets for this thing and all of them are different, ugh. Thanks for the help guys.


The waveform relationships between RS, R/W, E & DB7:DB0 will be the exact same thing, from HD44780 clone data-sheet to HD44780 clone data-sheet. What varies will be slight time delays from when RS & R/W change state, to when E rises to when data is accepted by DB7:DB0 the length of E, to when E falls and finally to when RS & R/W change state.

Compare the waveforms between data-sheets, and you find that they all look identical, that they all have the same terminology, and they all share only slight timing variances.

Once you understand the timing relationships among RS, R/W, E and DB7:DB0, it's a simple matter.

As far as manual testing the LCD with toggles switches goes, if you didn't debounce the E control line, I doubt that you will get the LCD to act properly, as the E control line is the most critical of the control lines, and the most temperamental.

_________________
Carl W. Livingston, KC5OTL
microcarl@roadrunner.com

It's a fundamental law of nature... All things gravitate toward total chaos!!!

The original Dragon Slayer !

Long live the AVR!!!
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits