4-Bit Interfacing and 8-Bit Interfacing
Interfacing with Hitatchi 44780
The most common connector used for the 44780 based LCDs is 14 pins in a row, with pin centers 0.100" apart. The pins are wired as:
Pins
|
Description
|
1
|
Ground
|
2
|
Vcc
|
3
|
Contrast Voltage
|
4
|
"R/S" _Instruction/Register
Select
|
5
|
"R/W" _Read/Write LCD Registers
|
6
|
"E" Clock
|
7
- 14
|
Data I/O Pins
|
The different instructions available for use with the 44780
are shown in the table below:
Highlighted commands are most commonly used.
The bit descriptions for the different commands are:
For most applications, there really is no reason to read from the LCD. I usually tie "R/W" to ground and just wait the maximum amount of time for each instruction (4.1 msecs for clearing the display or moving the cursor/display to the "home position", 160 usecs for all other commands). As well as making my application software simpler, it also frees up a microcontroller pin for other uses. Different LCDs execute instructions at different rates and to avoid problems later on (such as if the LCD is changed to a slower unit), I recommend just using the maximum delays given above.
Before you can send commands or data to the LCD module, the Module must be initialized. For eight bit mode, this is done using the following series of operations:
LCD Data Lines (DB0-DB7) =>>PORTB (Pins 14,15,16,17,18,19,9,10)
RS=> PC1 (pin 24)
R/W=>GND (Most cases we don't read display make it logic 0 Low)
E=> PC0 (pin 23)
VCC=> +5V
VEE(Contrast)=> Connect this pin to ground through 1KOhm Resistor for best suited contrast value.
GND=> GND
//-----------------------------------------------------------------------------------------------------------------------
/*
* _8_BitLCD.c
*
* Created: 23-04-2015 21:02:35
* Author: Komal Manoj Thakur
*/
#include <avr/io.h>
#define F_CPU 1000000UL // 1 MHz Clock (Required for util/delay.h)
#include <util/delay.h> //used for delay, Be careful when changing optimization settings when using util/delay.h
#include <string.h> //strlen Function uses this header
//Define connections of LCD
#define LCD_Data PORTB
#define DataMode PORTC |=(1<<PC1) //Set RS Pin = Logic 1
#define CommandMode PORTC &=~(1<<PC1) //Clear RS Pin = Logic 0
#define LCD_E_High PORTC |=(1<<PC0) //Set E Pin = Logic 1
#define LCD_E_Low PORTC &=~(1<<PC0) //Clear E Pin = Logic 0
void LCD_Print(char p[16]);
void LCD_Init(char k);
void LCD_SendByte(char d);
int main(void)
{
DDRB=0xFF; //Set LCD Port Direction as output
DDRC = 0x03; //Set LCD RS and E pins as output
_delay_ms(200); //Wait for LCD to get self setup
LCD_Init(0x38); //Set interface Length 8-Bit Two Lines
LCD_Init(0x0C); //Turn Display On and cursor off
LCD_Init(0x01); //Clear LCD Display
LCD_Init(0x80); //Move Cursor to Line 1 Home position
_delay_ms(100); //Wait for LCD to get initialize
LCD_Print("circuits4you.com");
LCD_Init(0xC0); //Move Coursor to Line 2
LCD_Print("16x2 LCD");
while(1);
}
void LCD_Init(char k)
{
CommandMode; //Set LCD in COmmand Mode
LCD_SendByte(k);
}
void LCD_SendByte(char d)
{
LCD_Data=d;
LCD_E_High;
_delay_ms(20);
LCD_E_Low;
_delay_ms(20);
}
void LCD_Print(char p[16])
{
int i;
DataMode; //Set LCD in data mode
for(i=0;i<strlen(p);i++)
{
LCD_SendByte(p[i]);
}
}
//-----------------------------------------------------------------------------------------------------------------------
R/S
|
R/W
|
D7
|
D6
|
D5
|
D4
|
D3
|
D2
|
D1
|
D0
|
Instruction/Description
|
4
|
5
|
14
|
13
|
12
|
11
|
10
|
9
|
8
|
7
|
Pins
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
Clear Display
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
*
|
Return Cursor and LCD to Home Position
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
ID
|
S
|
Set Cursor Move Direction
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
D
|
C
|
B
|
Enable Display/Cursor
|
0
|
0
|
0
|
0
|
0
|
1
|
SC
|
RL
|
*
|
*
|
Move Cursor/Shift Display
|
0
|
0
|
0
|
0
|
1
|
DL
|
N
|
F
|
*
|
*
|
Set Interface Length
|
0
|
0
|
0
|
1
|
A
|
A
|
A
|
A
|
A
|
A
|
Move Cursor into CGRAM
|
0
|
0
|
1
|
A
|
A
|
A
|
A
|
A
|
A
|
A
|
Move Cursor to Display
|
0
|
1
|
BF
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
Poll the "Busy Flag"
|
1
|
0
|
D
|
D
|
D
|
D
|
D
|
D
|
D
|
D
|
Write a Character to the Display at the
Current Cursor Position
|
1
|
1
|
D
|
D
|
D
|
D
|
D
|
D
|
D
|
D
|
Read the Character on the Display at the
Current Cursor Position
|
Highlighted commands are most commonly used.
The bit descriptions for the different commands are:
"*" - Not Used/Ignored. This bit can be either "1" or "0"
Set Cursor Move Direction:
ID - Increment the Cursor After Each Byte Written to Display if Set
S - Shift Display when Byte Written to Display
Enable Display/Cursor
D - Turn Display On(1)/Off(0)
C - Turn Cursor On(1)/Off(0)
B - Cursor Blink On(1)/Off(0)
Move Cursor/Shift Display
SC - Display Shift On(1)/Off(0)
RL - Direction of Shift Right(1)/Left(0)
Set Interface Length
DL - Set Data Interface Length 8(1)/4(0)
N - Number of Display Lines 1(0)/2(1)
F - Character Font 5x10(1)/5x7(0)
Poll the "Busy Flag"
BF - This bit is set while the LCD is processing
Move Cursor to CGRAM/Display
A - Address
Read/Write ASCII to the Display
D - Data
Reading Data back is best used in applications which
required data to be moved back and forth on the LCD (such as in applications
which scroll data between lines). The "Busy Flag" can be polled to
determine when the last instruction that has been sent has completed
processing. In most applications, I just tie the "R/W" line to ground
because I don't read anything back. This simplifies the application because
when data is read back, the microcontroller I/O pins have to be alternated
between input and output modes. For most applications, there really is no reason to read from the LCD. I usually tie "R/W" to ground and just wait the maximum amount of time for each instruction (4.1 msecs for clearing the display or moving the cursor/display to the "home position", 160 usecs for all other commands). As well as making my application software simpler, it also frees up a microcontroller pin for other uses. Different LCDs execute instructions at different rates and to avoid problems later on (such as if the LCD is changed to a slower unit), I recommend just using the maximum delays given above.
Before you can send commands or data to the LCD module, the Module must be initialized. For eight bit mode, this is done using the following series of operations:
- Wait more than 15 msecs after power is applied.
- Write 0x030 to LCD and wait 5 msecs for the instruction to complete
- Write 0x030 to LCD and wait 160 usecs for instruction to complete
- Write 0x030 AGAIN to LCD and wait 160 usecs or Poll the Busy Flag
- Set the Operating Characteristics of the LCD
- Write "Set Interface Length"
- Write 0x010 to turn off the Display
- Write 0x001 to Clear the Display
- Write "Set Cursor Move Direction" Setting Cursor Behaviour Bits
- Write "Enable Display/Cursor" & enable Display and Optional Cursor
- Wait more than 15 msecs after power is applied.
- Write 0x03 to LCD and wait 5 msecs for the instruction to complete
- Write 0x03 to LCD and wait 160 usecs for instruction to complete
- Write 0x03 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag)
- Set the Operating Characteristics of the LCD
- Write 0x02 to the LCD to Enable Four Bit Mode
All following
instruction/Data Writes require two nybble writes.
- Write "Set Interface Length"
- Write 0x01/0x00 to turn off the Display
- Write 0x00/0x01 to Clear the Display
- Write "Set Cursor Move Direction" Setting Cursor Behaviour Bits
- Write "Enable Display/Cursor" & enable Display and Optional Cursor
Eight
programmable characters are available and use codes 0x000 to 0x007. They are
programmed by pointing the LCD's "Cursor" to the Character Generator RAM
We have seen all the basics of LCD now lets move to interfacing techniques.
================================================
8-Bit (10 Wire) LCD Interfacing with AVR (ATmega8)
================================================
8-Bit (10 Wire) LCD Interfacing with AVR (ATmega8)
================================================
Circuit Connections:
LCD Data Lines (DB0-DB7) =>>PORTB (Pins 14,15,16,17,18,19,9,10)
RS=> PC1 (pin 24)
R/W=>GND (Most cases we don't read display make it logic 0 Low)
E=> PC0 (pin 23)
VCC=> +5V
VEE(Contrast)=> Connect this pin to ground through 1KOhm Resistor for best suited contrast value.
GND=> GND
//-----------------------------------------------------------------------------------------------------------------------
/*
* _8_BitLCD.c
*
* Created: 23-04-2015 21:02:35
* Author: Komal Manoj Thakur
*/
#include <avr/io.h>
#define F_CPU 1000000UL // 1 MHz Clock (Required for util/delay.h)
#include <util/delay.h> //used for delay, Be careful when changing optimization settings when using util/delay.h
#include <string.h> //strlen Function uses this header
//Define connections of LCD
#define LCD_Data PORTB
#define DataMode PORTC |=(1<<PC1) //Set RS Pin = Logic 1
#define CommandMode PORTC &=~(1<<PC1) //Clear RS Pin = Logic 0
#define LCD_E_High PORTC |=(1<<PC0) //Set E Pin = Logic 1
#define LCD_E_Low PORTC &=~(1<<PC0) //Clear E Pin = Logic 0
void LCD_Print(char p[16]);
void LCD_Init(char k);
void LCD_SendByte(char d);
int main(void)
{
DDRB=0xFF; //Set LCD Port Direction as output
DDRC = 0x03; //Set LCD RS and E pins as output
_delay_ms(200); //Wait for LCD to get self setup
LCD_Init(0x38); //Set interface Length 8-Bit Two Lines
LCD_Init(0x0C); //Turn Display On and cursor off
LCD_Init(0x01); //Clear LCD Display
LCD_Init(0x80); //Move Cursor to Line 1 Home position
_delay_ms(100); //Wait for LCD to get initialize
LCD_Print("circuits4you.com");
LCD_Init(0xC0); //Move Coursor to Line 2
LCD_Print("16x2 LCD");
while(1);
}
void LCD_Init(char k)
{
CommandMode; //Set LCD in COmmand Mode
LCD_SendByte(k);
}
void LCD_SendByte(char d)
{
LCD_Data=d;
LCD_E_High;
_delay_ms(20);
LCD_E_Low;
_delay_ms(20);
}
void LCD_Print(char p[16])
{
int i;
DataMode; //Set LCD in data mode
for(i=0;i<strlen(p);i++)
{
LCD_SendByte(p[i]);
}
}
//-----------------------------------------------------------------------------------------------------------------------
Output:
very God
ReplyDelete