You are on page 1of 16

Voltmeter using 8051.

A simple 0-5V voltmeter using 8051 is shown in this article. This digital voltmeter has a
sensitivity of 200mV which is a bit low but this project is meant for demonstrating how an
ADC and seven segment display can be interfaced to 8051 to obtain a digital readout of the
input voltage. A 31/2 digit high end voltmeter will be added soon. ADC0804 is the ADC and
AT89S51 is the controller used in this project. Before attempting this project, go through
these projects Interfacing ADC to 8051 and Interfacing seven segment display to
8051 which will give you a good idea on the basics.

Circuit diagram.

0-5 digital voltmeter using 8051

About the circuit.


In the circuit Vref/2 (pin9) of the ADC is left open and it means that the input voltage span
can be o to 5V and the step size will be 5/255 = 19.6mV. The equation for the digital output
of ADC0804 is Dout = Vin/Step size. In this circuit, for an input voltage of 1V the digital
output will be 1/19.6mV = 51 and so the binary equivalent of 51 ie 00110011. Digital output
of the ADC is interfaced to P1.0 of the microcontroller. Control signals for the ADC ie CS,
RD, WR and INTR are available from the P3.7, P3.6, P3.5 and P3.4 pins of the
microcontroller respectively. 2 digit multiplexed seven segment display is interfaced to
Port0 of the microcontroller. Control signals for the display driver transistors Q1 and Q2 are
obtained from P3.2 and P3.1 of the microcontroller. Push button switch S1, capacitor C2 and
resistor R10 forms a debouncing reset circuitry.

Program.
ORG

00H

MOV

P1,#11111111B

MOV

P0,#00000000B

MOV

P3,#00000000B

MOV

DPTR,#LABEL

MAIN:

CLR

P3.7

SETB

P3.6

CLR

P3.5

SETB

P3.5

WAIT:

JB

P3.4,WAIT

CLR

P3.7

CLR

P3.6

MOV

A,P1

MOV

B,#10D

DIV

AB

MOV

B,#2D

MUL

AB

MOV

B,#10D

DIV

AB

SETB

P3.2

ACALL

DISPLAY

MOV

P0,A

ACALL

DELAY

MOV

P0,#10000000B

ACALL

DELAY

MOV

A,B

CLR

P3.2

SETB

P3.1

ACALL

DISPLAY

MOV

P0,A

ACALL

DELAY

CLR

P3.1

SJMP

MAIN

DELAY:

MOV

R3,#02H

DEL1:

MOV

R2,#0FAH

DEL2:

DJNZ

R2,DEL2

DJNZ

R3,DEL1

RET
DISPLAY:
RET

MOVC

A,@A+DPTR

LABEL:

DB

3FH

DB

06H

DB

5BH

DB

4FH

DB

66H

DB

6DH

DB

7DH

DB

07H

DB

7FH

DB

6FH

END

About the program.


At first the program controls the ADC to produce a digital output corresponding to the input
voltage.This digital output is scanned through P1.0 and is loaded to accumulator. Then the
value in the accumulator is divided by 10 to omit the last digit. For example, let the input
voltage be 4V. Then the corresponding digital output of the ADC will be 204D (D stands for
decimal) .After the the division by 10, the value left in the accumulator will be 20D. This
20D is then multiplied by 2D which results in 40D. The next target of the program is to
manipulate this 40D and make a 4.0 readout on the display. For this the 40D is again
divided by 10D . This results in 4 inside accumulator and 0 inside B register. Then the
program gets the digit drive pattern for 4 using the lookup table , puts this pattern on Port 0
and activates Q1. After 1 ms delay 10000000B is loaded to P0 and this accounts for the dot.
After a further 1ms delay Q1 is deactivated, content in B (ie 0) is moved to A, gets the correct
digit drive pattern for 0 using the lookup table, puts this pattern on Port 0 and activates Q2.
After a further 1ms delay Q2 is deactivated and the entire cycle is repeated.

Interfacing ADC to 8051


ADMIN
SEPTEMBER - 6 - 2012
4 COMMENTS

ADC (Analog to digital converter) forms a very essential part in many embedded projects
and this article is about interfacing an ADC to 8051 embedded controller. ADC 0804 is the
ADC used here and before going through the interfacing procedure, we must neatly
understand how the ADC 0804 works.

ADC 0804.
ADC0804 is an 8 bit successive approximation analogue to digital converter from National
semiconductors. The features of ADC0804 are differential analogue voltage inputs, 0-5V
input voltage range, no zero adjustment, built in clock generator, reference voltage can be
externally adjusted to convert smaller analogue voltage span to 8 bit resolution etc. The pin
out diagram of ADC0804 is shown in the figure below.

