Sunteți pe pagina 1din 42

Project report

On

Digital clock using LCD display


ACKNOWLEDGEMENT

Apart from the efforts of me, the success of this project depends largely on
the encouragement and guidance of many others. I take this opportunity to
express my gratitude to the people who have been instrumental in the
successful completion of this project.
I would like to show my greatest appreciation to Er.Vishu Grover from
Innovation Research and Development. I can’t say thank you enough for
their tremendous support and help. I feel motivated and encouraged every
time. Without their Encouragement and Guidance this project would not
have materialized.
The guidance and support received from my friend (name) who contributed
and are contributing to this project, was vital for the success of the project. I
am grateful for their constant support and help.
DECLARATION

We hereby declare that the project work entitled (“Digital Clock”) is an


authentic records of my own work carried out at innovation research and
Development. Internship Project for the award of Degree of B.TECH-ECE,
(college name) under the guidance of VISHU GROVER, during July to
December 2010

Name of Student:
Registration Number
ABSTRACT:
This project incorporates the functionality of a digital clock and a digital thermometer.
The digital clock works in 12 hour mode and is configured by programming the 8051
microcontroller (AT89C51). The program uses a delay function for producing a delay of
1 second. The clock and alarm times can be set through a set of external tactile switches.
The digital thermometer employs a temperature sensor LM35. The sensor responds to the
temperature change by giving varying output. These analog signals of LM35 are
converted to digital equivalent by ADC0804. The reference voltage (Vref) should be set
properly corresponding to the desired temperature range. The data bits are taken as input
by the microcontroller at port P0. The microcontroller AT89C51 also gives control
signals to ADC0804.

This project is a clock that displays the time and date on seven segment led displays. Two
buttons are used to set the time and date. The program takes care of changing the date and
keeping track of leap years. In this project, we have built a digital clock with 12 hour
count time. The clock runs from 00:00 to 11:59 and then back to 00:00. Our display has
four digits, two digits for minutes and two for hour. The specialty of this clock is that it
has very low power consumption and condensed layout.
SUMMARY:

This project works as a digital clock wherein a user can also set alarm. Additionally, it
also works as a digital thermometer to specify the ambient temperature. Both, the clock
and temperature are displayed on a 16x2 LCD screen using the 8051 microcontroller
(AT89C51). AT89C51 is an eight bit controller which belongs to the 8051 family of
microcontrolers.

This clock works in 12 hour mode and is configured by programming


the microcontroller AT89C51. The program uses a delay function for
producing a delay of 1 second.

The connections in the circuit are as following: port P2 of


microcontroller is used as data input port which is connected to data
pins (7-14) of LCD. P3^0, P3^1 and P3^6 pins of microcontroller are
connected to control pins RS, RW and EN of LCD. P1^0, P1^1, P1^2
and P1^3 pins of microcontroller are connected to tactile switches to
take manual inputs.

On reset, the LCD prompts the user to set time. Only the hour and
minute components can be set by pressing the corresponding
switches, repeatedly. These switches are made active low and so they
provide ground to the corresponding input pins of the controller. The
AM/PM mode is set by toggling the switch between ground and Vcc.
Ground would set the clock in AM mode while Vcc would set it in PM
mode. The clock starts when start pin is connected to Vcc by pressing
the switch. The set time is displayed on LCD screen and changes as
the time passes on. Seconds are increased after every one second by
making use of delay function. As second reaches 59, minute is
incremented by one and second is reset to 0. Similarly, as minute
reaches 59, hour is increased by one and minute is set to 0. After hour
reaches 11, minute reaches 59 and second reaches 59, all of them are
set to 0 and the AM/PM mode is changed accordingly.

Circuit description
Components used

Preset
A preset is a three legged electronic component which
can be made to offer varying resistance in a circuit. The
resistance is varied by adjusting the rotary control over
it. The adjustment can be done by using a small screw
driver or a similar tool. The resistance does not vary
linearly but rather varies in exponential or logarithm...

AT89C51 or 89C51 microcontroller

AT89C51 is an 8-bit microcontroller and belongs to Atmel's


8051 family. AT89C51 has 4KB of Flash programmable and
erasable read only memory (PEROM) ...

LCD

LCD (Liquid Crystal Display) screen is an electronic display


module and find a wide range of applications. A 16x2 LCD
display is very basic module and is very commonly used in
various devices and circuits. These modules are preferred over
seven segments and other multi segment...

Interfacing switch with 8051

Lcd interfacing with microcontroller


Introduction

The most commonly used Character based LCDs are based on Hitachi's
HD44780 controller or other which are compatible with HD44580. In
this tutorial, we will discuss about character based LCDs, their
interfacing with various microcontrollers, various interfaces (8-bit/4-
bit), programming, special stuff and tricks you can do with these
simple looking LCDs which can give a new look to your application.

For Specs and technical information HD44780 controller Click Here

Pin Description

The most commonly used LCDs found in the market today are 1 Line, 2
Line or 4 Line LCDs which have only 1 controller and support at most of
80 charachers, whereas LCDs supporting more than 80 characters
make use of 2 HD44780 controllers.

Most LCDs with 1 controller has 14 Pins and LCDs with 2 controller has
16 Pins (two pins are extra in both for back-light LED connections). Pin
description is shown in the table below.

Figure 1: Character LCD type HD44780 Pin diagram

Pin No. Name Description


