Hey, guys:
First of all, I'm new here, so I'm very hopeful that I've found the right place to ask my question!
I've been working on learning electronics on my own. I'm currently working on programming an Atmel MCU (ATmega88A) to control a Newhaven 4x40 character display (NHD-0440WH-ATMI-JT#). I've followed the specification as closely as I could, but after days of banging my head against the wall, certain that I was just doing something dumb, I've decided to ask for some help. I've found a couple of folks with similar problems, but the responses have not helped me much. I'm also trying to learn C in the process, so please let me know if you have any constructive criticism there, too.
Please remember that I'm learning. I'm a Java engineer by day, so this is new territory to me.
When I power it up, lines 1 and 3 of the display are solid, while lines 2 and 4 are blank. Here is what I have so far:
lcd.h
lcd.c
main.c
I hate to drop a bunch of code on here, but I really don't know where the problem resides. I assume that I'm doing something wrong as early as 'lcd_init()' since lines 1 and 3 are still solid.
Any help whatsoever would be very, very much appreciated!
First of all, I'm new here, so I'm very hopeful that I've found the right place to ask my question!
I've been working on learning electronics on my own. I'm currently working on programming an Atmel MCU (ATmega88A) to control a Newhaven 4x40 character display (NHD-0440WH-ATMI-JT#). I've followed the specification as closely as I could, but after days of banging my head against the wall, certain that I was just doing something dumb, I've decided to ask for some help. I've found a couple of folks with similar problems, but the responses have not helped me much. I'm also trying to learn C in the process, so please let me know if you have any constructive criticism there, too.
Please remember that I'm learning. I'm a Java engineer by day, so this is new territory to me.
When I power it up, lines 1 and 3 of the display are solid, while lines 2 and 4 are blank. Here is what I have so far:
lcd.h
Code:
#ifndef LCD_H_
#define LCD_H_
#define LCD_DATA_DDR DDRB
#define LCD_CTRL_DDR DDRD
#define LCD_DATA PORTB
#define LCD_CTRL PORTD
#define LCD_E1 PIND0 // Operation Enable for Top 2 Lines
#define LCD_RW PIND1 // Read / Write (1/0)
#define LCD_RS PIND2 // Register Select (Command Register/Data Register)
#define LCD_E2 PIND3 // Operation Enable for Bottom 2 Lines
#define DEBUG_LED PINC5
#define LCD_CMD_CS 0b00000001 // Clear Screen
#define LCD_CMD_HOME 0b00000010 // Return Cursor to Home Position
#define LCD_CMD_DIR 0b00000100 // Set: Cursor Move Direction [ Pin 1 ], Display Shift [ Pin 0 ]
#define LCD_CMD_PWR 0b00001000 // Set Display: Full [ Pin 2 ], Cursor [ Pin 1 ], [ Pin 0 ] Cursor Position
#define LCD_CMD_SHIFT 0b00010000 // Set: Shift Control [ Pin 3 ], Cursor Move Direction (RTL/LTR) [ Pin 2 ]
#define LCD_CMD_FUNC 0b00100000 // Set: Data Length (8/4 Bits) [ Pin 4 ], Line Number (2/1) [ Pin 3 ], Font Size (5x11/5x8) [ Pin 2 ]
#define LCD_CMD_CGRAM 0b01000000 // Set: CGRAM Address [ Pins 5:0 ]
#define LCD_CMD_DDRAM 0b10000000 // Set: DDRAM Address [ Pins 6:0 ]
#define LCD_COLS 40
#define LCD_ROWS 4
void lcd_command ( int _command );
void lcd_init ( void );
void lcd_wait ( void );
void lcd_write ( char *_text );
void lcd_write_char ( unsigned char _char );
#endif /* LCD_H_ */
Code:
#include <asf.h>
#include <util/delay.h>
#include "lcd.h"
void lcd_command ( int _command ) {
lcd_wait();
LCD_DATA = _command;
LCD_CTRL &= ~ 1 << LCD_RW;
LCD_CTRL &= ~ 1 << LCD_RS;
lcd_wait();
LCD_DATA = 0;
}
void lcd_init ( void ) {
_delay_ms( 1000 ); // Specification >40mS
lcd_command( 0x3C );
_delay_us( 100 ); // Specification: >37uS
lcd_command( 0x3C );
_delay_us( 100 ); // Specification: >37uS
lcd_command( LCD_CMD_PWR + 0x07 );
_delay_us( 100 ); // Specification: >37uS
lcd_command( LCD_CMD_CS );
_delay_ms( 10 ); // Specification: >1.52mS
lcd_command( LCD_CMD_DIR + 0x02 );
}
void lcd_wait ( void ) {
LCD_DATA_DDR = 0x00;
LCD_CTRL |= 1 << LCD_RW;
LCD_CTRL &= ~ 1 << LCD_RS;
while ( LCD_DATA > 0x80 ) {
LCD_CTRL |= 1 << LCD_E1 | 1 << LCD_E2;
asm volatile ( "nop" );
LCD_CTRL &= ~ 1 << LCD_E1 | 1 << LCD_E2;
}
LCD_DATA_DDR = 0xFF;
}
void lcd_write ( char *_text ) {
while ( *_text > 0 ) { lcd_write_char( *_text++ ); }
}
void lcd_write_char ( unsigned char _char ) {
lcd_wait();
LCD_DATA = _char;
LCD_CTRL &= ~ 1 << LCD_RW;
LCD_CTRL |= 1 << LCD_RS;
lcd_wait();
LCD_DATA = 0x00;
}
Code:
#include <asf.h>
#include "lcd/lcd.h"
int main ( void )
{
board_init();
DDRB = 0b11111111;
DDRC = 0b11111111;
DDRD = 0b11111111;
lcd_init();
lcd_write( "Hello, World!" );
while ( 1 ) {
}
}
Any help whatsoever would be very, very much appreciated!