Sunteți pe pagina 1din 30

Microcontroller 15EE52

Module – 5: 8051 Interfacing


Syllabus:
Interfacing: LCD interfacing, Keyboard interfacing.
ADC, DAC and sensor interfacing: ADC 0808 interfacing to 8051, Serial ADC Max1112 ADC interfacing to 8051, DAC
interfacing, Sensor interfacing and signal conditioning.
Motor control: Relay, PWM, DC and stepper motor: Relays and opt isolators, stepper motor interfacing, DC motor
interfacing and PWM.
8051 interfacing with 8255: Programming the 8255, 8255 interfacing, C programming for 8255.

LCD Interfacing:

LCD operation
In recent years the LCD is finding widespread use replacing LEDs (seven-segment LEDs or other multi-segment
LEDs) due to the following reasons:

 The declining prices of LCDs.


 The ability to display numbers, characters, and graphics. This is in contrast to LEDs, which are limited to numbers
and a few characters.
 Incorporation of a refreshing controller into the LCD, thereby relieving the CPU of the task of refreshing the LCD.
In contrast, the LED must be refreshed by the CPU (or in some other way) to keep displaying the data.
 Ease of programming for characters and graphics.

LCD pin descriptions


The LCD having 14 pins is considered and their functions are described in the following table.

Pin Name Function Description


no.
1 VSS power GND
2 VDD Power +5V
3 VEE Contrast adjust 0–5V
4 RS Register Select Signal to select data or command register of the LCD
RS = 0; select command register (for write); Busy flag, address counter (for
read)
RS = 1; select data register ( for write)
5 R/W Read/Write Signal to read/write data from/to LCD.
R/W = 0 ; write to LCD
R/W = 1; read from LCD
6 E Enable (strobe) High to low pulse is applied to this pin to enable LCD to accept (latch)
data/command present on its data lines D0-D7
7-14 D0-D7 Data lines D0 Bidirectional data lines used to send data/command to LCD; or read LCD
(pin-7-LSB) to internal registers, D7 is also used as a busy flag, D4-D7 are used in 4-bit
pin -14-MSB) operation

Dept. of EEE, SJBIT


1
Microcontroller 15EE52
LCD Command Instructions & Codes:
Execution
Instruction RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description
Time (Max)
Clears entire display
Clear and sets DD RAM
0 0 0 0 0 0 0 0 0 1 1.64 ms
Display address 0 in address
counter
Set DD RAM address
0 as address counter.
Also returns display
Return
0 0 0 0 0 0 0 0 1 - being shifted to 1.64ms
Home
original position. DD
RAM contents remain
unchanged.
Sets cursor move
direction and specifies
Entry Mode shift of display. These
0 0 0 0 0 0 0 1 1/D S 40µs
Set operations are
performed during data
write and read.
Sets On/ Off of entire
display (D), cursor On/
Display On/
0 0 0 0 0 0 1 D C B Off (C ), and blink of 40µs
Off control
cursor position
character (B).
Moves cursor and
Cursor or shifts display with-out
0 0 0 0 0 1 S/C R/L - - 40µs
Display Shift changing DD RAM
contents.
Sets interface data
length (DL), number of
Function Set 0 0 0 0 1 DL N F - - 40µs
display lines (L), and
character font (F)
Sets CG RAM address
Set CG
CG RAM data is sent
RAM 0 0 0 1 AGC 40µs
and received after this
Address
setting.
Sets DD RAM address.
Set DD
DD RAM data is sent
RAM 0 0 1 ADD
& received after this
address
setting.
Reads Busy flag (BF)
indicating internal
Read Busy
operation is being
Flag & 0 1 BF AC 40µs
performed & reads
Address
address counter
contents.
Write Data
Write Write data into DD or
CG or DD 1 0 40µs
Data CG RAM
RAM
Read Data CG Read Read data from DD or
1 1 40µs
/ DD RAM Data CG RAM

Dept. of EEE, SJBIT


2
Microcontroller 15EE52

Code (Hex) Command to LCD Instruction Register


1 Clear display screen
2 Return home
4 Decrement cursor (shift cursor to left)
6 Increment cursor (shift cursor to right)
5 Shift display right
7 Shift display left
8 Display off, cursor off
A Display off, cursor on
C Display on, cursor off
E Display on, cursor blinking
F Display on, cursor blinking
10 Shift cursor position to left
14 Shift the entire display to right
18 Shift the entire display to the left
1C Shift the entire display to the right
80 Force cursor to beginning of 1st line
C0 Force cursor to beginning of 2nd line
38 2 lines and 5x7 matrix

Sending commands and data to LCDs with a time delay


To send commands to the LCD, make pin RS=0 & for data, make RS = 1. Then send a high-to-low pulse to the E
pin enable the internal latch of the LCD.
The following pin connections are assumed:

; P1.0-P1.7 are connected to LCD data pins D0-D7


; P2.0 is connected to RS pin of LCD
; P2.1 is connected to R/W pin of LCD
; P2.2 is connected to E pin of LCD

Dept. of EEE, SJBIT


3
Microcontroller 15EE52

ORG 0H
MOV A, #38H ; init. LCD 2 lines ,5x7 matrix
ACALL COMNWRT ; call command subroutine
ACALL DELAY ; give LCD some time
MOV A, #0EH ; display on, cursor on
ACALL COMNWRT ; call command subroutine
ACALL DELAY ; give LCD some time
MOV A, #01 ; clear LCD
ACALL COMNWRT ; call command subroutine
ACALL DELAY ; give LCD some time
MOV A, #06H ;shift cursor right
ACALL COMNWRT ; call command subroutine
ACALL DELAY ; give LCD some time
MOV A, #84H ; cursor at line 1, pos. 4
ACALL COMNWRT ; call command subroutine
ACALL DELAY ; give LCD some time
MOV A, # 'N' ; display letter N
ACALL DATAWRT ; call display subroutine
ACALL DELAY ; give LCD some time
MOV A, # '0' ; display letter 0
ACALL DATAWRT ; call display subroutine
AGAIN: SJMP AGAIN ; stay here
COMNWRT: ; send command to LCD
MOV P1, A ; copy reg A to port 1
CLR P2. 0 ; RS=0 for command
CLR P2. 1 ; R/W=0 for write
SETB P2. 2 ; E=1 for high pulse
ACALL DELAY ; give LCD some time
CLR P2. 2 ; E=0 for H-to -L pulse
RET
DATAWRT: ; write data to LCD
MOV P1, A ; copy reg A to port 1
SETB P2. 0 ; RS=1 for data
CLR P2. 1 ; R/W =0 for write
SETB P2. 2 ; E=1 for high pulse
Dept. of EEE, SJBIT
4
Microcontroller 15EE52
ACALL DELAY ; give LCD some time
CLR P2. 2 ; E=0 for H-to -L pulse
RET
DELAY: MOV R3, #50 ; 50 or higher for fast CPUs
HERE2: MOV R4, #255 ; R4=255
HERE: DJNZ R4, HERE ; stay until R4 become 0
DJNZ R3, HERE2
RET
END