Pin no. 1 VSS Power supply (GND)
Pin no. 2 VCC Power supply (+5V)
Pin no. 3 VEE Contrast adjust
0 = Instruction input
Pin no. 4 RS
1 = Data input
0 = Write to LCD module
Pin no. 5 R/W
1 = Read from LCD module
Pin no. 6 EN Enable signal
Pin no. 7 D0 Data bus line 0 (LSB)
Pin no. 8 D1 Data bus line 1
Pin no. 9 D2 Data bus line 2
Pin no. 10 D3 Data bus line 3
Pin no. 11 D4 Data bus line 4
Pin no. 12 D5 Data bus line 5
Pin no. 13 D6 Data bus line 6
Pin no. 14 D7 Data bus line 7 (MSB)
Table 1: Character LCD pins with 1 Controller

Pin No. Name Description


Pin no. 1 D7 Data bus line 7 (MSB)
Pin no. 2 D6 Data bus line 6
Pin no. 3 D5 Data bus line 5
Pin no. 4 D4 Data bus line 4
Pin no. 5 D3 Data bus line 3
Pin no. 6 D2 Data bus line 2
Pin no. 7 D1 Data bus line 1
Pin no. 8 D0 Data bus line 0 (LSB)
Pin no. 9 EN1 Enable signal for row 0 and 1 (1stcontroller)
0 = Write to LCD module
Pin no. 10 R/W
1 = Read from LCD module
0 = Instruction input
Pin no. 11 RS
1 = Data input
Pin no. 12 VEE Contrast adjust
Pin no. 13 VSS Power supply (GND)
Pin no. 14 VCC Power supply (+5V)
Pin no. 15 EN2 Enable signal for row 2 and 3 (2ndcontroller)
Pin no. 16 NC Not Connected
Table 2: Character LCD pins with 2 Controller

Usually these days you will find single controller LCD modules are used
more in the market. So in the tutorial we will discuss more about the
single controller LCD, the operation and everything else is same for the
double controller too. Lets take a look at the basic information which is
there in every LCD.

►DDRAM - Display Data RAM

Display data RAM (DDRAM) stores display data represented in 8-bit


character codes. Its extended capacity is 80 X 8 bits, or 80 characters.
The area in display data RAM (DDRAM) that is not used for display can
be used as general data RAM. So whatever you send on the DDRAM is
actually displayed on the LCD. For LCDs like 1x16, only 16 characters
are visible, so whatever you write after 16 chars is written in DDRAM
but is not visible to the user.

Figures below will show you the DDRAM addresses of 1 Line, 2 Line and
4 Line LCDs.

Figure 2: DDRAM Address for 1 Line LCD

Figure 3: DDRAM Address for 2 Line LCD

Figure 4: DDRAM Address for 4 Line LCD


►CGROM - Character Generator ROM

Now you might be thinking that when you send an ascii value to
DDRAM, how the character is displayed on LCD? so the answer is
CGROM. The character generator ROM generates 5 x 8 dot or 5 x 10
dot character patterns from 8-bit character codes (see Figure 5 and
Figure 6 for more details). It can generate 208 5 x 8 dot character
patterns and 32 5 x 10 dot character patterns. Userdefined character
patterns are also available by mask-programmed ROM.

Figure 5: LCD characters code map for 5x8 dots


Figure 6: LCD characters code map for 5x10 dots

As you can see in both the code maps, the character code from 0x00
to 0x07 is occupied by the CGRAM characters or the user defined
characters. If user want to display the fourth custom character then
the code to display it is 0x03 i.e. when user send 0x03 code to the LCD
DDRAM then the fourth user created charater or patteren will be
displayed on the LCD.

►CGRAM - Character Generator RAM

As clear from the name, CGRAM area is used to create custom


characters in LCD. In the character generator RAM, the user can
rewrite character patterns by program. For 5 x 8 dots, eight character
patterns can be written, and for 5 x 10 dots, four character patterns
can be written. Later in this tutorial i will explain how to use CGRAM
area to make custom character and also making animations to give
nice effects to your application.
►BF - Busy Flag

Busy Flag is an status indicator flag for LCD. When we send a


command or data to the LCD for processing, this flag is set (i.e BF =1)
and as soon as the instruction is executed successfully this flag is
cleared (BF = 0). This is helpful in producing and exact ammount of
delay. for the LCD processing.

To read Busy Flag, the condition RS = 0 and R/W = 1 must be met and
The MSB of the LCD data bus (D7) act as busy flag. When BF = 1
means LCD is busy and will not accept next command or data and BF
= 0 means LCD is ready for the next command or data to process.

►Instruction Register (IR) and Data Register (DR)

There are two 8-bit registers in HD44780 controller Instruction and


Data register. Instruction register corresponds to the register where
you send commands to LCD e.g LCD shift command, LCD clear, LCD
address etc. and Data register is used for storing data which is to be
displayed on LCD. when send the enable signal of the LCD is asserted,
the data on the pins is latched in to the data register and data is then
moved automatically to the DDRAM and hence is displayed on the LCD.
Data Register is not only used for sending data to DDRAM but also for
CGRAM, the address where you want to send the data, is decided by
the instruction you send to LCD. We will discuss more on LCD
instuction set further in this tutorial.

►Commands and Instruction set

