Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to interface 16×2 LCD and 4×4 keypad with AT89S52 using Keil uVision 4

Status
Not open for further replies.

StevenStudent

Newbie
Newbie level 3
Joined
Sep 22, 2013
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,366
How to interface 16×2 LCD and 4×4 keypad with AT89S52 using Keil uVision4

Hello.

I need assistance with initializing the 16×2 LCD with the microprocessor. I don't need to know how the initializing is done. All I need is a include file (something like lcd.h) and a simple Keil uVision4 fully copy-pasteable program that will initialize my LCD and demonstrate a simple example of a function that can read the value of the keypad and another function that can write the keypad’s value to the LCD.

The LCD is connected as follows:
Port 2 (0-7) = LCD data lines
Port 3_0 = RS
Port 3_1 = E

The keypad is connected to Port 1.

The keypad's opperation is not as crutial as the LCD's. I can figure it out without assistance. All I rely need is the LCD library and the C code that contains a working LCD write function. This I will copy into my C file of my uVision4 project, compile the hex file and plug it into my simple Proteus circuit that I have explained above.

The RW line is grounded as I don’t want to read from the LCD. I just want to write to it. I will run this simulation on Proteus to confirm its operation.

Thank you.
 
Last edited:

I guess the LCD program is easier than the keypad program. So when you can manage the keypad program, whats the difficulty with the lcd part. If you are facing some problem or stuck somewhere in your program then post it here, we will help you.

Code is available , but it will be good if you make it yourself.
 
Last edited:

hello use 4-bit data lines instead of 8-bit your pin count will save.
 

REPLY FROM THREAD CREATOR

Hello again. I forgot to mention that I have more than enough pins and prefer to keep things simple by using 8 bit mode.

errakeshphillia I am indeed stuck on this small problem and I'm running out of time. Need assistance ASAP! I have pasted my lcd.h file here after my code. I cannot understand how the compiler knows which pins are the data ports and RS, WR and EN pins. I took a wild guess in simply using the #define (pin/port) but somehow I don't think its that easy. Or is it. Have a look.

======================================================================================================
This is what I think the code should look like.
======================================================================================================

#include <AT89X52.h>
#include <lcd.h> // I have a lcd.h file that I will include after this main code.

#define LCD_data P2
#define LCD_RS P3_0
#define LCD_EN P3_1

void main (void)
{
LCD_Init();
LCD_Data_Wr(posX, posY, data);
}
======================================================================================================

I think I'me leaving out fundamental points.

I am running OSC frequency at 11.0592Hz.

======================================================================================================
This is my lcd.h file copy, pasted.
======================================================================================================

/*+++++++++++++++++++++++++++++++LCD Routines+++++++++++++++++++++++
/*************************************************
* Programmer : AJJ Mouton *
* Keil uVision Compiler *
* Intialiation of LCD *
*************************************************/

#include <absacc.h>
#include <AT89X52.h>

#define DataAddr 0x6001
#define CommAddr 0x6000
#define Time5ms 94
#define Time20ms 376
#define Time1s 18807


const unsigned char clear[17]=" ";

/********************************
Delay Routine
********************************/
void Delay(unsigned long TimeCnt){
unsigned long Cntr;
for (Cntr = 0; Cntr < TimeCnt; Cntr++){;}
}

/***************************************
LCD write Command from LCD.C
**************************************/
void LCD_Command_Wr(unsigned char Command){
XBYTE[CommAddr] = Command;
Delay(Time5ms); // Delay 5ms
}

/******************************************************
Initialise LCD Display on Data Bus from LCD.C
RW must be grounded RS connected to A0
******************************************************/
void Init_LCD(void){
unsigned char Teller;
Delay(Time20ms); // 20 msec
for(Teller = 0; Teller < 3; Teller++)
{
LCD_Command_Wr(0x30); // Function set
}
LCD_Command_Wr(0x3C);
LCD_Command_Wr(0x08); // Display off
LCD_Command_Wr(0x01); // Display clear
LCD_Command_Wr(0x06); // Entry mode set
LCD_Command_Wr(0x0C); //Display on
Delay(Time20ms); // Delay 20ms
}

/****************************************************
Write a Single ASCII Character to a 16x2 LCD Display
Y = line 0 or 1
X = Position 0 to 15 on the line
Ch = ASCII character to be written on LCD
****************************************************/
void LCD_Data_Wr(unsigned char X, unsigned char Y, unsigned char Ch){
unsigned char Offset;
switch (Y){
case 0:
Offset = 0x00;
break;
case 1:
Offset = 0x40;
}
LCD_Command_Wr((Offset + X) | 0x80); // Position the cursor
XBYTE[DataAddr] = Ch; // Write ASCII data to the display
Delay(Time5ms); // Delay 5 ms
}