Sending code or data to the LCD with checking busy flag


Another way is to monitor the busy flag before issuing a command to the LCD.
The following pin connections are assumed:
; P1.0-P1.7 are connected to LCD data pins D0-D7
; P2.0 is connected to RS pin of LCD
; P2.1 is connected to R/W pin of LCD
; P2.2 is connected to E pin of LCD

MOV A, #38H ; init. LCD 2 lines ,5x7 matrix


ACALL COMMAND ; issue command
MOV A, #0EH ; LCD on, cursor on
ACALL COMMAND ; issue command
MOV A, #01H ; clear LCD command
ACALL COMMAND ; issue command
MOV A, #06H ; shift cursor right
ACALL COMMAND ; issue command
MOV A, #086H ; cursor: line 1,pos. 6
ACALL COMMAND ; command subroutine
MOV A, # 'N' ; display letter N
ACALL DATA_DISPLAY
MOV A, # '0' ; display letter 0
ACALL DATA_DISPLAY
HERE: SJMP HERE ; stay here
COMMAND: ACALL READY ; is LCD ready?
MOV P1, A ; issue command code
CLR P2. 0 ; RS=0 for command
CLR P2. 1 ; R/W=0 for write to LCD
SETB P2. 2 ; E=1 for H-to -L pulse
CLR P2. 2 ; E=0 , for latch in
RET
DATA_DISPLAY:
ACALL READY ; is LCD ready?
MOV P1, A ; issue data
SETB P2. 0 ; RS=1 for data
CLR P2. 1 ; R/W =0 to write to LCD
SETB P2. 2 ; E=1 for H-to -L pulse
ACALL DELAY ; give LCD some time
CLR P2. 2 ; E=0 , latch in
Dept. of EEE, SJBIT
5
Microcontroller 15EE52
RET
READY: SETB P1.7 ; make P1. 7 input port
CLR P2. 0 ; RS=0 access command reg
SETB P2. 1 ; R/W=1 read command reg
; read command reg and check busy flag
BACK: CLR P2. 2 ; E=0 for L-to -H pulse
ACALL DELAY ; give LCD some time
SETB P2. 2 ; E=1 for L-to -H pulse
JB P1.7, BACK ; stay until busy flag =0
RET
END

LCD data sheet:


In the LCD, one can put data at any location. The following shows address locations and how they are accessed

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0 1 A A A A A A A

Where AAAAAAA = 0000000 to 0100111 for line 1 and AAAAAAA = 1000000 to 1100111 for line 2.

LCD addressing

DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


Line 1 (min) 1 0 0 0 0 0 0 0
Line 1 (max) 1 0 1 0 0 1 1 1
Line 2 (min) 1 1 0 0 0 0 0 0
Line 2 (max) 1 1 1 0 0 1 1 1
the address of cursor positions for various sizes of LCDs are as shown below.

16x2LCD 80 81 82 83 84 85 86 through 8F
C0 C1 C2 C3 C4 C5 C6 through CF
20x1 LCD 80 81 82 83 through 93
20x2 LCD 80 81 82 83 through 93
C0 C1 C2 C3 through D3
20x4 LCD 80 81 82 83 through 93
C0 C1 C2 C3 through D3
94 95 96 97 through A7
D4 D5 D6 D7 through E7
40x2 LCD 80 81 82 83 through A7
C0 C1 C2 C3 through E7
Note: All data is in hex.

Dept. of EEE, SJBIT


6
Microcontroller 15EE52
Ex-1: Write an 8051 C program to send letters ‘M’, ‘D’, and ‘E’ to the LCD using delays.
Solution:
#include <reg51.h>
sfr ldata = 0x90; //P1 = LCD data pins
sbit rs = P2^0;
sbit rw = P2^1;
sbit en = P2^2;
void main ( )
{
1cdcmd (0x38);
MSDELAY (250);
1cdcmd (0x0E);
MSDELAY (250);
1cdcmd (0x01);
MSDELAY (250);
1cdcmd (0x06);
MSDELAY (250);
1cdcmd (0x86); //line 1, position 6
MSDELAY (250);
1cddata (‘M’);
MSDELAY (250);
1cddata (‘D’);
MSDELAY (250);
1cddata (‘E’);
}
void lcdcmd (unsigned char value)
{
1data = value; //put the value on the pins
rs = 0;
rw = 0;
en = 1; //strobe the enable pin
MSDELAY (1);
en = 0;
return;
}
void lcddata (unsigned char value)
{
1data = value; //put the value on the pins
rs = 1;
rw = 0;
en = 1; //strobe the enable pin
MSDELAY (1);
en = 0;
return;
}
void MSDelay (unsigned int time)
{
unsigned inti, j;
Dept. of EEE, SJBIT
7
Microcontroller 15EE52
for(i=0; i<itime; i++)
for (j=0; j<1275; j++);
}

Ex-2: Write an 8051 C program to send letters ‘M’, ‘D’, and ‘E’ to the LCD monitoring the busy flag.
Solution:
#include <reg51.h>
sfr 1data = 0x90; //P1 = LCD data pins (Fig. 12-2)
sfr rs = P2^0;
sfr rw= P2^1;
sfr en= P2^2;
sfr busy= P1^7;
void main ( )
{
1cdcmd (0x38);
1cdcmd (0x0E);
1cdcmd (0x01);
1cdcmd (0x06);
1cdcmd (0x86); //line 1, position 6
1cddata (‘M’);
1cddata (‘D’);
1cddata (‘E’);
}

void lcdcmd (unsigned char value)