Only the instruction register (IR) and the data register (DR) of the LCD
can be controlled by the MCU. Before starting the internal operation of
the LCD, control information is temporarily stored into these registers
to allow interfacing with various MCUs, which operate at different
speeds, or various peripheral control devices. The internal operation of
the LCD is determined by signals sent from the MCU. These signals,
which include register selection signal (RS), read/write signal (R/W),
and the data bus (DB0 to DB7), make up the LCD instructions (Table
3). There are four categories of instructions that:

• Designate LCD functions, such as display format, data length,


etc.
• Set internal RAM addresses
• Perform data transfer with internal RAM
• Perform miscellaneous functions
Table 3: Command and Instruction set for LCD type HD44780

Although looking at the table you can make your own commands and
test them. Below is a breif list of useful commands which are used
frequently while working on the LCD.

No. Instruction Hex Decimal


1 Function Set: 8-bit, 1 Line, 5x7 Dots 0x30 48
2 Function Set: 8-bit, 2 Line, 5x7 Dots 0x38 56
3 Function Set: 4-bit, 1 Line, 5x7 Dots 0x20 32
4 Function Set: 4-bit, 2 Line, 5x7 Dots 0x28 40
5 Entry Mode 0x06 6
Display off Cursor off
6 0x08 8
(clearing display without clearing DDRAM content)
7 Display on Cursor on 0x0E 14
8 Display on Cursor off 0x0C 12
9 Display on Cursor blinking 0x0F 15
10 Shift entire display left 0x18 24
12 Shift entire display right 0x1C 30
13 Move cursor left by one character 0x10 16
14 Move cursor right by one character 0x14 20
15 Clear Display (also clear DDRAM content) 0x01 1
16 Set DDRAM address or coursor position on display 0x80+add* 128+add*
17 Set CGRAM address or set pointer to CGRAM location 0x40+add** 64+add**
Table 4: Frequently used commands and instructions for LCD

* DDRAM address given in LCD basics section see Figure 2,3,4


** CGRAM address from 0x00 to 0x3F, 0x00 to 0x07 for char1 and so
on..

The table above will help you while writing programs for LCD. But after
you are done testing with the table 4, i recommend you to use table 3
to get more grip on working with LCD and trying your own commands.
In the next section of the tutorial we will see the initialization with
some of the coding examples in C as well as assembly.

Sending Commands to LCD

To send commands we simply need to select the command register.


Everything is same as we have done in the initialization routine. But we
will summarize the common steps and put them in a single subroutine.
Following are the steps:

• Move data to LCD port


• select command register
• select write operation
• send enable signal
• wait for LCD to process the command

Keeping these steps in mind we can write LCD command routine as.

CODE:
;Ports used are same as the previous example
;Routine to send command to LCD

LCD_command:
mov LCD_data,A ;Move the command to LCD port
clr LCD_rs ;Selected command register
clr LCD_rw ;We are writing in instruction register
setb LCD_en ;Enable H->L
clr LCD_en
acall LCD_busy ;Wait for LCD to process the command
ret ;Return from busy routine

; Usage of the above routine


; A will carry the command for LCD
; e.g. we want to send clear LCD command
;
; mov a,#01H ;01H is command for clearing LCD
; acall LCD_command ;Send the command

The equivalent C code Keil C compiler. Similar code can be written for SDCC.

CODE:
void LCD_command(unsigned char var)
{
LCD_data = var; //Function set: 2 Line, 8-bit, 5x7 dots
LCD_rs = 0; //Selected command register
LCD_rw = 0; //We are writing in instruction register
LCD_en = 1; //Enable H->L
LCD_en = 0;
LCD_busy(); //Wait for LCD to process the command
}
// Using the above function is really simple
// var will carry the command for LCD
// e.g.
//
// LCD_command(0x01);

Setting cursor position on LCD


To set the cursor position on LCD, we need to send the DDRAM
address...
CODE:
Bit7 6 5 4 3 2 1 0
1 AD6 AD5 AD4 AD3 AD2 AD1 AD0

The seventh bit is always 1, and bit 0 to 7 are DDRAM address (See the
introduction section of LCD). so if you want to put the cursor on first
position the address will be '0000000B' in binary and 7th bit is 1. so
address will be 0x80, so for DDRAM all address starts from 0x80.

For 2 line and 16 character LCD. The adress from 0x80 to 0x8F are
visible on first line and 0xC0 to 0xCF is visible on second line, rest of
the DDRAM area is still available but is not visible on the LCD, if you
want to check this thing, then simply put a long sting greater than 16
character and shift the entire display, you will see all the missing
character coming from the back.. this way you can make scrolling line
on LCD (see more on shifting display in commands section).
Below is an example for setting cursor position on LCD.

CODE:
;We are placing the cursor on the 4th position
;so the DDRAM address will be 0x03
;and the command will be 0x80+0x03 = 0x83
mov a,#83H ;load the command
acall LCD_command ;send command to LCD

CODE:
// to do the same thing is C
// as we done before
LCD_command(0x83);

►Sending Data to LCD

To send data we simply need to select the data register. Everything is


same as the command routine. Following are the steps:

• Move data to LCD port


• select data register
• select write operation
• send enable signal
• wait for LCD to process the data

Keeping these steps in mind we can write LCD command routine as.

CODE:
;Ports used are same as the previous example
;Routine to send data (single character) to LCD

LCD_senddata:
mov LCD_data,A ;Move the command to LCD port
setb LCD_rs ;Selected data register
clr LCD_rw ;We are writing
setb LCD_en ;Enable H->L
clr LCD_en
acall LCD_busy ;Wait for LCD to process the data
ret ;Return from busy routine