ADC0804 pinout

The voltage at Vref/2 (pin9) of ADC0804 can be externally adjusted to convert smaller
input voltage spans to full 8 bit resolution. Vref/2 (pin9) left open means input voltage span
is 0-5V and step size is 5/255=19.6V. Have a look at the table below for different Vref/2
voltages and corresponding analogue input voltage spans.

Vref/2 (pin9) (volts)

Input voltage span (volts)

Step size (mV)

Left open

05

5/255 = 19.6

04

4/255 = 15.69

1.5

03

3/255 = 11.76

1.28

0 2.56

2.56/255 = 10.04

1.0

02

2/255 = 7.84

0.5

01

1/255 = 3.92

Steps for converting the analogue input


ADC0804.

and reading the output from

Make CS=0 and send a low to high pulse to WR pin to start the conversion.
Now keep checking the INTR pin. INTR will be 1 if conversion is not finished and

INTR will be 0 if conversion is finished.


If conversion is not finished (INTR=1) , poll until it is finished.
If conversion is finished (INTR=0), go to the next step.
Make CS=0 and send a high to low pulse to RD pin to read the data from the ADC.

Circuit diagram.

Interfacing ADC to 8051

The figure above shows the schematic for interfacing ADC0804 to 8051. The circuit initiates
the ADC to convert a given analogue input , then accepts the corresponding digital data and
displays it on the LED array connected at P0. For example, if the analogue input voltage Vin
is 5V then all LEDs will glow indicating 11111111 in binary which is the equivalent of 255 in
decimal. AT89s51 is the microcontroller used here. Data out pins (D0 to D7) of the
ADC0804 are connected to the port pins P1.0 to P1.7 respectively. LEDs D1 to D8 are
connected to the port pins P0.0 to P0.7 respectively. Resistors R1 to R8 are current limiting
resistors. In simple words P1 of the microcontroller is the input port and P0 is the output
port. Control signals for the ADC (INTR, WR, RD and CS) are available at port pins P3.4 to
P3.7 respectively. Resistor R9 and capacitor C1 are associated with the internal clock
circuitry of the ADC. Preset resistor R10 forms a voltage divider which can be used to apply
a particular input analogue voltage to the ADC. Push button S1, resistor R11 and capacitor
C4 forms a debouncing reset mechanism. Crystal X1 and capacitors C2,C3 are associated
with the clock circuitry of the microcontroller.

Program.
ORG 00H

MOV P1,#11111111B // initiates P1 as the input port


MAIN: CLR P3.7 // makes CS=0
SETB P3.6 // makes RD high
CLR P3.5 // makes WR low
SETB P3.5 // low to high pulse to WR for starting conversion
WAIT: JB P3.4,WAIT // polls until INTR=0
CLR P3.7 // ensures CS=0
CLR P3.6 // high to low pulse to RD for reading the data from ADC
MOV A,P1 // moves the digital data to accumulator
CPL A // complements the digital data (*see the notes)
MOV P0,A // outputs the data to P0 for the LEDs
SJMP MAIN // jumps back to the MAIN program
END

Notes.
The entire circuit can be powered from 5V DC.
ADC 0804 has active low outputs and the instruction CPL A complements it t0 have

a straight forward display. For example, if input is 5V then the output will be 11111111
and if CPL A was not used it would have been 00000000 which is rather awkward to
see.

Interfacing Seven segment display to 8051


ADMIN
JUNE - 20 - 2012
34 COMMENTS

A Note about 7 segment LED display.

This article is about how to interface a seven segment LED display to an 8051
microcontroller. 7 segment LED display is very popular and it can display digits from 0 to 9
and quite a few characters like A, b, C, ., H, E, e, F, n, o,t,u,y, etc. Knowledge about how to
interface a seven segment display to a micro controller is very essential in designing
embedded systems. A seven segment display consists of seven LEDs arranged in the form of
a squarish 8 slightly inclined to the right and a single LED as the dot character. Different
characters can be displayed by selectively glowing the required LED segments. Seven
segment displays are of two types,common cathode and common anode. In common
cathode type , the cathode of all LEDs are tied together to a single terminal which is usually
labeled as com and the anode of all LEDs are left alone as individual pins labeled as a, b,
c, d, e, f, g & h (or dot) . In common anode type, the anode of all LEDs are tied together as a
single terminal and cathodes are left alone as individual pins. The pin out scheme and
picture of a typical 7 segment LED display is shown in the image below.