{
1cdready( ); //check the LCD busy flag
1data = value; //put the value on the pins
rs = 0;
rw = 0;
en = 1; //strobe the enable pin
MSDELAY (1);
en = 0;
return;
}
void lcddata (unsigned char value)
{
1cdready ( ); //check the LCD busy flag
1data = value; //put the value on the pins
rs = 1;
rw = 0;
en = 1; //strobe the enable pin
MSDELAY (1);
en = 0;
return;
}
void lcdready ( )
{
Dept. of EEE, SJBIT
8
Microcontroller 15EE52
Busy = 1; //make the busy pin an input
rs = 0;
rw = 1;
while (busy = = 1) //wait here for busy flag
{
en = 0; //strobe the enable pin
MSDELAY (1);
en = 1;
}
return;
}
void MSDelay (unsigned int time)
{
unsigned inti, j;
for(i=0; i<itime; i++)
for (j=0; j<1275; j++);
}

Keyboard Interfacing
Keyboards and LCDs are the most widely used input/output devices of the 8051.

Interfacing the keyboard to the 8051


At the lowest level, keyboards are organized in a matrix of rows and columns. The CPU accesses both rows and
columns through ports; therefore, with two 8-bit ports, an 8 x 8 matrix of keys can be connected to a microprocessor.
When a key is pressed, a row and a column make a contact; otherwise, there is no connection between rows and
columns. In such systems, it is the function of programs stored in the EPROM of the microcontroller to scan the keys
continuously, identify which one has been activated, and present it to the motherboard.

Scanning and identifying the key:


Figure below shows a 4 x 4 matrix connected to two ports. The rows are connected to an output port and the columns
are connected to an input port. If no key has been pressed, reading the input port will yield 1s for all columns since
they are all connected to high (V cc). If all the rows are grounded and a key is pressed, one of the columns will have 0
since the key pressed provides the path to ground. It is the function of the microcontroller to scan the keyboard
continuously to detect and identify the key pressed.

Dept. of EEE, SJBIT


9
Microcontroller 15EE52
Grounding Rows and Reading the Columns
To detect a pressed key, the microcontroller grounds all rows by providing 0 to the output latch, and then it reads the
columns. If the data read from the columns is D3 – D0 = 1111, no key has been pressed and the process continues until
a key press is detected. However, if one of the column bits has a zero, this means that a key press has occurred. For
example, if D3-D0 = 1101, this means that a key in the D1 column has been pressed. After a key press is detected, the
microcontroller will go through the process of identifying the key. Starting with the top row, the microcontroller
grounds it by providing a low to row D0 only; then it reads the columns. If the data read is all 1s, no key in that row is
activated and the process is moved to the next row. It grounds the next row, reads the columns, and checks for any
zero. This process continues until the row is identified. After identification of the row in which the key has been
pressed, the next task is to find out which column the pressed key belongs to. This should be easy since the
microcontroller knows at any time which row and column are being accessed.

To make sure that the preceding key has been released, 0s are output to all rows at once, and the columns are read and
checked repeatedly until all the columns are high. When all columns are found to be high, the program waits for a short
amount of time before it goes to the next stage of waiting for a key to be pressed.
To see if any key is pressed, the columns are scanned over and over in an infinite loop until one of them has a 0 on it.
Remember that the output latches connected to rows still have their initial zeros (provided in stage 1), making them
grounded. After the key press detection, the microcontroller waits 20 ms for the bounce and then scans the columns
again. This serves two functions: (a) it ensures that the first key press detection was not an erroneous one due to a spike
noise, and (b) the 20-ms delay prevents the same key press from being interpreted as a multiple key press. If after the
20-ms delay the key is still pressed, it goes to the next stage to detect which row it belongs to; otherwise, it goes back
into the loop to detect a real key press.
To detect which row the key press belongs to, the microcontroller grounds one row at a time, reading the columns each
time. If it finds that all columns are high, this means that the key press cannot belong to that row; therefore, it grounds
the next row and continues until it finds the row the key press belongs to. Upon finding the row that the key press
belongs to, it sets up the starting address for the look-up table holding the scan codes (or the ASCII value) for that row
and goes to the next stage to identify the key.
To identify the key press, the microcontroller rotates the column bits, one bit at a time, into the carry flag and checks to
see if it is low. Up on finding the zero, it pulls out the ASCII code for that key from the look-up table; otherwise, it
increments the pointer to point to the next element of the look-up table.
While the key press detection is standard for all keyboards, the process for determining which key is pressed varies.

Dept. of EEE, SJBIT


10
Microcontroller 15EE52

MOV P2, #0FFH ; make P2 an input port


K1: MOV P1, #0 ; ground all rows at once
MOV A, P2 ; read all col. Ensure all keys open
ANL A, #00001111B ; masked unused bits
CJNE A, #00001111B, K1 ; check till all keys released
K2: ACALL DELAY ; call 20 ms delay
MOV A, P2 ; see if any key is pressed
ANL A, #00001111B ; mask unused bits
CJNE A, #00001111B, OVER ; key pressed, await closure
SJMP K2 ; check if key pressed
OVER: ACALL DELAY ; wait 20 ms debounce time
MOV A, P2 ; check key closure
ANL A, #00001111B ; mask unused bits
CJNE A, #00001111B, OVER1 ; key pressed, find row

Dept. of EEE, SJBIT


11
Microcontroller 15EE52
SJMP K2 ; if none, keep polling
OVER1: MOV P1, #11111110B ; ground row 0
MOV A, P2 ; read all columns
ANL A, #00001111B ; mask unused bits
CJNE A, #00001111B, ROW_0 ; key row 0, find the col.
MOV P1, #11111101B ; ground row 1
MOV A, P2 ; read all columns
ANL A, #00001111B ; mask unused bits
CJNE A, #00001111B, ROW_1 ; key row 1, find the col.
MOV P1, #11111011B ; ground row 2
MOV A, P2 ; read all columns
ANL A, #00001111B ; mask unused bits
CJNE A, #00001111B, ROW_2 ; key row 2, find the col.
MOV P1, #11110111B ; ground row 3
MOV A, P2 ; read all columns
ANL A, #00001111B ; mask unused bits
CJNE A, #00001111B, ROW_3 ; key row 3, find the col.
LJMP K2 ; if none, false input, repeat

ROW0: MOV DPTR, # KCODE0 ;set DPTR = start of row 0