; Usage of the above routine


; A will carry the character to display on LCD
; e.g. we want to print A on LCD
;
; mov a,#'A' ;Ascii value of 'A' will be loaded in
accumulator
; acall LCD_senddata ;Send data
The equivalent C code Keil C compiler. Similar code can be written for
SDCC.

CODE:
void LCD_senddata(unsigned char var)
{
LCD_data = var; //Function set: 2 Line, 8-bit, 5x7 dots
LCD_rs = 1; //Selected data register
LCD_rw = 0; //We are writing
LCD_en = 1; //Enable H->L
LCD_en = 0;
LCD_busy(); //Wait for LCD to process the command
}
// Using the above function is really simple
// we will pass the character to display as argument to function
// e.g.
//
// LCD_senddata('A');

Now you have seen that its really easy to send command and data to
LCD. Now what if we have a string to send to LCD? how we are going to
do that?

Is simple, we will store the LCD string in the ROM of controller and call
the string character by character. A simple exmple is shown below.

CODE:
;Sending string to LCD Example

LCD_sendstring:
clr a ;clear Accumulator for any previous
data
movc a,@a+dptr ;load the first character in
accumulator
jz exit ;go to exit if zero
acall lcd_senddata ;send first char
inc dptr ;increment data pointer
sjmp LCD_sendstring ;jump back to send the next character
exit:
ret ;End of routine

; Usage of the above routine


; DPTR(data pointer) will carry the address
; of string to send to LCD.
; e.g. we want to print "LCD Tutorial" on LCD then
;
; mov dptr,#my_string ;my_string is the label where the string is
stored
; acall LCD_sendstring ;Send string
;
; To store a string..
; my_string:
; DB "LCD Tutorial", 00H
; 00H indicate that string is finished.

The equivalent C code Keil C compiler. Similar code can be


written for SDCC.

CODE:
void LCD_sendstring(unsigned char *var)
{
while(*var) //till string ends
LCD_senddata(*var++); //send characters one by one
}
// Using the above function is really simple
// we will pass the string directly to the function
// e.g.
//
// LCD_sendstring("LCD Tutorial");

Now we are ready with sending data and sending command to LCD.
Now the last and final section which is creating custom characters or
patterns to display on LCD. Please proceed to the next section to read
more.

4-bit Initialization

Initialization of LCD is completed only after the reset sequence and


basic initialization commands. We have already discussed about the
reset sequence of the lcd in the previous section. So lets look at the
programming now...

►Assembly Program

CODE:
;In this whole 4-bit tutorial LCD is connected to
;my controller in following way...
;D4 - P3.0
;D5 - P3.1
;D6 - P3.2
;D7 - P3.3
;EN - P3.7
;RS - P3.5

lcd_port equ P3 ;LCD connected to Port3


en equ P3.7 ;Enable connected to P3.7
rs equ P3.5 ;Register select to P3.5

lcd_reset: ;LCD reset sequence


mov lcd_port, #0FFH
mov delay,#20 ;20mS delay
acall delayms
mov lcd_port, #83H ;Data = 30H, EN = 1, First Init
mov lcd_port, #03H ;Data = 30H, EN = 0
mov delay,#15 ;Delay 15mS
acall delayms
mov lcd_port, #83H ;Second Init, Data = 30H, EN = 1
mov lcd_port, #03H ;Data = 30H, EN = 0
mov delay,#5 ;Delay 5mS
acall delayms
mov lcd_port, #83H ;Third Init
mov lcd_port, #03H
mov delay,#5 ;Delay 5mS
acall delayms
mov lcd_port, #82H ;Select Data width (20H for 4bit)
mov lcd_port, #02H ;Data = 20H, EN = 0
mov delay,#5 ;Delay 5mS
acall delayms
ret

lcd_init:
acall lcd_reset ;Call LCD Reset sequence
mov a,#28H ;4-bit, 2 line, 5x7 dots
acall lcd_cmd ;Call LCD command
mov a,#0CH ;Display ON cursor OFF
acall lcd_cmd ;Call LCD command
mov a,#06H ;Set entry mode (Auto increment)
acall lcd_cmd ;Call LCD command
mov a,#80H ;Bring cursor to line 1
acall lcd_cmd ;Call LCD command
ret

►C Program

CODE:
//The pins used are same as explained earlier
#define lcd_port P3

//LCD Registers addresses


#define LCD_EN 0x80
#define LCD_RS 0x20

void lcd_reset()
{
lcd_port = 0xFF;
delayms(20);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(10);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(1);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(1);
lcd_port = 0x02+LCD_EN;
lcd_port = 0x02;
delayms(1);
}

void lcd_init ()
{
lcd_reset(); // Call LCD reset
lcd_cmd(0x28); // 4-bit mode - 2 line - 5x7 font.
lcd_cmd(0x0C); // Display no cursor - no blink.
lcd_cmd(0x06); // Automatic Increment - No Display shift.
lcd_cmd(0x80); // Address DDRAM with 0 offset 80h.
}

►Sending Dommand/Data to LCD in 4-bit mode


►Assembly Program

CODE:
lcd_cmd: ;LCD command Routine
mov temp,a ;Save a copy of command to temp
swap a ;Swap to use higher nibble
anl a,#0FH ;Mask the first four bits
add a,#80H ;Enable = 1, RS = 0
mov lcd_port,a ;Move it to lcd port
anl a,#0FH ;Enable = 0, RS = 0
mov lcd_port,a ;Move to lcd port

mov a,temp ;Reload the command from temp


anl a,#0FH ;Mask first four bits
add a,#80H ;Enable = 1
mov lcd_port,a ;Move to port
anl a,#0FH ;Enable = 0
mov lcd_port,a ;Move to lcd port

mov delay,#1 ;delay 1 ms


acall delayms
ret

lcd_dat: ;LCD data Routine


mov temp,a ;Keep copy of data in temp
swap a ;We need higher nibble
anl a,#0FH ;Mask first four bits
add a,#0A0H ;Enable = 1, RS = 1
mov lcd_port,a ;Move to lcd port
nop
clr en ;Enable = 0

mov a,temp ;Reload the data from temp


anl a,#0FH ;we need lower nibble now
add a,#0A0H ;Enable = 1, RS = 1
mov lcd_port,a ;Move to lcd port
nop
clr en ;Enable = 0

mov delay,#1 ;Delay 1mS


acall delayms
ret

►C Program
CODE:
void lcd_cmd (char cmd)
{
lcd_port = ((cmd >> 4) & 0x0F)|LCD_EN;
lcd_port = ((cmd >> 4) & 0x0F);

lcd_port = (cmd & 0x0F)|LCD_EN;


lcd_port = (cmd & 0x0F);

delayus(200);
delayus(200);
}

void lcd_data (unsigned char dat)


{
lcd_port = (((dat >> 4) & 0x0F)|LCD_EN|LCD_RS);
lcd_port = (((dat >> 4) & 0x0F)|LCD_RS);

lcd_port = ((dat & 0x0F)|LCD_EN|LCD_RS);


lcd_port = ((dat & 0x0F)|LCD_RS);

delayus(200);
delayus(200);

Basic Circuit for 8051

8051 PIN OUT

 Power - Vcc, Vss

Reset - RST

Crystal - XTAL[1,2]

External device interfacing


– EA, ALE, PSEN, WR, RD

 I/O Port
– P0[7;0], P1[7:0], P2[7:0], P3

P3 is shared with control lines


– Serial I/O RxD, TxD,
– external interrupts INT0, INT1
– Counter control T0, T1

P0 and P2 are multiplexed with Address and Data bus


BASIC CIRCUIT -THAT MAKES 8051 WORKS.

EA/VP Pin
The EA on pin 31 is tied high to make the 8051 executes program from Internal ROM

Reset Circuit
RESET is an active High input When RESET is set to High, 8051 goes back to the power on
state.
The 8051 is reset by holding the RST high for at least two machine cycles and then returning it
low.

Power-On Reset

- Initially charging of capacitor makes RST High


- When capacitor charges fully it blocks DC.

Manual reset
-closing the switch momentarily will make RST High.

After a reset, the program counter is loaded with 0000H but the content of on-chip RAM is not affected.

Register Content Register Content


Program
0000h IP XXX00000b
counter
Accumulator 00h IEv 0XX00000b
All timer
B register 00h 00h
registers
PSW 00h SCON 00h
SP 07h SBUF 00h
PCON
DPTR 0000h 0XXXXXXXbv
(HMOS)
PCON
All ports FFh 0XXX0000b Note: content of on-
(CMOS)v
chip RAM is not
affected by Reset.

Oscillator Circuit

The 8051 uses the crystal for precisely that: to synchronize it’s operation. Effectively, the 8051
operates using what are called "machine cycles." A single machine cycle is the minimum amount
of time in which a single 8051 instruction can be executed. although many instructions take
multiple cycles.

8051 has an on-chip oscillator. It needs an external crystal thats decides the operating
frequency of the 8051.

This can be achieved in two ways,,

The crystal is connected to pins 18 and 19 with stabilizing capacitors. 12 MHz


(11.059MHz) crystal is often used and the capacitance ranges from 20pF to 40pF.

The oscillator can also be a TTL clock source connected with a NOT gate as shown

How fast 8051 works ?

A cycle is, in reality, 12 pulses of the crystal. That is to say, if an instruction takes one machine
cycle to execute, it will take 12 pulses of the crystal to execute. Since we know the crystal is
pulsing 11,059,000 times per second and that one machine cycle is 12 pulses, we can calculate
how many instruction cycles the 8051 can execute per second:

11,059,000 / 12 = 921,583
Why is such an oddball crystal frequency?

11.0592 MHz crystals are often used because it can be divided to give you exact clock rates for
most of the common baud rates for the UART, especially for the higher speeds (9600, 19200). Despite the "oddball"
value, these crystals are readily available and commonly used.

Power Supply

C1-1000 mf ,C2-
100 mf

The 78L05 is a 5V
regulator. The input
voltage ranges
from 7V to 35V and the output voltage is about 5V.

Using Ports for I/O Operation

8051 is TTL logic device. TTL logic has two levels: Logic "High" (1) and logic "Low" (0). The voltage and current involved for the
two levels are as follows:

Leve Voltag
Current
l e
High Above Virtually no current flow
2.4V
1.6mA Sinking current
Below
Low from TTL input to ground
0.9V
(Depends on logic family)

Port functions

Ports
Function

Port Dual-purpose port- 1. general purpose I/O Port.


0 2. multiplexed address & data bus
Open drain outputs
(Pin
32-
39)
Port
1

(Pin Dedicated I/O port – Used solely for interfacing to external devices
1-8) Internal pull-ups

Port
2

(Pin Dual-purpose port- 1. general purpose I/O port.


21- 2. a multiplexed address & data bus.
28) Internal pull-ups

Port
3
Dual-purpose port- 1. general purpose I/O port.
2. pins have alternate purpose related to special features of the 8051
(Pin Internal pull-ups
10-
17)

The 8051 internal ports are partly bi-directional (Quasi-bi-directional). The following is the internal circuitry for the 8051 port
pins:

1.Configuring for output

P0 is open drain.
– Has to be pulled high by external 10K resistors.
– Not needed if P0 is used for address lines

Writing to a port pin loads data into a port latch that drives a FET connected to the port pin.

P0: Note that the pull-up is absent on Port 0 except when functioning as the external
address/data bus. When a "0" is written to a bit in port 0, the pin is pulled low. But when a "1"
is written to it, it is in high impedance (disconnected) state. So when using port 0 for output, an
external pull-up resistor is needed, depending on the input characteristics of the device driven
by the port pin

P1, P2, P3 have internal pull-ups: When a "0" is written to a bit in these port , the pin is
pulled low ( FET-ON) ,also when 1 is written to a bit in these port pin becomes high (FET-OFF)
thus using port P1,P2,P3 is simple.

2. Configuring for input

At power-on all are output ports by default


To configure any port for input, write all 1’s (0xFF) to the port
Latch bit=1, FET=OFF, Read Pin asserted by read instruction

You can used a port for output any time. But for input, the FET must be off. Otherwise, you will
be reading your own latch rather than the signal coming from the outside. Therefore, a "1"
should be written to the pin if you want to use it as input, especially when you have used it for
output before. If you don't do this input high voltage will get grounded through FET so you will
read pin as low and not as high. An external device cannot easily drive it high

so, you should not tide a port high directly without any resistor. Otherwise, the FET would burn.

Be Careful :

Some port pins serve multiple functions. Be careful writing to such ports. For example, P3.0 is
the UART RXD (serial input), and P3.1 is the UART TXD (serial output). If you set P3.0 to a '0',
an external buffer (such as an RS232 level translator) cannot drive it high. Therefore you have
prevented receiving any serial input.

If an external interrupt such as EX1 on P3.3 is enabled, and set to be level sensitive, and you
clear this pin's output latch to a zero, guess what? You've just caused a perpetual interrupt 1.
The pin's input buffer will read the output of it's latch as always low. Your controller will spend
all of its time in the interrupt handler code and will appear to have crashed, since it will have
very little time for other tasks. In fact, it will get to execute a single instruction before re-
entering the interrupt handler, so the rest of your program will execute very, very slowly.
Program code

// Program to make a digital clock using LCD

#include<reg51.h>

#define cont_port P3

#define port P1

#define dataport P2 // Data port for LCD

#define m_sec 10

sbit rs = cont_port^0;

sbit rw = cont_port^1;

sbit en = cont_port^6;

sbit dig_hr1=port^0;

sbit dig_min1=port^1;

sbit start=port^2;

sbit am_pm=port^3;

int hr ,hr1=0;

int min,min1=0;

int sec,sec1=0,dig_am_pm=0;

void delay(unsigned int msec) // Time delay funtion

int i,j ;

for(i=0;i<msec;i++)

for(j=0;j<1275;j++);

}
void lcd_cmd(unsigned char item) // Function to send command on LCD

