Wednesday, April 22, 2015

16x2 LCD interface with microcontroller


4-Bit Interfacing and 8-Bit Interfacing

16x2 LCD

Interfacing with Hitatchi 44780
            The purpose of this page is to give a brief tutorial on how to interface with Hitatchi 44780 based LCDs. I have tried to provide the all the data necessary for successfully adding LCDs to your application.
             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:


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:
  1. Wait more than 15 msecs after power is applied.
  2. Write 0x030 to LCD and wait 5 msecs for the instruction to complete
  3. Write 0x030 to LCD and wait 160 usecs for instruction to complete
  4. Write 0x030 AGAIN to LCD and wait 160 usecs or Poll the Busy Flag
  5. 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
In describing how the LCD should be initialized in four bit mode, I will specify writing to the LCD in terms of nybbles. This is because initially, just single nybbles are sent (and not two, which make up a byte and a full instruction). As I mentioned above, when a byte is sent, the high nybble is sent before the low nybble and the "E" pin is toggled each time four bits is sent to the LCD. To initialize in four bit mode:
  1. Wait more than 15 msecs after power is applied.
  2. Write 0x03 to LCD and wait 5 msecs for the instruction to complete
  3. Write 0x03 to LCD and wait 160 usecs for instruction to complete
  4. Write 0x03 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag)
  5. 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 
The Character Set available in the 44780 is basically ASCII. I say "basically" because some characters do not follow the ASCII convention fully (probably the most significant difference is 0x05B or "\" is not available). The ASCII Control Characters (0x008 to 0x01F) do not respond as control characters and may display funny (Japanese) characters.



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)
================================================
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:
16x2 LCD Interfacing with ATmega8







1 comment: