Tiny2313: PORTB only. 4.7K Ohm Ballast resistors required
between USCK, MISO and MOSI
Mega16: PORTA, PORTB, PORTC, PORTD
Mega32: PORTA, PORTB, PORTC, PORTD
Mega64: PORTA, PORTB, PORTC, PORTD, PORTE, (((PORTF JTAG disabled)))
Mega128: PORTA, PORTB, PORTC, PORTD, PORTE, (((PORTF JTAG disabled)))
Mega168: PORTD only
Mega644: PORTA, PORTB, PORTC, PORTD
// My_LCD.c
// Single port 4 BIT LCD control program
// Writen by Carl W. Livingston
//
microcarl@roadrunner.com
// AVR Freaks member - microcarl
// December 30, 2006
// **** From the LCD perspective ****
// LCD:RS = PORTx:0
// LCD:R/W = PORTx:1
// LCD:E = PORTx:2
// LCD:Vee = CONTRAST
// LCD:DB0 = GND
// LCD:DB1 = GND
// LCD:DB2 = GND
// LCD:DB3 = GND
// 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 PORTx perspective ****
// PORTx:0 = LCD:RS
// PORTx:1 = LCD:R/W
// PORTx:2 = LCD:E
// PORTx:3 = FREE TO USE
// PORTx:4 --> 4.7K Ohm --> LCD:DB4
// PORTx:5 --> 4.7K Ohm --> LCD:DB5
// PORTx:6 --> 4.7K Ohm --> LCD:DB6
// PORTx:7 --> 4.7K Ohm --> LCD:DB7
/*************************************************************/
/*************************************************************/
#include <iom64v.h>
/*************************************************************/
/*************************************************************/
// If you want to define a different LCD control & data port
// do it here!!!
#define LCD_DATA_OUT PORTF
#define LCD_DATA_IN PINF
#define LCD_DDR DDRF
/*************************************************************/
/*************************************************************/
/* Devices tested for compatability
Tiny2313: PORTB only. 4.7K Ohm Ballast resistors required
between USCK, MISO and MOSI
Mega16: PORTA, PORTB, PORTC, PORTD
Mega32: PORTA, PORTB, PORTC, PORTD
Mega64: PORTA, PORTB, PORTC, PORTD, PORTE, (((PORTF JTAG disabled)))
Mega128: PORTA, PORTB, PORTC, PORTD, PORTE, (((PORTF JTAG disabled)))
Mega168: PORTD only
Mega644: PORTA, PORTB, PORTC, PORTD
*/
// Define LCD Register Select as PORTx, 0x01;
#define LCD_RS 0
// Define LCD Read/Write as PORTx, 0x02;
#define LCD_RW 1
// Define LCD Enable as PORTx, 0x04;
#define LCD_E 2
// TURN OFF POWER TO THE DISPLAY
#define PWR_OFF 0x08
// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define PWR_ON 0x0C
// SET 8 DATA BIT MODE
#define DL_CMD 0x30
// SET 4 DATA BITS
#define DATA_4 0x20
// SET 4 DATA BITS
#define DATA_8 0x30
// SET 4 DATA BITS, 4 DISPLAY LINES
#define LINE_4x4 0x28
// SET 8 DATA BITS, 4 DISPLAY LINES
#define LINE_8x4 0x38
// INCREMENT COMMAND
#define INC_CMD 0x06
// CLEAR DISPLAY COMMAND
#define CLR_DSP 0x01
#define LINE1 0x80
#define LINE2 0xC0
#define LINE3 0x94
#define LINE4 0xD4
#define NULL 0x00
#define HIGH_MASK 0x0F
#define LOW_MASK 0xF0
const char BANNER_1[] = {"Having Fun"};
const char BANNER_2[] = {"With LCD's"};
const char BANNER_3[] = {"By"};
const char BANNER_4[] = {"Carl W. Livingston"};
void LCD_Delay (unsigned long int d);
void LCD_INIT (void);
void LCD_8_BIT_INIT(char c);
void LCD_PutCmd (char);
void LCD_PutChar (char);
void LCD_PutString (const char *);
void main (void)
{
LCD_INIT ();
while(1)
{
// Add other LCD related program operations here...
}
}
void LCD_Delay (unsigned long int d)
{
unsigned long int n;
for (n = 0; n < d; n++);
}
void LCD_INIT (void)
{
// Initialize the AVR controller I/O
LCD_DDR = 0xFF; // SET LCD_DATA TO ALL PUTPUTS
LCD_DATA_OUT = 0x01; // SET RS CONTROL LINE TO LOGIC HIGH
// Initialize the LCD controller
LCD_DATA_OUT &= ~(1<<LCD_RS);
LCD_8_BIT_INIT (DATA_8); // SET 8 BIT DATA MODE
LCD_8_BIT_INIT (DATA_8); // SET 8 BIT DATA MODE
LCD_8_BIT_INIT (DATA_8); // SET 8 BIT DATA MODE
LCD_8_BIT_INIT (DATA_4); // SET 4 BIT DATA MODE
LCD_DATA_OUT |= (1<<LCD_RS);
// The display is now in 4 bit data mode
LCD_PutCmd (LINE_4x4); // SET 4 BIT DATA, 4 DISPLAY LINES
LCD_PutCmd (CLR_DSP); // Clear the display
LCD_PutCmd (PWR_ON); // Power up the display
LCD_PutCmd (LINE1+5);
LCD_PutString (BANNER_1);
LCD_PutCmd (LINE2+5);
LCD_PutString (BANNER_2);
LCD_PutCmd (LINE3+9);
LCD_PutString (BANNER_3);
LCD_PutCmd (LINE4+1);
LCD_PutString (BANNER_4);
}
void LCD_8_BIT_INIT(char c)
{
LCD_DATA_OUT |= (1<<LCD_E);
LCD_Delay (10); // Wait for the display to respone to the E pulse
LCD_DATA_OUT = ((LCD_DATA_IN & HIGH_MASK) | (c & LOW_MASK));
LCD_Delay (10); // Wait for the display to respone to the E pulse
LCD_DATA_OUT &= ~(1<<LCD_E);
}
void LCD_PutCmd (char c)
{
LCD_DATA_OUT &= ~(1<<LCD_RS);
LCD_Delay (200); // Wait for the display to respone to R/S
LCD_PutChar(c);
LCD_Delay (200); // Wait for the display to respone to the data
LCD_DATA_OUT |= (1<<LCD_RS);
LCD_Delay (200); // Wait for the display to respone to R/S
}
void LCD_PutChar (char c)
{
// Send the MS Nibble
LCD_DATA_OUT |= (1<<LCD_E);
LCD_Delay (10); // Wait for the display to respone to the E pulse
LCD_DATA_OUT = ((LCD_DATA_IN & HIGH_MASK) | (c & LOW_MASK));
LCD_Delay (10); // Wait for the display to respone to the E pulse
LCD_DATA_OUT &= ~(1<<LCD_E);
LCD_Delay (10); // Wait for the display to respone to the E pulse
// Send the LS Nibble
LCD_DATA_OUT |= (1<<LCD_E);
LCD_Delay (10); // Wait for the display to respone to the E pulse
LCD_DATA_OUT = ((LCD_DATA_IN & HIGH_MASK) | ((c * 16) & LOW_MASK));
LCD_Delay (10); // Wait for the display to respone to the E pulse
LCD_DATA_OUT &= ~(1<<LCD_E);
}
void LCD_PutString (const char *p)
{
char n = NULL; // Pointer position counter.
while (p[n] != NULL) // Keep sending data until the NULL character is found.
LCD_PutChar(p[n++]);
}