dataport = item;

rs= 0;

rw=0;

en=1;

delay(1);

en=0;

return;

void lcd_data(unsigned char item) // Function to send data on LCD

dataport = item;

rs= 1;

rw=0;

en=1;

delay(1);

en=0;

return;

void lcd_data_string(unsigned char *str) // Function to send string on LCD

int i=0;

while(str[i]!='\0')

lcd_data(str[i]);

i++;

delay(1);

return;

}
lcd_data_int(int time_val) // Function to send number on LCD

int int_amt;

int_amt=time_val/10;

lcd_data(int_amt+48);

int_amt=time_val%10;

lcd_data(int_amt+48);

void lcd(unsigned char str1[10]) // Function to initialize LCD

lcd_cmd(0x38); //2 LINE, 5X7 MATRIX

lcd_cmd(0x0e); //DISPLAY ON, CURSOR BLINKING

delay(m_sec);

lcd_data_string(str1);

void set_hr1() // Function to set hour

hr1++;

if(hr1>11)

hr1=0;

lcd_cmd(0xc3);

lcd_data_int(hr1);

lcd_data(':');

void set_min1() // Function to set minute

min1++;

if(min1>59)

min1=0;
lcd_cmd(0xc6);

lcd_data_int(min1);

void main()

int k;

start=1;

dig_hr1=1;

dig_min1=1;

lcd_cmd(0x01);

lcd_cmd(0x83);

lcd("SET TIMING");

lcd_cmd(0xc3);

lcd_data_int(hr1);

lcd_data(':');

lcd_data_int(min1);

while(start==0)

delay(10);

if(dig_hr1==0)

set_hr1();

if(dig_min1==0)

set_min1();

if(am_pm==0)

lcd_cmd(0xc8);

lcd_data_string("am");

dig_am_pm=0;

}
if(am_pm==1)

lcd_cmd(0xc8);

lcd_data_string("pm");

dig_am_pm=1;

delay(200);

lcd_cmd(0x01);

while(1)

