Robolab Technologies Pvt Ltd | 8051 Tutorial 4
The tutorial for the LCD screen will use the basic 1602 type from Hitachi!! This has been cloned to death... Everyone has a copy of this chip set down to mimicking its every function.. I use “Displaytech” and “Fordata” mainly because of the cost... I'm certainly not advertising them.. Use whatever you have... But they have served me well over the past few years... To use these devices you have to set them up before you can use them.... The chip set can use a variety of sizes, the main ones being 16 character by 2 line, 20 character by 2 line, 16 character by 4 line and 20 character by 4 line. The basic commands for the display set up are shown here..8051 Tutorial 4
Tags For Robolab Technologies: College Of Engineering, Sanjay Inamdar, Bhau Institute, ABB ROBOTICS, ACET, ACET robo cell, amol gulhane, pratik deshmukh,ashutosh patil, ajit pawar, sarang kamble, Robotics, Amritsar, College Of Engineering and Technology, ARC, arduino, award, Awards, Best aesthetic award, best innovative idea award, Bhau Institute of Innovation, Bteach Projects, Btech projects, Companies who establish highly advanced and state of the art robotics labs, Complete Task, Computer, EDFEFXKITS, Electronics, embedded projects, Establishment, Experiment, fire extinguisher robot, Fire Extinguisher Robot(FIRO), Gadget, Leadership and Entrepreneurship Robolab Technologies Projects/Products: Mars Exploration Robot(MARSian), Math, Mechanics Code VIsion AVR, Mtv, Physics, Proteus ty mini project, Pune (Organization)
6063
post-template-default,single,single-post,postid-6063,single-format-standard,ajax_fade,page_not_loaded,smooth_scroll,

Blog

   

8051 Tutorial 4

The tutorial for the LCD screen will use the basic 1602 type from Hitachi!! This has been cloned to death… Everyone has a copy of this chip set down to mimicking its every function..

I use “Displaytech” and “Fordata” mainly because of the cost… I’m certainly not advertising them.. Use whatever you have… But they have served me well over the past few years…

To use these devices you have to set them up before you can use them…. The chip set can use a variety of sizes, the main ones being 16 character by 2 line, 20 character by 2 line, 16 character by 4 line and 20 character by 4 line.

The basic commands for the display set up are shown here..

lcd commands.png

This is the start of the digital communication age… devices talking to other devices we can control various devices by addressing, commands and data… As we move on through the next few tutorials we will see more and more “control” over the way we read and write to sensors and displays..

I have connected an LCD to our circuit.. The data lines D0~D7 are connected to P1 of our micro and the three control lines RS, RW and E are connected to P3 of our micro..
LCD.png
The display has 16 pins D0~D7, RS, RW, E , Vo, Vcc and Vee, we also have the Cathode and Anode for the back light.. The screen I use uses an LED back light that needs 20mA at 4.2 volts..

This needs a current limiting resistor of 0.8v /20mA ( Ohms law ) = 40 ohm resistor… This will give optimal lighting, however! I try to give the LED its best life so I decrease the current to 10mA to prolong its life… As the daylight reflection isn’t too bad and the display is still readable in the dark and the light, so I use an 80 ohm resistor to limit the back light current.. ( nearest value = 82R )

The display also needs a contrast!! The contrast varies from manufacturer to manufacturer… The small 5mm digit sized displays run with a contrast of 5 volts… Bigger displays need more contrast voltage… This can be up to 17 volts. This voltage is almost always referenced from the Vcc rail down… So the display I use has a maximum of -5 volts…. I use a small negative voltage generator… Namely the ICL7660, a small 8 pin IC that can produce the negative of the voltage that is supplied.. In our case +5 volts will produce -5 volts to generate the negative voltage the LCD contrast needs.

For your convenience just use the single rail type… then the contrast will fall between 5 volts and ground…

I have written the ASM and C code to write to the LCD screen and display messages and user input information..

Code 13

Code (asm):

org    0        ; Reset vector
sjmp    Start

org    30H        ; Code starts here
Start:
acall     LcdInit        ; Initialise screen
While:
acall    LcdGotoline1
mov    DPTR,#mess1    ; Get message 1
acall    LcdPrint
acall    LcdGotoline2
mov    DPTR,#mess2    ; Get message 2
acall    LcdPrint
mov    A,#0CDH        ; Line 2 position 13
acall    LcdCmd
jb     P0.0, SW2    ; Is switch one pressed
mov    A,#31H        ; print a ‘1’
acall    LcdData
SW2:
jb    P0.1,NS        ; Is switch two pressed
mov    A,#32H        ; print a ‘2’
acall    LcdData
NS:
sjmp    While        ; Back to loop

; Screen Init..
;—————
LcdInit:
clr    P3.6
clr    P3.7
acall    Delay15        ; Settle time
mov    P1,#33H        ; Init 1
setb    P3.5
nop
clr    P3.5        ; Init 2
acall    Delay5
setb    P3.5
nop
clr    P3.5
acall    Delay1
mov    A,#38H        ; Function set 38
acall    LcdCmd
mov    A,#0CH        ; Display on
acall    LcdCmd
mov    A,#06H        ; cursor off
acall    LcdCmd
mov    A,#01H        ; Clear and home..
acall    LcdCmd
ret

; Screen goto
;—————
LcdGotoline1:
mov    A,#080H        ; Home 0,0
acall    LcdCmd
ret

LcdGotoline2:
mov    A,#0C0H        ; Home 0,1
acall    LcdCmd
ret

; Screen Print
;—————
LcdPrint:
clr    A
Lp:
push    Acc        ; save index
movc    A,@A+DPTR    ; Get character
jz    Fin        ; NULL terminator
acall    LcdData        ; place on screen
pop    Acc
inc    A        ; Increase index
sjmp    Lp        ; Next character
Fin:
pop    Acc
ret            ; Done

; Screen Busy
;—————
LcdBusy:
mov    P1,#0FFH    ; Port as input
clr    P3.7        ; RS = 1
setb    P3.6        ; RW = 0
setb    P3.5        ; E on
nop
mov    A,P1        ; Busy flag
clr    P3.5        ; E off
clr    P3.6        ; RW = off
ret

; Screen data
;—————
LcdData:
push     Acc        ; save data
Dbusy:
acall    LcdBusy        ; See if screen is ready
jb    Acc.7,DBusy    ; Loop until it is
pop    Acc        ; get data
setb    P3.7        ; RS = 1
clr    P3.6        ; RW = 0
mov    P1,A        ; Data to screen
setb    P3.5        ; E on
nop
clr    P3.5        ; E off
clr    P3.7        ; RS = off
ret

; Screen command
;—————
LcdCmd:
push     Acc        ; save data
Cbusy:
acall    LcdBusy        ; See if screen is ready
jb    Acc.7,CBusy    ; Loop until it is
pop    Acc        ; get data
clr    P3.7        ; RS = 0
clr    P3.6        ; RW = 0
mov    P1,A        ; Command to screen
setb    P3.5        ; E on
nop
clr    P3.5        ; E off
ret

delay15:
mov    R2,#1BH        ; Aproximately 15mS
sjmp    delay
Delay5:
mov    R2,#0AH        ; aproximately 5mS
sjmp    delay
Delay1:
mov    R2,#2H        ; Aproximately 1mS
delay:
mov    R1,#0        ; 2 clock cycles (loading)    = 2
d1:
djnz    R1,d1        ; 2 * 256 clock cycles *180    = 92160
djnz    R2,d1        ; 2 * 180 clock cycles     = 380
ret            ; 2 clock cycles (return)    = 2
; * 1.0815 (11.0952 osc)    = 100.07ms

Mess1:    db    ”  PRESS A KEY   “,0
Mess2:    db    “YOU PRESSED:    “,0

END