7 segment LED display

Digit drive pattern.


Digit drive pattern of a seven segment LED display is simply the different logic
combinations of its terminalsa to h in order to display different digits and characters.
The common digit drive patterns (0 to 9) of a seven segment display are shown in the table
below.
Digit

Interfacing seven segment display to 8051.

Interfacing 7 segment display to 8051

The circuit diagram shown above is of an AT89S51 microcontroller based 0 to 9 counter


which has a 7 segment LED display interfaced to it in order to display the count. This
simple circuit illustrates two things. How to setup simple 0 to 9 up counter using 8051 and
more importantly how to interface a seven segment LED display to 8051 in order to display
a particular result. The common cathode seven segment display D1 is connected to the Port
1 of the microcontroller (AT89S51) as shown in the circuit diagram. R3 to R10 are current
limiting resistors. S3 is the reset switch and R2,C3 forms a debouncing circuitry. C1, C2 and
X1 are related to the clock circuit. The software part of the project has to do the following
tasks.

Form a 0 to 9 counter with a predetermined delay (around 1/2 second here).

Convert the current count into digit drive pattern.


Put the current digit drive pattern into a port for displaying.

All the above said tasks are accomplished by the program given below.

Program.
ORG

000H

START:

MOV

//initial

A,#00001001B

starting

//

initial

value

address
of

accumulator

MOV

B,A

MOV R0,#0AH //Register R0 initialized as counter which counts from 10 to 0


LABEL:

MOV

A,B

INC

MOV

B,A

MOVC

A,@A+PC

//

adds

the

byte

in

to

the

program

counters

address

MOV

P1,A

ACALL

DELAY

DEC
MOV

//

calls

R0//Counter
A,R0

//

R0

moved

the

delay

R0
to

of

decremented

accumulator

to

check

if

it

is

the

timer

by

zero

in

next

instruction.
JZ START //Checks accumulator for zero and jumps to START. Done to check if
counting

has

been

finished.

SJMP

LABEL

DB

3FH

//

digit

drive

pattern

for

DB

06H

//

digit

drive

pattern

for

DB

5BH

//

digit

drive

pattern

for

DB

4FH

//

digit

drive

pattern

for

DB

66H

//

digit

drive

pattern

for

DB

6DH

//

digit

drive

pattern

for

DB

7DH

//

digit

drive

pattern

for

DB

07H

//

digit

drive

pattern

for

DB

7FH

//

digit

drive

pattern

for

DB

6FH

//

digit

drive

pattern

for

DELAY:

MOV

R4,#05H

//

subroutine

for

delay

WAIT1:

MOV

R3,#00H

WAIT2:

MOV

R2,#00H

WAIT3:

DJNZ

R2,WAIT3

DJNZ

R3,WAIT2

DJNZ

R4,WAIT1

RET
END

About the program.


Instruction MOVC A,@A+PC is the instruction that produces the required digit drive
pattern for the display. Execution of this instruction will add the value in the accumulator A
with the content of the program counter(address of the next instruction) and will move the
data present in the resultant address to A. After this the program resumes from the line
after MOVC A,@A+PC.
In the program, initial value in A is 00001001B. Execution of MOVC A,@A+PC will add
oooo1001B to the content in PC ( address of next instruction). The result will be the
address of label DB 3FH (line15) and the data present in this address ie 3FH (digit drive
pattern for 0) gets moved into the accumulator. Moving this pattern in the accumulator to
Port 1 will display 0 which is the first count.
At the next count, value in A will advance to 00001010 and after the execution of MOVC
A,@+PC ,the value in A will be 06H which is the digit drive pattern for 1 and this will
display 1 which is the next count and this cycle gets repeated for subsequent counts.
The reason why accumulator is loaded with 00001001B (9 in decimal) initially is that the
instructions from line 9 to line 15 consumes 9 bytes in total.
The lines 15 to 24 in the program which starts with label DB can be called as a Look Up
Table (LUT). label DB is known as Define Byte which defines a byte. This table defines
the digit drive patterns for 7 segment display as bytes (in hex format). MOVC operator
fetches the byte from this table based on the result of adding PC and contents in the
accumulator.
Register B is used as a temporary storage of the initial value of the accumulator and the
subsequent increments made to accumulator to fetch each digit drive pattern one by one
from the look up table(LUT).
Note:- In line 6, Accumulator is incremented by 1 each time (each loop iteration) to select
the next digit drive pattern. Since MOVC operator uses the value in A to fetch the digit drive
pattern from LUT, value in ACC has to be incremented/manipulated accordingly. The digit
drive patterns are arranged consecutively in LUT.