for(k=0;k<2;k++)

for(hr=hr1;hr<12;hr++)

for(min=min1;min<60;min++)

for(sec=0;sec<60;sec++)

lcd_cmd(0x82);

delay(1);

lcd_data_int(hr);

lcd_data(':');

lcd_data_int(min);

lcd_data(':');

lcd_data_int(sec);

if(dig_am_pm==0)

lcd("am");

else

lcd("pm");

}
lcd_data_string(" ");

delay(100);

min1=0;

if(dig_am_pm==0)

dig_am_pm=1;

else

dig_am_pm=0;

hr1=0;

Overview to Keil compiler

Keil development tools for the 8051 Microcontroller Architecture


support every level of software developer from the professional applications engineer
to the student just learning about embedded software development.

The industry-standard Keil C Compilers, Macro Assemblers, Debuggers, Real-time


Kernels, Single-board Computers, and Emulators support all 8051 derivatives and
help you get your projects completed on schedule.

Tool Overview
The Keil 8051 Development Tools are designed to solve the complex problems facing
embedded software developers.
 When starting a new project, simply select the microcontroller you use from
the Device Database and the µVision IDE sets all compiler, assembler, linker,
and memory options for you.
 Numerous example programs are included to help you get started with the
most popular embedded 8051 devices.
 The Keil µVision Debugger accurately simulates on-chip peripherals (I²C,
CAN, UART, SPI, Interrupts, I/O Ports, A/D Converter, D/A Converter, and PWM
Modules) of your 8051 device. Simulation helps you understand hardware
configurations and avoids time wasted on setup problems. Additionally, with
simulation, you can write and test applications before target hardware is
available.
 When you are ready to begin testing your software application with target
hardware, use the MON51, MON390, MONADI, or FlashMON51 Target Monitors,
the ISD51 In-System Debugger, or the ULINK USB-JTAG Adapter to download
and test program code on your target system

Interfacing to 8051 I/O ports.

SWITCH ON I/O PORTS

Good Circuit
It is always best connecting the switch to ground with a pull-up resistor as shown in the
"Good" circuit. When the switch is open, the 10k resistor supplies very small current needed
for logic 1. When it is closed, the port pin is short to ground. The voltage is 0V and all the
sinking current requirement is met, so it is logic 0. The 10k resistor will pass 0.5 mA (5
Volt/10k ohm). Thus the circuits waste very little current in either state. The drawback is that
the closure of switch gives logic 0 and people like to think of a switch closure gives logic 1. But
this is not a matter because it is easy to handle in software.

Fair circuit
The "Fair" circuit requires that the pull-down resistor be very small. Otherwise, the pin will rise
above 0.9V when the resistor passes the 1.6mA sinking current. When the switch is closed,
the circuit waste a large current since virtually no current flows into the pin. The only
advantage is that a switch closure gives logic 1.

Poor circuit
In the "Poor" circuit, the logic 1 is stable when the switch is closed. But when the switch is
open, the input floats to a noise-sensitive high rather than a low. An open TTL pin is usually
read as logic 1 but the pin may picks up noise like an antenna.
To conclude, driving a TTL input should always consider current sinking (pulling input to 0V).

LED ON I/O PORTS

Since TTL outputs is designed to feed multiple TTL


inputs, they are good at current sinking but
poor at current sourcing. The Standard TTL can
sink up to 16mA and source 250uA. The LS logic
family can sink 8mA and source 100uA. The 8051
port pin can sink 1.6mA (3.2mA for port 0) and
source 60uA. Therefore, if you drive significant current, try to arrange your circuits to use
current sinking.

Unlike diodes, Light-emitting diodes have a forward voltage drop from 1.7 to 2.5 volts and
most of them flow a forward current 20mA.

Poor circuit
since the TTL output can't source above 1mA so the LED will be very dim.

Fair circuit
The LED will conduct heavily at about 2V and the extra 3V has to be dropped in the TTL
circuitry. This causes high power dissipation in the TTL or the LED fails.

Good circuit
The resistor limits the current. The resistance can be calculated by assuming its voltage is
about 2.5V and the TTL output is 0.9V. For 2.2V LED, 1.9V is across the resistor so the
220ohm would limit the current to 8.6mA (1.9/220). For 1.7V LED, 2.4V is across the resistor
so it would limit the current to 10.9mA (2.4/220). The resistor should not less than 100ohm or
the LED would fail.
CODE EXAMPLE
Connection -Switch -P1.0 , LED - P2.0
Condition - Turn on LED when switch is pressed.

ASSEMBLY LANGUAGE C LANGUAGE (SPJ )