SJMP FIND ; find col. Key belongs to
ROW1: MOV DPTR, # KCODE1 ; set DPTR = start of row 1
SJMP FIND ; find col. Key belongs to
ROW2: MOV DPTR, # KCODE2 ;set DPTR = start of row 2
SJMP FIND ; find col. Key belongs to
ROW0: MOV DPTR, # KCODE3 ;set DPTR = start of row 3
FIND: RRC A ; see if any CY bit is low
JNC MATCH ; if zero, get the ASCII code
INC DPTR ; point to next col. Address
SJMP FIND ; keep searching
MATCH: CLR A ; set A = 0 (match is found)
MOVC A, @A+DPTR ; get ASCII code from table
MOV P0, A ; display pressed key
LJMP K1
; ASCII LOOK-UP TABLE FOR EACH ROW
ORG 300H
KCODE0: DB ‘0’, ‘1’,’2’,’3’ ; ROW 0
KCODE1: DB ‘4’, ‘5’,’6’,’7’ ; ROW 1
KCODE2: DB ‘8’, ‘9’,’A’,’B’ ; ROW 2
KCODE3: DB ‘C’, ‘D’,’E’,’F’ ; ROW 3
END

Dept. of EEE, SJBIT


12
Microcontroller 15EE52
ADC0808/0809 chip with 8 analog channels:

The ADC0808 chip allows us to monitor up to 8 different analog inputs using only a single chip. The ADC0808/0809
has an 8-bit data output. The 8 analog input channels are multiplexed and selected according to below table using three
address pins, A, B, and C.
Table: ADC0808/0809 analog channel selection
Selected Analog Channel C B A
IN0 0 0 0
IN1 0 0 1
IN2 0 1 0
IN3 0 1 1
IN4 1 0 0
IN5 1 0 1
IN6 1 1 0
IN7 1 1 1

In the ADC0808/0809, Vref(+) and Vref(-) set the reference voltage. If Vref(-) = Gnd and Vref (+) = 5V, the step size is 5
V /256 =19.53 mV. Therefore, to get a 10 mV step size we need to set Vref(+) = 2.56V and Vref(-) = Gnd. From the
above figure, notice the ALE pin. We Use A, B, and C addresses to select IN0 – IN7, and activate ALE to latch in the
address. SC is for start conversion. EOC is for end-of-conversion, and OE is for output enable (READ). Table below
shows the step size relation to the Vref voltage.

Table: Vref relation to Vin Range for ADC088/0809


Vref (V) Vin(V) Step Size (mV)
Not connected 0 to 5 5/256 = 19.53
4.0 0 to 4 4/256 = 15.62
3.0 0 to 3 3/256=11.71
2.56 0 to 2.56 2.56/256=10
2.0 0 to 2 2/256 = 7.81
1 0 to 1 1/256=3.90

Dept. of EEE, SJBIT


13
Microcontroller 15EE52
Interfacing of ADC0808/0809 with 8051:

Steps to program the ADC0808/0809:


The following are steps to get data from an ADC0808/0809
1. Select an analog channel by providing corresponding bits to A, B, and C addresses.
2. Activate the ALE (address latch enable) pin. It needs an L-to-H pulse to latch in the address.
3. Activate SC (start conversion) by an L-to-H pulse to initiate conversion.
4. Monitor EOC (end of conversion) to see whether conversion is finished. H-to-L output indicates that the data is
converted and is ready to be picked up. If we do not use EOC, we can read the converted digital data after a brief
time delay. The delay size depends on the speed of the external clock we connect to the CLK pin.
5. Activate OE (output enable) to read data out of the ADC chip. An L-to-H pulse to the OE pin will bring digital
data out of the chip.
6. Notice in the ADC0808/0809 that there is no self-clocking and the clock must be provided from an external source
to the CLK pin. Although the speed of conversion depends on the frequency of the clock connected to the CLK
pin, it cannot be faster than 100 microseconds.

Programming ADC0808/0809 in Assembly

ALE BIT P2.4


OE BIT P2.5
SC BIT P2.6
EOC BIT P2.7
ADDR_A BIT P2.0
ADDR_B BIT P2.1
ADDR_C BIT P2.2
MYDATA EQU P1
ORG 0H
MOV MYDATA, # 0FFH ; make P1 an input
SETB EOC ; make EOC an input
CLR ALE ; clear ALE
CLR SC ; clear WR ;
CLR OE ; clear RD

Dept. of EEE, SJBIT


14
Microcontroller 15EE52
BACK:
CLR ADDR_C ; C=0
CLR ADDR_B ; B=0
SETB ADDR_A ; A=1 (select Channel 1)
ACALL DELAY ; make sure the address is stable
SETB ALE ; latch address
ACALL DELAY ;
SETB SC ; start conversion
ACALL DELAY
CLR ALE
CLR SC
HERE: JB EOC, HERE ; wait until done
HERE1: JNB EOC, HERE1 ; wait until done
SETB OE ; enable RD
ACALL DELAY ; wait
MOV A, MYDATA ; read data
CLR OE ; clear RD for next time
ACALL CONVERSION ; hex to ASCII
ACALL DATA_DISPLAY ; display the data
SJMP BACK

Programming ADC0808/0809 in C

#include <reg51.h>
sbit ALE = P2^4;
sbit OE = P2^5;
sbit SC = P2^6;
sbit EOC = P2^7;
sbit ADDR_A = P2^0;
sbit ADDR_B = P2^1;
sbit ADDR_C = P2^2;
sfr MYDATA = P1;
void main ( )
{
unsigned char value; //make P1 an input
MYDATA = 0xFF; //make EOC an input
ALE = 0; //clear ALE
OE = 0; //clear OE
SC = 0; // clear SC
while (1)
{
ADDR_C = 0; //C=0
ADDR_B = 0; //B=0
ADDR_A = 1; //A=1 (Select Channel 1)
MSDelay(1); //delay for fast DS89C4x0
ALE = 1;
MSDELAY(1);
SC = 1;

Dept. of EEE, SJBIT


15
Microcontroller 15EE52
MSDELAY (1);
ALE = 0;
SC = 0; // start conversion
While (EOC = = 1); //wait for data conversion
While(EOC = =0);
OE = 1; //enable RD
MSDelay (1);
Value = MYDATA; //get the data
OE = 0; //disable RD for next round
ConvertAndDisplay (value);
}
}

Serial ADC:

For many applications where space is a critical issue, using large number of parallel pins for data is not feasible for
which serial ADC are becoming widely used.

MAX1112 ADC:
The MAX1112 is an 8-bit serial ADC chip with 8 channels of analog input. It has a single D out pin to bring out the
digital data after it has been converted:

CH0-CH7: CH0 - CH7 are 8 channels of the analog inputs. In the single-ended mode, each of the channels can be used
for an analog input where the COM pin is used as a ground reference for all the channels. In single- ended mode, 8
channels of input allow us to read 8 different analog inputs. We select the input channel by sending in the control byte
via the DIN pin. In differential mode, we have 4 sets of 2-channel differentials. CH0 and CH1 go together, and CH2 -
CH3, and so on.

COM: Ground reference for the analog input in single-ended mode.

CS: Chip select is an active low Input used to select the MAX112chip. To send in the control byte via the D IN pin, CS
must be low. When CS is high the DOUT is high impedance.
Dept. of EEE, SJBIT
16
Microcontroller 15EE52

SCLK: Serial clock input. SCLK is used to bring data out and send in the control byte, one bit at a time.

DOUT: Serial data out. The digital data is clocked out one bit at a time on the H-to-L edge (falling edge) of SCLK.

DIN: Serial data in the control byte is clocked in one bit at a time on the L-to-H edge (rising edge) of SCLK.

SSTRB: Serial strobe output. In internal clock mode-this indicates end-of-conversion. It goes high when the
conversion is complete.

VDD: VDD is the +5 volt power supply.

AGND, DGND (analog ground and digital ground): Both are input pins providing ground for both the analog and
the digital signals.
SHDN: Shutdown is an input and is normally not connected (or is connected to V DD). If low, the ADC is shut down to
save power. This is shut down by hardware. The control byte causes shutdown by software.

REFIN: Reference voltage input. This voltage dictates the step size.

REFOUT: Internal Reference Generator output. A 1 µF bypass capacitor is placed between this pin and AGND.

MAX1112 control byte:


The MAX112 chip has 8 channels of analog inputs that are selected using a control byte. The control byte is fed into
the MAX112 serially one bit at a time via the DIN pin with the help of SCLK. The control byte must be sent in with the
MSB (most significant bit) going in first. The MSB of the control byte is high to indicate the start of the control byte,
as shown in below figure.

Start SEL2 SEL1 SEL0 UN/BIP SGL/DF PD1 PD0

Start The MSB (D7) must be high to define the beginning of the control byte.
SEL2 SEL1 SEL0 CHANNEL SELECTION (SINGLE-ENDED MODE0)
0 0 0 CHAN0
0 0 1 CHAN1
0 1 0 CHAN2
0 1 1 CHAN3
1 0 0 CHAN4
1 0 1 CHAN5
1 1 0 CHAN6
1 1 1 CHAN7
UN/BIP 1 = unipolar: Digital data output is binary 00 – FFH
0 = bipolar: Digital data output is in 2’s complement.
SGL/DIF 1= single-ended: 8 channels of single-ended with COM as reference
0 = differential: Two channels (eg., CH0-CH1) are differential.
PD1 1= fully operational
0= power-down: Power down to save power using software.
PD0 1= external clock mode: The conversion speed is dictated by SCLK.
0 = internal clock mode: The conversion speed is dictated internally, and the SSTRB pin
goes high to indicate end-of-conversion (EOC).
Dept. of EEE, SJBIT
17
Microcontroller 15EE52

Interfacing serial ADC MAX1112 to 8051:

REFIN voltage and step size:


The step size for the MAX112 depends on the voltage connected to the REFIN pin. In unipolar mode, with VDD = 5 V,
we get 4.096 V for full-scale if the REFIN pin is connected to the AGND with a 1-µF capacitor. That gives us a 16mV
step size since 4.096V /256 = 16 mV. To get a 10 mV step size, we need to connect the REFIN pin to a 2.56 V external
voltage source, since 2.56V / 256 = 10 mV. According to the MAX1112 data sheet, the external reference voltage must
be between 1V and VDD.

Selecting a channel:
We select the analog input channel using the control byte. The MSB (D7) of the control byte must be high. The control
byte is fed into the DIN pin one bit at a time using SCLK. The DIN pin clocks in the control byte on the rising edge of
SCLK.

Ex: Find the MAX1112 control byte for (a) CH0, and (b) CH3. Assume single-ended, unipolar, internal clock,
and fully operational modes.
Solution:

(a) 10001110(8E in hex) (b) 10111110 (BE in hex)

Ex: Assembly Code for sending in control byte for MAX1112

CS BIT P2.0
SCLK BIT P2.1
DIN BIT P2.2
DOUT BIT P2.3

MOV A, #9EH ; channel 1 selection


Dept. of EEE, SJBIT
18
Microcontroller 15EE52
MOV R3, #8 ; load count
CLR CS ; CS = 0
CLR C
H1: RLC A ; give bit to CY
MOV DIN, C ; send bit to DIN
CLR SCLK ; low SCLK for L-H pulse
ACALL DELAY ; delay
SETB SCLK ; latch data
ACALL DELAY ; delay
DJNZ R3, H1 ; repeat for all 8 bits
SETB CS ;deselect ADC, Conversion Starts
CLR SCLK ; SCLK =0 during conversion

Ex: C code for sending in control byte for MAX1112 ADC

#include <reg51.h>
sbit CS = P2^0;
sbit SCLK= P2^1;
sbit DIN = P2^2;
sbit DOUT = P2^3;
sbit MSBRA = ACC^7;
void main ( )
{
unsigned char conbyte = 0x9E; //Chan 1
unsigned char x;
ACC = conbyte;
CS = 0;
for (x = 0; x<8; x++)
{
SCLK = 0; //Send D7 of Reg A to Din
DIN = MSBRA;
Delay ( );
SCLK = 1; // latch in the bit
Delay ( );
ACC = ACC<< 1; // next bit
}
CS = 1; // deselect MAX1112
SCLK = 0; // make SCLK low during conversion
}

Start conversion and end of conversion for MAX1112:


When the last bit of the control byte, PD0, is sent in, the conversion starts, and SSTRB goes-low. The end-of-
conversion state is indicated by SSTRB going high, which happens 55 µs after PD0 is clocked in. We can either wait
55 µs, or monitor SSTRB before we get the digital data out of the ADC chip.

Reading out digital data:


The 8-bit converted digital data is brought out of the MAX1112 via the DOUT pin using SCLK. As we apply a negative-
edge pulse to the SCLK pin, the 8-bit digital data is read out one bit at a time with the MSB (D7) coming out first. The

Dept. of EEE, SJBIT


19
Microcontroller 15EE52
SSTRB goes high to indicate that the conversion is finished. After SSTRB goes high, the second falling edge of SCLK
produces the MSB of converted data at the DOUT pin. In other words, we need 9 pulses to get data out. To bring data
out, CS must be low.

Ex: ALP for reading out digital data in the MAX1112.

CS BIT P2.0
SCLK BIT P2.1
DIN BIT P2.2
DOUT BIT P2.3

SETB DOUT ; make it an input


CLR CS ; CS = 0
SETB SCLK
ACALL DELAY ; need delay for DS89C4x0
CLR SCLK ; first H-to-L
ACALL DLELAY ; read data out on 2ND H-to-L
CLR A
MOV R3, #8;
H2: SETB SCLK;
ACALL DELAY ; need delay for DS89C4x0
CLR SCLK ;H-to-L pulse to get bit out
ACALL DELAY;
MOV C, DOUT ; move bit to CY flag
RLC A ; bring in the bit
DJNZ R3, H2 ; repeat for all 8 bits
SETB CS ; CS = 1
MOV P1, A ; send converted data to P1

Ex: C Code for reading data in MAX1112

#include <reg51.h>
sbit CS = P2^0;
sbit SCLK= P2^1;
sbit DIN = P2^2;
sbit DOUT = P2^3;
sbit LSBRA = ACC^0;

void main ( )
{
unsigned char x;

Dept. of EEE, SJBIT


20
Microcontroller 15EE52
CS = 0; //select max1112
SCLK = 1; //an extra H-to-L pulse
Delay ( );
SCLK = 0;
Delay ( );
for (x=0; x<8, x++) // get all 8 bits
{
SCLK = 1;
Delay ( );
SCLK = 0;
Delay ( )
LSBRA = DOUT; //bring in bit from DOUT pin to D0 of Reg A
ACC = ACC << 1; //keep shifting data for all 8 bits
}
CS = 1; //deselect ADC
P1=ACC; //display data on P1
}

Ex: ALP to select the channel and read the ADC data

CS BIT P2.0
SCLK BIT P2.1
DIN BIT P2.2
DOUT BIT P2.3

ORG 0H
; sending in control byte
MAIN: MOV A, #9EH ; channel 1
MOV R3, #8 ; load count
CLR CS ; CS=0
H1: RLC A ; give bit to CY
MOV DIN, C ; send bit to DIN
CLR SCLK ; low SCLK for L-H pulse
ACALL DELAY ; delay
SETB SCLK ;latch data
ACALL DELAY ; delay
DJNZ R3, H1 ; repeat for all 8 bits
SETB CS ; deselect ADC, conv starts
CLR SCLK ; SCLK = 0 during conversion
SETB DOUT ; make it an input
; Reading data out
CLR CS ; CS = 0
SETB SCLK
ACALL DELAY ; need delay for DS89C4x0
CLR SCLK ; first H-to-L
ACALL DLELAY ; read data out on 2nd H-L
MOV R3, #8 ;

Dept. of EEE, SJBIT


21
Microcontroller 15EE52
H2: SETB SCLK ;
ACALL DELAY ; need delay
CLR SCLK ; H-to-L pulse to get bit out
ACALL DELAY;
MOV C, DOUT ; move bit to CY flag
RLC A ; bring in the bit
DJNZ R3, H2 ; repeat for all 8 bits
SETB CS ; CS = 1
MOV P1, A ; display data on P1
SJMP MAIN ; keep doing it

Ex: C Program to select the channel and read the ADC data

#include <reg51.h>
sbit CS = P2^0;
sbit SCLK= P2^1;
sbit DIN = P2^2;
sbit DOUT = P2^3;
sbit MSBRA = ACC^7;
sbit LSBRA = ACC^0;
void main ( )
{
unsigned char conbyte = 0x9E; //Chan 1
unsigned char x;
while (1)
{
ACC = conbyte; //select the channel
CS = 0;
for (x=0; x<8; x++)
{
SCLK = 0;
DIN = MSBRA; //send D7 of Reg A to Din
Delay ( );
SCLK = 1; //latch in the bit
Delay ( );
ACC = ACC << 1; //next bit
}
CS = 1; //deselect MAX1112
SCLK = 0; // make SCLK low during conversion
CS = 0; //read the data
SCLK = 1; // an extra H-to-L pulse
Delay( );
SCLK = 0; // get all 8 bits
Delay();
For (x=0, x<8, x++)
{
SCLK = 1;
Delay ( );
Dept. of EEE, SJBIT
22
Microcontroller 15EE52
SCLK = 0;
Delay ( )
LSBRA = DOUT; //bring in bit from DOUT pin to D0 of Reg A
ACC = ACC << 1; //keep shifting data for all 8 bits
}
CS = 1; //deselect ADC
P1=ACC; //display data on P1
}
}

DAC INTERFACING:
Digital-to-analog (DAC) converter:
The digital-to-analog converter (DAC) is a device widely used to convert digital pulses to analog signals.
Two methods of creating a DAC are: binary weighted and R/ 2R ladder. The majority of integrated circuit DACs uses
the R/2R method since it can achieve a much higher degree of precision. The first criterion for judging a DAC is its
resolution, which is a function of the number of binary inputs. The common ones are 8, 10, and 12 bits. The number of
data bit inputs decides the resolution of the DAC since the number of analog-output levels is equal to 2n, where n is the
number of data bit inputs. Therefore, an 8-input DAC such as the DAC0808 provides 256 discrete voltage (or current)
levels of output. Similarly, the 12-bit DAC provides 4096 discrete voltage levels. There are also 16-bit DACs, but they
are more expensive.

MC1408 DAC (or DAC0808):

In the MC1408 (DAC0808), the digital inputs are converted to current (Iout), and by connecting a resistor to the IOUT
pin, we convert the result to voltage. The total current provided by the Iout pin is a function of the binary numbers at the
D0 - D7 inputs of the DAC0808 and the reference current (Iref), and is as follows:

𝐷7 𝐷6 𝐷5 𝐷4 𝐷3 𝐷2 𝐷1 𝐷0
𝐼𝑜𝑢𝑡 = 𝐼𝑟𝑒𝑓 ( + + + + + + + )
2 4 8 16 32 64 128 256

Where D0 is the LSB, D7 is the MSB for the inputs, and Iref is the input current that must be applied to pin 14. The Iref
current is generally set to 2.0 mA. Figure above shows the generation of current reference (setting Iref = 2 mA) by using
the standard 5-V power supply and 1K and l.5K-ohm standard, resistors.

Ex-3: For the above circuit, find the maximum output amplitude of the saw tooth waveform obtained with the
following program.

(a) MOV A, #00H

Dept. of EEE, SJBIT


23
Microcontroller 15EE52
MOV P1, A
BACK: INC A
SJMP BACK

(b) MOV R0, #64H


RPT: MOV A, #00H
BACK: MOV P1, A
INC A
CJNE A, R0, BACK
SJMP RPT
Solution:

(a) Here, the method to generate the saw tooth wave is to increment the A register from 0 to FF to 0 continuously, In
this case, the maximum value of the digital number is FFH =11111111B.
𝐷7 𝐷6 𝐷5 𝐷4 𝐷3 𝐷2 𝐷1 𝐷0
𝐼𝑜𝑢𝑡 = 𝐼𝑟𝑒𝑓 ( + + + + + + + )
2 4 8 16 32 64 128 256

= 2mA x 255/256 = 2x0.996 = 1.99mA

V OUT = 1.99mA x 5K = 9.96 V ;The peak amplitude of the saw tooth waveform is 9.96 V.

(b) In this case, the maximum value of the digital number is 64 H = 01100100B. With the same calculation,
IOUT = 0.78125MA
VOUT = 3.906 V

Converting Iout to voltage in DAC0808:


Ideally we connect the output pin Iout to a resistor, convert this current to voltage, and monitor the output on the scope.
In real life, however, this can cause inaccuracy since the input resistance of the load where it is connected will also
affect the output voltage. For this reason, the Iref current output is isolated by connecting it to an op-amp such as the
741 with Rf = 5K ohms for the feedback resistor.

Ex: In the circuit, connect a switch SW to pin P0.0. Write a program to do the following:
When SW = 0, the DAC output gives a staircase waveform.
When SW = 1, the DAC output gives a triangular waveform.

Solution:
Staircase waveform for 5 steps: 255/5 = 51.
So the increment of each step is 51. After maximum value is reached, the output drops to zero and the next cycle starts.

SW EQU P0.0
ORG 0000H
Dept. of EEE, SJBIT
24
Microcontroller 15EE52
SETB SW ; make SW an input port
CHECK: MOV C, SW ; move SW to carry
JC TRIANG ; if SW = 1, jump to TRIANG
START: MOV A, #00 ; this is for the staircase, A = 0
MOV P1, A ; move A to P1
ACALL DELAY ; delay
RPT: ADD A, #51 ; add 51 to get the next step
MOV P1, A ; output value to port 1
ACALL DELAY ; delay
CJNE A, #255, RPT ; check if A =255. If not, go to next step
SJMP CHECK ; the staircase has reached maximum value
; check SW before continuing
TRIANG: MOV A, #00 ; this is for the triangular wave, A = 0
INCR: MOV P1, A ; output value on P1
INC A ; increment A for upward transition
CJNE A, #255, INCR ; check if A = 255, if not keep incrementing
DECR: MOV P1, A ; output value on P1
DEC A ; decrement A for downward transition
CJNE A, #00, DECR ; if A = 0, the minimum, step out
SJMP CHECK ; check SW before starting the next cycle
DELAY:
RPT1: MOV R1, #20 ; this delay routine gives a delay ‘T’
RPT2: MOV R2, #200
RPT3: DJNZ R0, RPT3
DJNZ R0, RPT2
DJNZ R0, RPT1
RET
END

Generating a sine wave:


To generate a sine wave, we first need a table whose values represent the magnitude of the sine of angles between 0
and 360 degrees. The values for the sine function vary from -1.0 to +1.0 for 0- to 360-degree angles. Therefore, the
table values are integer numbers representing the voltage magnitude for the sine of theta. This method ensures that only
integer numbers are output to the DAC by the 8051 microcontroller. Table below shows the angles, the sine values, the
voltage magnitudes, and the integer values representing the voltage magnitude for each angle (with 30-degree
increments). To generate the below table, we assume the full-scale voltage of 10 V for DAC output. Full-scale output
of the DAC is achieved when all the data inputs of the DAC are high. Therefore, to achieve the full-scale 10 V output,
we use the following equation.
VOUT = 5 V + (5 x sin ɵ)
VOUT of DAC for various angles is calculated and shown in below table.
To find the value sent to DAC for various angles we simply multiply the V out voltage by 25.60 because there are 256
steps and full-scale Vout is 10 volts. Therefore, 256 steps/10V = 25.6 steps per volt.

Table: Angle vs. Voltage Magnitude for Sine Wave


Angle ɵ (degrees) Sin ɵ VOUT (Voltage Magnitude) 5V Values sent to DAC (decimal)
+(5V x sin ɵ) (Voltage Mag. X 25.6)
0 0 5 128
30 0.5 7.5 192
60 0.866 9.33 238
Dept. of EEE, SJBIT
25
Microcontroller 15EE52
90 1.0 10 255
120 0.866 9.33 238
150 0.5 7.5 192
180 0 5 128
210 -0.5 2.5 64
240 -0.866 0.669 17
270 -1.0 0 0
300 -0.866 0.669 17
330 -0.5 2.5 64
360 0 5 128
AGAIN: MOV DPTR, # TABLE
MOV R2, #COUNT
BACK: CLR A
MOVC A, @ A + DPTR
MOV P1, A
INC DPTR
DJNZ R2, BACK
SJMP AGAIN
ORG 300
TABLE: DB 128, 192, 238, 255, 238, 192 ; see above table
DB 128, 64, 17, 0, 17, 64, 128
END

Programming DAC in C

#include <reg51.h>
sfr DACDATA = P1;
void main ( )
{
unsigned char WAVEVALUE[12] = {128, 192, 238, 255, 238, 192, 128, 64, 17, 0, 17, 64};
unsigned char x ;
while (1)
{
for (x=0; x<12; x++)
{
DACDATA = WAVEVALUE [x];
}
}
}