Register R0 is used as a counter which counts from 10 down to 0. This ensures that digits
from o to 9 are continuously displayed in the 7 segment LED. You may note lines 4, 11, 12,
and 13 in the above program. Line 4 initializes R0 to 10 (OAh). When the program counter
reaches line 11 for the first time, 7 segment LED has already displayed 0. So we can reduce
one count and that is why we have written DEC Ro. We need to continuously check if R0 has
reached full count (that is 0). In order to do that lines 12 and 13 are used. We move R0 to
accumulator and then use the Jump if Zero (JZ) instruction to check if accumulator has
reached zero. If Acc=0, then we makes the program to jump to START (initial state) and
hence we restart the 7 segment LED to display from 0 to 9 again. If Acc not equal to zero, we
continue the program to display the next digit (check line 14).

Multiplexing 7 segment display to 8051.


Suppose you need a three digit display connected to the 8051. Each 7 segment display have
8 pins and so a total amount of 24 pins are to the connected to the microcontroller and there
will be only 8 pins left with the microcontroller for other input output applications. Also the
maximum number of displays that can be connected to the 8051 is limited to 4 because 8051
has only 4 ports. More over three 3 displays will be ON always and this consumes a
considerable amount of power. All these problems associated with the straight forward
method can be solved by multiplexing .
In multiplexing all displays are connected in parallel to one port and only one display is
allowed to turn ON at a time, for a short period. This cycle is repeated for at a fast rate and
due to the persistence of vision of human eye, all digits seems to glow. The main advantages
of this method are

Fewer number of port pins are required .


Consumes less power.
More number of display units can be interfaced (maximum 24).

The circuit diagram for multiplexing 2 seven segment displays to the 8051 is shown below.

Multiplexing 7 segement display to 8051

When assembled and powered on, the circuit will display the number 16 and let us see how
it is done. Initially the first display is activated by making P3.0 high and then digit drive
pattern for 1 is loaded to the Port 1. This will make the first display to show 1. In the
mean time P3.1 will be low and so do the second display will be OFF. This condition is
maintained for around 1ms and then P3.0 is made low. Now both displays will be OFF. Then
the second display is activated by making P3.1 high and then the digit drive pattern for 6
is loaded to the port 1. This will make the second display to show 6. In the mean time P3.0
will be low and so the second display will be OFF. This condition is maintained for another
1ms and then port 3.1 is made low. This cycle is repeated and due to the persistence of vision
you will feel it as 16.
Transistor Q1 drives the first display (D1) and transistor Q2 drives the second display (D2).
R11 and R12 are the base current limiting resistors of Q1 and Q2. The purpose of other
components are explained in the first circuit.

Program.
ORG

000H

//

MOV

P1,#00000000B

initial
//

starting
clears

address
port

MOV

R6,#1H

//

stores

"1"

MOV

R7,#6H

//

stores

"6"

MOV
MOV

P3,#00000000B
DPTR,#LABEL1

MAIN:

MOV

//

A,R6

SETB

P3.0

//
loads
//

clears

the

adress

"1"

is

//

port

of

line

moved

29

to

activates

3
to

DPTR

accumulator

1st

display

ACALL DISPLAY // calls the display sub routine for getting the pattern for "1"
MOV

P1,A

ACALL

//

moves

DELAY

CLR

//

P3.0

MOV

//

A,R7

SETB

the

//
P3.1

pattern

for

calls

the

deactivates

the

"2"

is

//

"1"

into
1ms
1st

moved

delay
display

to

activates

port

accumulator

2nd

display

ACALL DISPLAY // calls the display sub routine for getting the pattern for "2"
MOV

P1,A

ACALL

moves

DELAY

CLR
SJMP

//

//

P3.1
MAIN

//
//

the

jumps

pattern

for

calls

the

deactivates

the

back

DELAY:

to

main

and

"2"

into
1ms
2nd

cycle

port

delay
display

is

MOV

repeated
R3,#02H

DEL1:

MOV

R2,#0FAH

DEL2:

DJNZ

R2,DEL2

DJNZ

R3,DEL1

RET
DISPLAY: MOVC A,@A+DPTR // adds the byte in A to the address in DPTR and loads
A

with

data

present

in

the

resultant

address

RET
LABEL1:DB

3FH

DB

06H

DB

5BH

DB

4FH

DB

66H

DB

6DH

DB

7DH

DB

07H

DB

7FH

DB 6FH
END
Got any doubts/questions? Ask here in comments!

You might also like