B P1.0 ; input pin. BIT button p1.0 / * Using BIT keyword for p1.0 definition*/
OP: BIT LED p2.0
2.0, LOOP ; not grounded then stay in loop void main ( )
P0.0 ;To clear pin P0.0 when P1.0 is at 0 v
while (1) {
LED = button ; /* Note LED=button is wrong */

RELAY ON I/O PORT (2CO Relay)

In A, NPN transistor (say a BC337 or BC338) is being used to control a relay with a 5 V coil.
Series base resistor R1 is used to set the base current for Q1, so that the transistor is driven
into saturation (fully turned on) when the relay is to be energized. That way, the transistor will
have minimal voltage drop, and hence dissipate very little power as well as delivering most of
the 5V to the relay coil.

How do work out the value of R1?.

Let us say RLY1 needs 50mA of coil current to pull in and hold reliably, and has a resistance of
24 Ohms so it draws this current from 5V. Our BC337/338 transistor will need enough base
current to make sure it remains saturated at this collector current level. To work this out, we
simply make sure that the base current is greater than this collector current divided by the
transistors minimum DC current gain hFE. So as the BC337/338 has a minimum hFE of 100
(at 100mA), we'll need to provide it with at least 50mA/100 = 0.5mA of base current.
In practice, you give it roughly double this value, say 1mA of base current, just to make sure
it does saturate. So if your resistance will be
TTL Logic High Voltage (Min) /1ma ( 1K approx)

EXAMPLE

Connection -Port 0 is connected to eight LEDs, each of them is connected to 5V through a


330ohm resistor. Port 1 is connected to a DIP switch and a 10Kohm resistor

Condition - Corresponding led should light up when switch pressed , i.e. if Switch at 1.0 is
pressed -> LED at P0.0 should light up.
CODE EXAMPLE

ASSEMBLY LANGUAGE C LANGUAGE (SPJ SIDE51)

LOOP: . 1.
mov p1,#0ffh ; To configure port for input.
mov a,p1 void main() {
mov p0 ,a while (1) {
sjmp LOOP ; Stay in infinite loop P0 = P1; /* Note P1=P0 will not work
}
}

2.

voided main() {
char port_value;
while (1) {
port_value = P1;
P0 = port_value;
}
}

Circuit Schematic
1 THE CIRCUIT

The circuit to be simulated is shown here, consisting of a PIC 16F877


microcontroller unit (MCU), input push buttons and output LEDs which
will display a binary count. An external adjustable CR clock circuit is used.
The push buttons are not used in the simple program BIN1.

Make a folder to hold the project files called BIN1.

ISIS Screen
2 THE SCHEMATIC

The ISIS user interface is shown here, consisting of edit, overview and
object select windows, with edit toolbars. Components are added to the
object list from the libraries provided, dropped onto the schematic, and
connected up using virtual wiring. Components can be labelled and their
simulation properties modified.

Save the schematic as BIN1.DSN in the project folder.

Component selection dialogue


3 SELECT COMPONENTS

Components are found in the libraries accessed via the ‘pick’ button P in the
object select window. The MCU is selected from ‘Microprocessors ICs’
category, ‘PIC16 Family’ sub-category. The other components are added to
the pick list from the appropriate categories. These are then selected and
dropped on the schematic within the blue border.

Save the design file BIN1.DSN in the project folder.

Program Source Code


4 WRITE PROGRAM
PROCESSOR 16F877
The MCU needs a program to work as required. From the ‘Source’ menu,
select ‘add source file’, ‘new’ and open the source file BIN1.ASM in folder MOVLW 00
TRIS 06
BIN1. Select code generation tool MPASM. Open the source edit window
by selecting the new file from the source menu, and enter the source code CLRF 06
listed here. It is a minimal program which produces a binary count at Port B again INCF 06
GOTO again
(06).
END
Save the source file code file BIN1.ASM in the project folder.

Machine Code Program


5 ASSEMBLE PROGRAM

Save the source code when complete. From the Source menu, select Build
All. The message window should confirm build OK. If not, correct syntax :020000040000FA
errors in the source code by reference to PIC programming rules. A hex file :0A000000003066008601
is produced as shown, BIN1.HEX, which contains the MCU machine code. :00000001FF

The machine code program BIN1.HEX is stored automatically in the project


folder with the source code.

MCU properties dialogue


6 ATTACH PROGRAM

This hex file must be attached to the MCU in the schematic. Right click,
then left click on the PIC chip to open the Edit Component dialogue. Click
on the Program File folder tab and select the BIN1.HEX file from the
project folder. Set the Processor Clock Frequency to 40kHz. Note that the
external components do not affect the simulation clock frequency. The Port
B output LEDs should operate when the run/step/pause/stop controls are
clicked (the buttons on the schematic have no effect with this program).

Save the completed design file.

Source code debug window


7 TEST PROGRAM

Pause the program and from the Debug menu check the PIC CPU Source
Code option to display the program with the execution point highlighted.
Use the ‘Step Into’ button in the source code window to single step the
program. Note that the initialisation instructions are executed once, and the
loop then repeats endlessly – this is the usual program operating sequence
for control applications. The source code window has buttons to run, single
step (into, over and out of subroutines) and set breakpoints.

Correct any logical program errors detected.

Program debug windows


8 DEBUG PROGRAM

To monitor program progress, the MCU registers can be displayed, and


other changes monitored, using:

• • Special function register display


• • RAM register display
• • Register watch window
• • Execution clock
• • Simulation logs

The effect of the program on the registers and status flags, and program
timing can thus be checked.

Save the test window arrangement using ‘save preferences’.

ICD
module
9 DOWNLOAD PROGRAM

When all logical errors have been resolved, the program can be downloaded
to the real hardware using the programming tools in MPLAB, for example,
using the Mpstart programmer unit. Alternatively, the ICD system allows
in-circuit programming and debugging, requiring the purchase of the Embedded
System
MPLAB ICD2 module. Development System PIC MCU

See www.microchip.com
PC +
PROTEUS
+ MPLAB
REFRENCES
www.altavista.com
www.8051.net
www.8051.info
www.freewebs.com
www.innovationrnd.in
www.google.com
www.scribd.com
www.esnips.com

S-ar putea să vă placă și