Dept. of EEE, SJBIT


26
Microcontroller 15EE52
Sensor interfacing and signal conditioning:
Transducers convert physical data such as temperature, light intensity, flow, and speed to electrical signals. Depending
on the transducer, the output produced is in the form of voltage, current, resistance, or capacitance.

Temperature sensors:
Temperature is converted to electrical signals using a transducer called a thermistor. A thermistor responds to
temperature change by changing resistance, but its response is not linear as shown in below table. Complexity
associated with writing software for such nonlinear devices has led many manufacturers to
a linear temperature sensor. Simple and widely used linear temperature sensors include the LM34 and LM35 series
from National Semiconductor Corp.
Table: Thermistor Resistance vs. Temperature
Temperature (C) Tf (K ohms)
0 29.490
25 10.000
50 3.893
75 1.700
100 0.817

LM34 and LM35 temperature sensors:


The sensors of the LM34 series are precision integrated-circuit temperature sensors whose output voltage is linearly
proportional to the Fahrenheit temperature as shown in above table. The LM34 requires no external calibration since it
is internally calibrated. It outputs 10mV for each degree of Fahrenheit temperature.
The LM35 series sensors are precision integrated-circuit temperature sensors whose output voltage is linearly
proportional to the Celsius (centigrade) temperature. The LM35 requires no external calibration since it is internally
calibrated. It outputs 10 mV for each degree of centigrade temperature.

Table: LM34 Temperature Sensor series selection Guide


Part Scale Temperature Range Accuracy Output
LM34A -50 F to +300 F +2.0 F 10mV / F
LM34 -50 F to +300 F +3.0 F 10mV / F
LM34CA -40 F to +230 F +2.0 F 10mV / F
LM34C -40 F to +230 F +3.0 F 10mV / F
LM34D -32 F to +212 F +4.0 F 10mV / F

Table: LM35 Temperature Sensor Series Selection Guide


Part Temperature Range Accuracy Output Scale
LM35A -55 C to + 150 C + 1.0 C 10 mV / C
LM35 -55 C to + 150 C + 1.5 C 10 mV / C
LM35CA -40 C to + 110 C + 1.0 C 10 mV / C
LM35C -40 C to + 110 C + 1.5 C 10 mV / C
LM35D 0 C to + 100 C + 2.0 C 10 mV / C

Signal conditioning and interfacing the LM35 to the 8051:


Signal conditioning is widely used in the world of data acquisition. The most common transducers produce an output in
the form of voltage, current, charge, capacitance, and resistance. However, we need to convert these signals to voltage
in order to send input to an A-to-D converter. This conversion (modification) is commonly called signal conditioning.
Signal conditioning can be a current-to-voltage conversion or signal amplification. For example, the thermistor
Dept. of EEE, SJBIT
27
Microcontroller 15EE52
changes resistance with temperature. The change of resistance must be translated into voltages in order to be of any use
to an ADC.

Figure below shows the connection of a temperature sensor to the ADC0848. Here LM336-2.5 zener diode is used to
fix the voltage across the 10K pot at 2.5 volts. The use of the LM336-2.5 should overcome any fluctuations in the
power supply.

Temperature vs. Vout for ADC0848


Temp. (C) V in (mV) V out (D7-D0)
0 0 0000 0000
1 10 0000 0001
2 20 0000 0010
3 30 0000 0011
10 100 0000 1010
30 300 0001 1110

Ex: ALP to read temperature, convert it and put it on P0 with some delay

RD BIT P2.5 ;RD


WR BIT P2.5 ; WR (start conversion)
INTR BIT P2.5 ; end-of-conversion
MYDATA EQU P1 ; P1.0-P1.7 = D0-D7 of the ADC0848
MOV P1, #0FFH ; make P1 = input
Dept. of EEE, SJBIT
28
Microcontroller 15EE52
SETB INTR
BACK: CLR WR ;WR = 0
SETB WR ; WR = 1 L-to-H to start conversion
HERE: JB INTR, HERE ; wait for end of conversion
CLR RD ; conversion finished, enable RD
MOV A, MYDATA ; read the data from ADC0848
ACALL CONVERSION ;hex-to-ASCII conversion
ACALL DATA_DISPLAY ;display the data
SETB RD ; make RD = 1 for next round
SJMP BACK

CONVERSION:
MOV B, #10
DIV AB
MOV R7, B ; least significant byte
MOV B, #10
DIV AB
MOV R6, B
MOV R5, A ; most significant byte
RET

DATA_DISPLAY:
MOV P0, R7
ACALL DELAY
MOV P0, R6
ACALL DELAY
MOV P0, R5
ACALL DELAY
RET
DELAY:
MOV R0, #0FFh
ITR2: MOV R1, #0FFh
ITR1: DJNZ R1, ITR1
DJNZ R0, ITR2
RET

Ex: C program to read temperature, convert it and put it on P0 with some delay

#include <reg51.h>
sbit RD = P2^5;
sbit WR= P2^6;
sbit INTR = P2^7;
sfr MYDATA = P1; //P1 connected to D0-D7 of 848
void ConvertAndDisplay (unsigned char value);
void MSDelay (unsigned int value);
void main ( )
{
MYDATA = 0x FF; //make P1 and input
Dept. of EEE, SJBIT
29
Microcontroller 15EE52
INTR = 1; //make INTR and input
RD = 1; //set RD high
WR = 1; //set WR high
{
WR = 0; //send WR pulse
WR = 1;
While (INTR = = 1); //wait for EOC
RD = 0; //send RD pulse
Value = MYDATA; //read value from ADC0848
ConvertAndDisplay (value);
RD = 1;
}
}
void ConvertAndDisplay (unsigned char value)
{
unsigned char x, d1, d2, d3;
x = value/10;
d1 = value%10;
d2 = x %10
d3 = x/10
P0 = d1; //LSBYTE
MSDelay (250);
P0 = d2;
MSDelay (250);
P0 = d3; //MSBYTE
MSDelay (250);
}
void MSDelay (unsigned int value)
{
unsigned char x, y;
for (x=0; x<value; x++)
for (y=0;y<1275;y++);
}

Dept. of EEE, SJBIT


30

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