In this tutorial we shall explore how to connect 16 X 2 LCD with ATMEGA 16 on Development board.
By 2 ways we can connect , first one is 8 bit mode & the second is 4 bit mode
This post is on 8 BIT MODE
In 8 bit mode all port pins of a Port , say PORT B is assigned for DATA communication.
For CONTROL we need 3 more pins RS , RW & EN
RS is REGISTER SELECT RS=0 Command Register of LCD selected , RS=1 DATA Register is selected
RW is READ/WRITE pin when RW=1 LCD is in Read mode , when RW=0 LCD is in WRITE mode
Generally LCD is used to display data.So mostly RW is connected to GND ( RW=0)
PB0 to PB7 – D0 to D7 of LCD
PD4 (PIN 18) — > RS
PD5 (PIN 19)– > RW
PD6 (PIN 20) — > EN
The backlight connection & Contrast pot are taken care in the development board.
We use PROGRAMMERS NOTEPAD of WINAVR to develop the C code & Hex file .
WINAVR is a lightweight excellent tool for AVR Programming compared to the AVR STUDIO ( which is a huge download)
You can download WINAVR
https://sourceforge.net/projects/winavr/files/latest/download?source=files
Its only 29MB download & easy to install.
Once WINAVR is installed , you can see the Programmers Notepad & MFILE inside the WINAVR Folder.
Open Programmers Notepad to type in the C code.
To start with the code , include the 2 Header files on the top . avr/io.h defines all Port Registers & port pins of AVR IC & the util/delay.h is responsible for the Delay we use in the code.
#include <avr/io.h>
#include <util/delay.h>
Next we define the LCD Function definitions like
void LCD_send_command(unsigned char cmnd);
void LCD_send_data(unsigned char data);
void LCD_init(void);
Above all are user defined Functions & we’ve to write code for these functions.
For better code readability & reuse of coded we use # define statements
#define DATA_PORT PORTB
#define DATA_DDR DDRB
#define CNTRL_PORT PORTD
#define CNTRL_DDR DDRD
#define RS_PIN 4
#define RW_PIN 5
#define ENABLE_PIN 6
PORTB is defined as DATA_PORT & PORTD is defined as CNTRL_PORT , DDRB as DATA_DDR, DDRD as CNTRL_DDR
In the code , wherever DATA_PORT is mentioned it is replaced with PORTD & wherever CNTRL_PORT is mentioned is replaced with PORTD.
Also pins PD4 is defined as RS_PIN , PD5 as RW_PIN , PD6 as ENABLE_PIN .Its enough to mention only the pin number. Instead of PD5 you can mention only 5.
Later if you decide to change the port pins assigned to LCD , you need to change it in the #define statements and the rest of the code is left as it is.
First let us see the LCD_init() function which initializes the LCD
void LCD_init()
{
_delay_ms(10);
LCD_send_command(0x38);
LCD_send_command(0x0E);
LCD_send_command(0x01);
_delay_ms(10);
LCD_send_command(0x06);
}
To initialize the LCD we send the HEX values as command.The HEX command codes are
We send HEX value 0x38 to define 16 x 2 LCD 2lines & character size is 5 x 7
0x0E forDisplay ON & cursor blinking
0x06 to increment cursor
& 0x01 to Clear Screen
We send Command using Function LCD_sendcommand
Which accepts parameter as unsigned char
—————————————————–
void LCD_send_command(unsigned char cmnd)
{
DATA_PORT = cmnd;
CNTRL_PORT &= ~(1<< RW_PIN);
CNTRL_PORT &= ~(1<< RS_PIN);
CNTRL_PORT |= (1<< ENABLE_PIN);
_delay_us(2);
CNTRL_PORT &= ~(1<< ENABLE_PIN);
_delay_us(100);
}
————————————————–
Command received as unsigned char is assigned to DATA_PORT
RW pin is made LOW to enable Write operation
RS pin is made LOW to select COMMAND REGISTER
ENABLE pin is made HIGH & after a small delay made LOW ( pulse)
In the same way DATA is sent to LCD for Display using the following function :
——————————————–
void LCD_send_data(unsigned char data)
{
DATA_PORT = data;
CNTRL_PORT &= ~(1<< RW_PIN);
CNTRL_PORT |= (1<< RS_PIN);
CNTRL_PORT |= (1<< ENABLE_PIN);
_delay_us(2);
CNTRL_PORT &= ~(1<< ENABLE_PIN);
_delay_us(100);
}
—————————————
Data received as unsigned char is assigned to DATA_PORT
RW pin is made LOW to enable Write operation
RS pin is made HIGH to select DATA REGISTER
ENABLE pin is made HIGH & after a small delay made LOW ( pulse)
The next function takes 2 variables y & x & moves the cursor to that location on LCD
——————————————-
void LCD_goto(unsigned char y, unsigned char x)
{
unsigned char firstAddress[] = {0x80,0xC0,0x94,0xD4};
LCD_send_command(firstAddress[y-1] + x-1);
_delay_ms(10);
}
————————————————-
Following is the Function to print String characters on LCD
We put a string in memory location & use it as a Pointer
While String is greater than 0 , all the characters represented or pointed by the string variable is sent to LCD for printing
void LCD_print(char *string)
{
while(*string > 0)
{
LCD_send_data(*string++);
}
}
In the LCD_blink() function we send command , a hex value 0x08 to make the display OFF & after a delay we send a command Hex 0x 0C to ON the display, thus generating a blink effect
void LCD_blink()
{
LCD_send_command(0x08);
_delay_ms(250);
LCD_send_command(0x0C);
_delay_ms(250);
}
To clear the display we send command Hex 0x01 as seen in the LCD_clear function below
void LCD_clear(void)
{
LCD_send_command(0x01);
_delay_ms(100);
}
Finally in the main Function we declare PORTD as Output , as well as PORTC as OUTPUT.
This is done by assigning 0x FF to CNTRL_DDR ( PORTD) & DATA_DDR (PORTB)
Then we clear the LCD , Initialize it & go to first position & print the String
int main(void)
{
CNTRL_DDR = 0xFF;
CNTRL_PORT = 0x00;
DATA_DDR = 0xFF;
DATA_PORT = 0x00;
LCD_clear();
LCD_init();
LCD_goto(1,2);
LCD_print(“ALSELECTRO.COM”);
LCD_goto(2,3);
LCD_print(“16×2 LCD DEMO”);
Complete code for 8bit LCD MODE is as below :
—————————————————
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000UL // FCPU Definition for util/delay used in AVR STUDIO only
/*LCD function declarations */
void LCD_send_command(unsigned char cmnd);
void LCD_send_data(unsigned char data);
void LCD_init(void);
void LCD_goto(unsigned char y, unsigned char x);
void LCD_print(char *string);
void LCD_blink(void);
void LCD_clear(void);
#define DATA_PORT PORTB
#define DATA_DDR DDRB
#define CNTRL_PORT PORTD
#define CNTRL_DDR DDRD
#define RS_PIN 4
#define RW_PIN 5
#define ENABLE_PIN 6
int main(void)
{
CNTRL_DDR = 0xFF;
CNTRL_PORT = 0x00;
DATA_DDR = 0xFF;
DATA_PORT = 0x00;
LCD_clear();
LCD_init();
LCD_goto(1,2);
LCD_print(“ALSELECTRO.COM”);
LCD_goto(2,3);
LCD_print(“16×2 LCD DEMO”);
while(1)
{
}
}
/* This function sends a command ‘cmnd’ to the LCD module*/
void LCD_send_command(unsigned char cmnd)
{
DATA_PORT = cmnd;
CNTRL_PORT &= ~(1<< RW_PIN);
CNTRL_PORT &= ~(1<< RS_PIN);
CNTRL_PORT |= (1<< ENABLE_PIN);
_delay_us(2);
CNTRL_PORT &= ~(1<< ENABLE_PIN);
_delay_us(100);
}
/* This function sends the data ‘data’ to the LCD module*/
void LCD_send_data(unsigned char data)
{
DATA_PORT = data;
CNTRL_PORT &= ~(1<< RW_PIN);
CNTRL_PORT |= (1<< RS_PIN);
CNTRL_PORT |= (1<< ENABLE_PIN);
_delay_us(2);
CNTRL_PORT &= ~(1<< ENABLE_PIN);
_delay_us(100);
}
void LCD_init()
{
_delay_ms(10);
LCD_send_command(0x38);
LCD_send_command(0x0E);
LCD_send_command(0x01);
_delay_ms(10);
LCD_send_command(0x06);
}
/* This function moves the cursor the line y column x on the LCD module*/
void LCD_goto(unsigned char y, unsigned char x)
{
unsigned char firstAddress[] = {0x80,0xC0,0x94,0xD4};
LCD_send_command(firstAddress[y-1] + x-1);
_delay_ms(10);
}
void LCD_print(char *string)
//put a string in memory location & use it as POINTER
{
while(*string > 0)
{
LCD_send_data(*string++);
}
}
void LCD_blink()
{
LCD_send_command(0x08);
_delay_ms(250);
LCD_send_command(0x0C);
_delay_ms(250);
}
void LCD_clear(void)
{
LCD_send_command(0x01);
_delay_ms(100);
}
—————————————–
Download code from here
Save the file inside a folder with .C extension.
Now open the MFILE of WINAVR & set the MCU as ATMEGA16 , Port as usb , Programmer as usbasp.
To make programmer as usbasp , you need to enable editing & type in usbasp against Programmer.
If the C code is saved as main.c , then you need not change the Target in Makefile.
Save the Makefile inside the same folder where .c file exists.
Click on Tools à MakeALL to generate HEX file & then click on Program to upload the HEX file on to the ATMEGA16 chip.
To create a Header file , watch the following video :
1 Trackback or Pingback for this entry:
[…] https://alselectro.wordpress.com/2017/08/13/avr-self-learning-kit-interfacing-16-x-2-lcd-in-8-bit-mo… […]