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!