From the code above you will see that all the commands are made by manipulating the data and control lines ( buses ). By writing several low level “device drivers” then several High level routines, we have proper control over the device connected to port 1

LcdPrint can be called to print an entire NULL terminated string to the display.. Almost automating the process.

The C code version starts to show the big differences when programming…. We can use strings as simply as typing them out.. If you examine the differences in the code, you start to understand the ease without the mundane programming…. I do not want to discourage ASM coding as its the nuts and bolts that all compilers are built on….

I program comfortably in both environments so I can get to grips with both… I have written oodles of line of code in ASM and in C.. You can include ASM into C code to make the timing aspect of ASM possible in C…

Here’s my representation of the code in C…. Representation because the code WILL start to differ greatly..

Code 14

Code (c):

#include<8051.h>        // definition file#define LCDPORT P1

__sbit __at (0xB7) RS;    // Register select pin
__sbit __at (0xB6) RW;    // Read write pin
__sbit __at (0xB5) E;    // Enable pin

void delayUs(int x)
{                // As I don’t need uS delays:—-
x/=19;            // Explanation:  This takes 380uS
while(x–);        // This takes 11uS 1000 / 19 = 52.
}                // 52 * 11uS + 380uS + 4uS = 963uS

void delayMs(int x)
{
while(x–)
delayUs(1000);    // 13uS + 963uS = 976uS (close enough )
}

unsigned char LcdBusy(void)
{
char ERR = 0;
LCDPORT = 0xFF;            // Port as input
RS = 0;                    // Set for command
RW = 1;                    // Set to read
E = 1;                    // Clock on
ERR = LCDPORT & 0x80;    // Bit 7 is busy flag
E = 0;                    // Clock off
RW = 0;                    // Set to write
if(ERR)return 1;        // Return 1 or 0
return 0;
}

void LcdCmd( unsigned char C)
{
while(LcdBusy());        // Wait until not busy
RS = 0;                    // Set to command
RW = 0;                    // Set to write
LCDPORT = C;            // Write command
E = 1;                    // Clock
E = 0;
}

void LcdData( unsigned char C)
{
while(LcdBusy());        // Wait until not busy
RS = 1;                    // Set to Data
RW = 0;                    // Set to write
LCDPORT = C;            // Write Data
E = 1;                    // Clock
E = 0;
}
void LcdInit(void)
{
delayMs(50);    // Setting time
RS = 0;            // Command
RW = 0;            // Write
LCDPORT = 0x33;    // Init value
E = 1;            // Clock
E = 0;
delayMs(15);    // Twice
E = 1;            // Clock
E = 0;
delayMs(5);        // Ready to start
LcdCmd(0x38);    // Function set
LcdCmd(0x0C);    // Display command
LcdCmd(0x06);    // Cursor conmmand
LcdCmd(0x01);    // Clear and Home command
}

void LcdClear(void)
{
LcdCmd(1);        // Clear and Home
}

void LcdPrintRam(unsigned char* str)
{
while(*str != 0)
LcdData(*str++);    // Print until NULL
}

void LcdPrintConst( const char * str)
{
LcdPrintRam((unsigned char *) str);    //Convert to ram and print
}

void LcdGoto(unsigned char x, unsigned char y)
{
x += 0x80;                // Line 1
if(y==1) x+=0x40;        // Line 2
LcdCmd(x);                // Line Command
}                        // For 4 line use 0xD4 and 0x94 as well..

void main(void)            // Main entry point
{
LcdInit();            // Get screen ready

while(1)            // Forever loop
{
LcdGoto(0,0);
LcdPrintConst(”   PRESS A KEY   “);
LcdGoto(0,1);
LcdPrintConst(“YOU PRESSED:     “);
LcdGoto(13,1);
if(!P0_0) LcdData(0x31);
if(!P0_1) LcdData(0x32);
}
}

I am hopefully going to upload the serial communication tutorial next. Simple micro ~ PC stuff….

Enjoy!

No Comment

Post A Comment