/***************************************************
Write an 8 or 16 bit Variable to a 16x2 LCD Display
Y = line 0 or 1
X = Position 0 to 15 on the line
VarSize: Byte = 1, Word = 2
***************************************************/
void LCD_Variable_Wr(char Digits, char X, char Y, unsigned int Var){
unsigned char Offset=0, Cntr=0, SizeOffset=0, Temp=0;
unsigned int Val=0, VarIn;
char DispArr[5];

VarIn = Var;

switch (Y){
case 0:
Offset = 0x00;
break;
case 1:
Offset = 0x40;
break;
default:
Offset = 0x40;
break;
}

LCD_Command_Wr((Offset + X) | 0x80); // Position the cursor
for (Cntr = 5; Cntr > 0; Cntr--){
Val = Var%10;
Var = Var/10;
Temp = (char)Val;
DispArr[Cntr-1] = (Temp) + 0x30; // Determine BCD value and convert to ASCII
}
if(Digits == 1){SizeOffset = 4;} //1 character

if(Digits == 2){SizeOffset = 3;} //2 characters

if(Digits == 3){SizeOffset = 2;} //3 characters

if(Digits == 4){SizeOffset = 1;} //4 characters

if(Digits == 5){SizeOffset = 0;} //5 characters



for (Cntr = SizeOffset; Cntr < 5; Cntr++){
XBYTE[DataAddr] = DispArr[Cntr]; // Write ASCII data to the display
Delay(Time5ms); // Delay 5 ms
}
}

//***********************************************
void ClearScreen(void){
unsigned char i;

for(i=0;i<16;i++) //Clear screen
LCD_Data_Wr(i,0,clear);

for(i=0;i<16;i++) //Clear screen
LCD_Data_Wr(i,1,clear);
}
//+++++++++++++++++++++LCD END++++++++++++++++++
======================================================================================================
 

errakeshphillia I am indeed stuck on..........
It should have been errakeshpillai.. :) . Never mind..

Now, tell me which LCD are you using..?
Also, I guess you are just making a simple project and so all these advanced write functions might not be needed which is making it difficult to understand. You can cut it short to simple functions. I'll post the code snippets when I get back home after 6 hrs..
 

REPLY FROM THREAD CREATOR

I am using the LCD with part number LM016L in Proteus. It is a standard 16x2 LCD with 8 data lines, RS, RW, E, VSS, VEE and VDD.

The eventual goal is to set up a system that works like a Alpha Numeric Keypad. Whatever is typed on the keypad must be displayed on the display. I think for this job the functions, although making life difficult now to figure out, will make life a lot easier once I start using the timer/counter so sense delay times for a held in key and the time window after a key is pressed to decide weather the next key pressed is a new character or the next character on that key. But this is not rely relevant. All I need is the working functions that will enable me to print to the LCD and continue my struggle to success with this project.

The following Dropbox link contains a blank uVision4 Project setup to my requirements, the Proteus Circuit diagram and the lcd.h file I have.
https://www.dropbox.com/sh/tvvl0izdcsowomr/df0Dup2mJY

My wishlist is that someone writes the code into my project that makes reading and writing to the LCD understandable and easy.
 

I have attached an LCD header which has simple write function implemented. You can just check it out whether it will of some use to you or not.

Code:
#define lcd_data P0
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;

void write_lcd(unsigned char dat)
{
	lcd_data=dat;
	rw=0;
	en=1;
	en=0;
	delay_ms(1);
}

void cmd_lcd(unsigned char cmd)
{
	rs=0;
	write_lcd(cmd);
}

void disp_lcd(unsigned char c)
{
	rs=1;
	write_lcd(c);
}

void init_lcd(void)
{
	cmd_lcd(0x01);
	cmd_lcd(0x02);
	cmd_lcd(0x06);
	cmd_lcd(0x0e);
	cmd_lcd(0x38);
	cmd_lcd(0x80);
}

void str_lcd(char *s)
{
	while(*s)
		disp_lcd(*s++);
}
/*
void int_lcd(unsigned int n)
{
	char a[5]={0},i=0;
	if(n==0)
	{
		disp_lcd('0');
		return;
	}
	else
	{
		while(n>0)
		{
			a[i++]=((n%10)+48);
			n=n/10;
		}
		for(--i;i>=0;i--)
		{
			disp_lcd(a[i]);
		}
	}
}

void float_lcd(float f)
{
	int i;
//	unsigned char j;
	i=f;
	int_lcd(i);
	disp_lcd('.');
	f=(f-i)*1000;
	i=f;
	int_lcd(i);
	for(j=0;j<3;j++)
	{
		f=(f-i)*10;
		i=f;
		int_lcd(i);
	}
}
*/
 

REPLY FROM THREAD CREATOR

Looks like the code I'me looking for I just need to study it and figure out how to get it working on my computer.

I have a few questions about the code though.

* What is the function of the pointer

* Does sbit rs=P2^0; do the job that #declare? Does it automatically make it an output. How would you make that line a input?

* Is there a standard library that contains delay_ms()?

Thank you.
 

Ans 1: I don't know which pointer you are talking about. But the only pointer used is in the str_lcd function which is used to receive a string , which is a char pointer.

Ans 2: sbit is a pre-defined datatype in embedded C for 8051. The difference between #define and sbit is same as the difference between a variable and a macro usage. Also defining a variable of sbit type will not make it output/input automatically. Since this is a header file, it will not take care of that fact and is taken care of in the main program itself.

Ans 3: No, I don't now any library having delay_ms as a standard function. The delay function that I have used here has been defined by me and its definition was in another file which I missed out. But I guess you can work that out.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top