Professional Documents
Culture Documents
MICROCONTROLLER APPLICATIONS
LAB MANUAL
(ECE263)
SYLLABUS
MICROCONTROLLER APPLICATION LAB
I. PROGRAMMING
1. Data Transfer - Block move, Exchange, Sorting, Finding largest element in an array.
2. Arithmetic Instructions – Addition, subtraction, multiplication and division, square, Cube – (16
bits Arithmetic operations – bit addressable).
3. Counters.
4. Boolean & Logical Instructions (Bit manipulations).
5. Code conversion: BCD – ASCII; Decimal - ASCII; HEX - Decimal and Decimal - HEX.
Note: Programming exercise is to be done on 8051 using KEIL .
II. INTERFACING:
Write C programs to interface 8051 chip to Interfacing modules to develop single chip solutions.
6.. Simple Calculator using 6 digit seven segment display and Hex Keyboard interface to 8051.
7. Alphanumeric LCD panel and Hex keypad input interface to 8051.
8. External ADC and Temperature control interface to 8051.
9. Generate different waveforms Sine, Square, Triangular, Ramp etc. using DAC interface to 8051;
change the frequency and amplitude.
10. Stepper and DC motor control interface to 8051.
11. Elevator interface to 8051
Note: Programming exercise is to be done on 8051 using KEIL uv3, Microcontroller 8051 kit
and flip 2.4.2 tool.
CONTENTS
INTRODUCTION
Features of 8051:
The main features of 8051 microcontroller are:
1) RAM – 128 Bytes (Data memory)
2) ROM – 4Kbytes (ROM signify the on – chip program space)
3) Serial Port – Using UART makes it simpler to interface for serial communication.
4) Two 16 bit Timer/ Counter
5) Input/output Pins – 4 Ports of 8 bits each on a single chip.
6) Five Interrupt Sources
7) 8 – bit ALU (Arithmetic Logic Unit)
8) Harvard Memory Architecture – It has 16 bit Address bus (each of RAM and ROM)
and 8 bit Data Bus.
9) 8051 can execute 1 million one cycle instructions per second with a clock frequency of
12MHz.
This microcontroller is also called as “System on a chip” because it has all the features on a
single chip
AT89C51ED2 MICROCONTROLLER
Description
AT89C51RD2/ED2 is high performance CMOS Flash version of the 80C51 CMOS single
chip 8- bit microcontroller. It contains a 64-Kbyte Flash memory block for code and for data.
The 64-Kbytes Flash memory can be programmed either in parallel mode or in serial mode
with the ISP capability or with software. The programming voltage is internally generated
from the standard VCC pin.
The AT89C51RD2/ED2 retains all of the features of the Atmel 80C51 with 256 bytes of
internal RAM, a 5 source 4-level interrupt controller and three timer/counters. The
AT89C51ED2 provides 2048 bytes of EEPROM for nonvolatile data storage.
In addition, the AT89C51RD2/ED2 has a Programmable Counter Array, an XRAM of 1792
bytes, a Hardware Watchdog Timer, SPI interface, Keyboard, a more versatile serial
channel that facilitates multiprocessor communication (EUART) and a speed improvement
mechanism (X2 Mode).
The fully static design of the AT89C51RD2/ED2 allows reducing system power consumption
by bringing the clock frequency down to any value, including DC, without loss of data.
The AT89C51RD2/ED2 has 2 software-selectable modes of reduced activity and an 8-bit
clock prescaler for further reduction in power consumption. In the Idle mode the CPU is
frozen while the peripherals and the interrupt system are still operating. In the Power-down
mode the RAM is saved and all other functions are inoperative.
The added features of the AT89C51RD2/ED2 make it more powerful for applications that
need pulse width modulation, high speed I/O and counting capabilities such as alarms,
motor control, corded phones, and smart card readers.
INTERUPTS
Five sources of interrupt (both external and internal).
Two External interrupts INTO and INTI are provided with push button switches: these can
also be used as general-purpose switches.
I/O (Port) Lines Four 10-pin connectors for all the 32 I/O lines.
P0,P1 and P2 Port lines are available on a 26-pin connector,
16X2 LCD & SERIAL I/O are also available.
1. Data Transfer - Block move, Exchange, Sorting, Finding largest element in an array
1.a) Data Transfer
Aim: To write an ALP to transfer block data from one memory location to another
ORG 00H
MOV R2,#04H ;No of elements = 4
MOV R0,#40H ;block 1 address
MOV R1,#50H ;block 2 address
NXT_LOC:
MOV A,@R0 ; transfer the element in present address
MOV @R1,A
INC R0 ; go to next element address of block1
INC R1 ; go to next element address of block2
DJNZ R2, NXT_LOC ; jump to NXT_LOC for next element
; Transfer till the end of an array
END
Result:
I/P:
O/P:
Aim: To write an ALP to exchange block data from one memory location to another memory
location
ORG 00H
MOV R2,#04H ;No of elements = 4
MOV R0,#40H ;block 1 address
MOV R1,#50H ;block 2 address
NXT_LOC:
MOV A,@R0 ; exchange the element in present address
XCH A,@R1
MOV @R0,A
INC R0 ; go to next element address of block1
INC R1 ; go to next element address of block2
DJNZ R2,NXT_LOC ; jump to NXT_LOC for next element
; Transfer till the end of an array
END
Result:
I/P:
O/P:
ORG 00H
MOV R7,#04H ;No of elements
DEC R7 ;no of iterations = no of elements -1
NXT_ITN: MOV R0,#40H ;array address
MOV R6,#03H ;no of exchanges = iteration no-1
NXT_NO: MOV A,@R0 ;A= present element in array
INC R0 ;
MOV B,@R0 ; B= next element in array
CJNE A,B,N_E ;compare present with next element
N_E: JNC NO_EXG ; no. are equal/ A>B exchange not required
MOV @R0,A ;exchange the elements
DEC R0
MOV @R0,B
INC R0 ; go to next number address
NO_EXG: DJNZ R6,NXT_NO ; jump to NXT_NO for next 2 numbers
; Comparison. If all the number are
; Compared go to next iteration
DJNZ R7,NXT_ITN; If all the iterations are over then exit
END
Result:
I/P:
O/P:
ORG 00H
MOV R3,#04H ; N-1 WHERE N LENGTH OF AN ARRAY
MOV R0,#40H ; array address
MOV A,@R0 ; A= present element in array
NXT_NO: INC R0
MOV B,@R0 ;B= next element in array
CJNE A,B,NT_E ; compare present with next element
SJMP AGB ;A=B
NT_E: JNC AGB ; if carry = 0, then A>B
MOV A,@R0 ;else B>A, move B to A
AGB: DJNZ R3,NXT_NO ; go to next no. In an array till last no.
MOV 50H,A ;A has the largest no save it in internal
;memory
END
Result:
I/P:
O/P:
Program:
ORG 00H
MOV R0,#40H ;address of Lower byte of 1st number
MOV R1,#50H ; address of Lower byte of 2nd number
MOV A,@R0
ADDC A,@R1 ; add lower bytes of 2 numbers
MOV 60H,A ; save the lower byte of sum in 60h INC R0
; address of higher byte of 1st number
INC R1 ; address of higher byte of 2nd number
MOV A,@R0 ; add the higher bytes of 2 numbers with
ADDC A,@R1 ; along with carry generated by lower byte
; Addition
MOV 61H,A ; save the second byte of sum in 61h
MOV 62H,#00H
JNC N_C
MOV 62H,#01H ; save the third byte of sum in 62h
N_C:
END
Result:
I/P:
O/P:
Program:
ORG 00H
Result:
I/P:
O/P:
Logic:
P2 P1 B3B1
+ P4 P3 B4B1
P6 P5 P1
+ P8 P7 B3B2
P11 P10 P9 P1
+ P13 P12 B4B2
P15 P14 P9 P1
Save in 63h 62h 61h 60h
ORG 00H
MOV A,20H ;lower byte of 1st number (say B1)
MOV B,40H ;lower byte of 2nd number (say B3)
MUL AB ; B3xB1= product of 16 bit say (P2 P1)
MOV 60H,A ;[60h]=P1
MOV 61H,B ;[61h]=P2
MOV A,21H
MOV B,40H
MUL AB
ADD A,61H
MOV 61H,A
MOV A,B
ADDC A,62H
MOV 62H,A
MOV A,#00
ADDC A,#00
MOV 63H,A
MOV A,21H
MOV B,41H
MUL AB
ADD A,62H
MOV 62H,A
MOV A,B
ADDC A,63H
MOV 63H,A
END
Result:
I/P:
O/P:
2.d Division
ORG 00H
MOV DPTR,#2000H
MOVX A,@DPTR
MOV B,A
MOV DPTR,#2001H
MOVX A,@DPTR
DIV AB
MOV DPTR,#2010H
MOVX @DPTR,A
END
Result:
I/P:
O/P:
Aim: To write an ALP to find the square & cube of a given 8 bit number
ORG 00H
MOV A,20H
MOV B,20H
MUL AB
MOV 40H,A
MOV 41H,B
MOV A,20H
MOV B,40H
MUL AB
MOV 60H,A
MOV 61H,B
MOV A,20H
MOV B,41H
MUL AB
ADD A,61H
MOV 61H,A
MOV A,B
ADDC A,62H
MOV 62H,A
END
Result:
I/P:
O/P:
3. Counters
Aim: To write an ALP to count decimal UP
ORG 00H
MOV A,40H
NXT_CNT: MOV P1,A
ADD A,#01H ; ADD A,#0FFH (FOR BINARY DOWN) , ADD
A,#99H ( FOR DECIMAL DOWN)
DA A ; DELETE THIS INSTRUCTION FOR BINARY
COUNTER
ACALL DELAY
CJNE A,41H,NXT_CNT
MOV P1,A
RET
DJNZ R1,BACK
DJNZ R0,BACK
RET
END
Result:
Y=ABC'+AB'C+AB'C'
ORG 00H
MOV C,20H
ANL C,01H
ANL C,/00H
MOV 8H,C
MOV C,20H
ANL C,/01H
ANL C,00H
ORL C,8
MOV 8,C
MOV C,20H
ANL C,/01H
ANL C,/00H
ORL C,8
MOV 8,C
END
Result:
Truth Table
A B C Y=ABC'+AB'C+AB'C'
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 0
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 0
5. Code conversion: BCD – ASCII; ASCII – Decimal; HEX - Decimal and Decimal - HEX
Aim: To write an ALP to find the ASCII code of given BCD number
ORG 0000
MOV A,40H
ANL A,#0F0H
SWAP A
ADD A,#30H
MOV 41H,A
MOV A,40H
ANL A,#0FH
ADD A,#30H
MOV 42H,A
SJMP $
END
Result:
I/P:
O/P:
Aim: To write an ALP to find the hexadecimal value of given decimal number
ORG 00H
MOV A,40H
MOV B,#0AH
DIV AB
MOV 43H,B
MOV B,#0AH
DIV AB
MOV 42H,B
MOV 41H,A
SJMP $
END
Result:
I/P:
O/P:
Aim: To write an ALP to find the hexadecimal value of given decimal number.
ORG 00H
MOV A,40H
MOV B,#10H
DIV AB
MOV R2,B
MOV B,#0AH
MUL AB
ADD A,R2
MOV 41H,A
SJMP $
END
Result:
Run 1
Run 2
6. Simple Calculator using 6 digit seven segment display and Hex Keyboard interface to 8051
Aim: To write a C program to simulate a simple calculator by interfacing 6 digit seven segment
display and key board
P0.3 chk CE / AC
-
P0.2 . = + x %
8051 P0.1 5 6 7 8 9
P0.0
0 1 2 3 4
P1.0
.
.
P1.4
{
TL0 = 0xcc;
TH0 = 0xf8;
if(df==1)
{ //P2 holding position of led from right
P2 =0x50;
P1 = dg4; //P0 holding value to be display
df=2;
}
else if(df ==2)
{
P2 =0x40;
P1 = dg3;
df=3;
}
else if(df ==3)
{
P2 =0x30;
P1 = dg2;
df=4;
}
else if(df ==4)
{
P2 =0x20;
P1 = dg1;
df=5;
}
else if(df ==5)
{
P2 =0x10;
P1 = dg5;
df=1;
}
}
void main ()
{
TMOD = 0x01;
TL0 = 0xcc;
TH0 = 0xf8;
ET0 = 1;
EA = 1;
TR0 = 1;
df = 1;
ind = 0;
operator = 0x00;
dg1 = 0x00;
dg2 = 0x00;
dg3 = 0x0;
dg4 = 0x0;
dg5= 0x0;
dg6= 0x00;
P3=0x0f;
// get first digit of the first number
do{
get_key();
}while (number>9);
num1 = number;
dg4 = LEDCODE[number]; //display first bit in unit place
dg3=0x00;
display();
delay_ms(500);
// get operator or second digit of the first number
do
{ //get next key
get_key();
}while(number>13);
if(number <10) //if it is less than 10 then it is no
{ //now that is unit value previous value is
delay_ms(500);
// get first digit of the second number
do{
get_key();
}while (number>9);
num2 = number;
dg4 = LEDCODE[number]; //display first bit in unit place
dg3=0x00;
delay_ms(500);
//get second digit of the second number or EXEC key('E')
do
{
get_key();
}while(number>10 && number != 14);//get next key
// is it continuation of second number?
if(number <10) //if it is less than 10 then it is no
{
dg4 = LEDCODE[number];//now that is unit value previous value is
dg3 = LEDCODE[num2]; //in tens place
num2= num2*10 + number; //whole no is stored in num2
// get execute key (.) or second number
do{
get_key();
}
while (number != 14); //get execute key
}
dg6 = LEDCODE[number];
dg3 = 0x0;
dg4 = 0x0;
delay_ms(500);
//0A=addition;0B=substraction;0C=multiplication;0D=division
switch (operator)
{
case 10: result1 = (num1 + num2);
break;
case 11: result1 =(int) (num1 - num2);
break;
case 12: result1 =(int) (num1 * num2);
break;
case 13: result1 = (num1 / num2);
break;
default :result1 = 5;
break;
}
if(result1<0)
{
result1=~result1+1; //displaying sign
dg5=0x40;
}
dg1 = result1 / 1000; //get thousands bit
result1=result1-(dg1*1000);
dg2 = result1 / 100; //get hundreds bit
result1=result1-(dg2*100);
dg3 = result1 / 10; //get tens bit
result1=result1-(dg3*10);
dg4 = result1 % 10; //get unit bit
dg1=LEDCODE[dg1]; //get led code values to all bits
dg2=LEDCODE[dg2];
dg3=LEDCODE[dg3];
dg4=LEDCODE[dg4];
display_res();
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
here: goto here;
// while(1)
}
void get_key(void)
{
int i;
flag = 0x00;
while(1)//flag == 0x00)
{
for(row=0;row<4;row++) //find which row is low
{ // store corresponding value in temp3
if( row == 0)
temp3=0xfe;
else if(row == 1)
temp3=0xfd;
else if(row == 2)
temp3=0xfb;
else if(row == 3)
temp3=0xf7;
P0 = temp3;
scan();
delay_ms(10);
if(flag == 0xff)
break;
} // end of for
if(flag == 0xff)
break;
} // end of while
for(i=0;i<16;i++)
{
if(scan_code[i] == res1) //find position of scan code
{ //corresponding to result value
number = i; //that value is assigned to number
break;
}
}
}// end of get_key();
void scan(void)
{
unsigned char t;
temp2 = P0;
temp2 = temp2 & 0xf0;
if(temp2 != 0xF0) //rOW SELECTION
{
delay_ms(100); //read P2 mask with 0x0f if the value is
delay_ms(100); //other than 0f then give debounce delay
delay_ms(100);
delay_ms(100);
delay_ms(100);
delay_ms(100);
temp2 = P0;
temp2 = temp2 & 0xF0; //repeat process if there is change
if(temp2 != 0xF0)
{
flag = 0xff;
res1 = temp2;
// t = (temp3 << 4) & 0xf0;
t = temp3 & 0x0F;
res1 = res1 | t;//assign the scan code in res1
}
else
{
flag = 0x00;
}
}
} // end of scan()
void delay_ms(unsigned int r)
{
for(r1=0;r1<r*4;r1++);
}
Result:
Thus the program was executed successfully and the output is seen.
P0.3
C D E F
P0.2
8 9 A B
P0.1 4 5 6 7
8051
P0.0
0 1 2 3
P1.0
P1.1
P1.2
P1.3
P2 P3
LCD Display
#include "at89c51xd2.h"
void scan(void);
void get_key(void);
void display(void);
void delay_ms(int i);
void uart_init(void);
void delay(int);
void main ()
{
lcd_init();
// configure P2 lower as input to read from rows
//P2=0x0f;
while(1)
{
get_key();
display();
P3 = 0xFF;
}
} //end of main()
void get_key(void)
{
int i;
display();
flag = 0x00;
while(flag == 0x00)
{
for(row=0;row<4;row++)
{
if( row == 0)
temp3=0xFE;
else if(row == 1)
temp3=0xFD;
else if(row == 2)
temp3=0xFB;
else if(row == 3)
temp3=0xF7;
// make coulmn high one by one output to Port P1 and
// invoke scan() function
P0 = temp3;
scan();
delay_ms(10);
// on sensing a key scan() function will make flag = 0xff
if(flag == 0xff)
break;
} // end of for
if(flag == 0xff)
break;
} // end of while
// in this for for loop scan code received which is in res1 variable is compared with
// the lookup table for array scan code[] and when a match is
// found will return the correspoding led code for the key pressed
P3 = 0x00; // Enable U21
for(i=0;i<16;i++)
{
if(scan_code[i] == res1)
{
temp1 = 0x87;
lcd_comm();
temp2 = LCD_CODE[i];
lcd_data();
result = LED_CODE[i];
break;
}
}
}// end of get_key();
temp4 = P0;
temp4 = temp4 & 0xF0; //read port2 ,mask with 0x0Fh
}
} // end of scan()
void display(void)
{
// P2 = 0x0f is done beacuse P2 upper 4 bits are used
// as address of 7 segment display
// data is output on to P0 port
// result contians
// P3=0x00;
P1 = result;
}
void delay_ms(int i)
{
int j;
for(j=0;j<i;j++);
}
Result:
Thus the program was executed successfully and the output is seen.
8051
ADC Interface
& relay control
P0 for heater
P3 LCD Interface
P2
Interfacing Diagram
Program:
//#include "D:\Keil\C51\INC\Atmel\reg51f.h"
#include<at89c51xd2.h>
#include<stdio.h>
// LCD FUNCTION PROTOTYPE
void lcd_init(void);
void lcd_comm(void);
void lcd_data(void);
void delay(int);
float adc_temp;
sbit EOC = P0^4;
void main ()
{
START_ALE = 0;
lcd_init();
temp1 = 0x80; // Display the data from first position of first line
lcd_comm(); // Command Writing
for(i=0;i<10;i++)
{
temp2 = arr1[i];
lcd_data(); // Data Writing
}
delay(200);
while(1)
{
P0 &= 0xF0; // Select the as input channel
temp_hi=adc_val>>4;
temp_hi=temp_hi & 0x0f;
if(temp_low>9)
temp_low = temp_low + 0x37;
else
temp_low = temp_low + '0';
delay(100);
temp_msg[1] = temp_hi ;
temp_msg[2] = temp_low ;
temp1 = 0x8A;
lcd_comm(); // Command Writing
temp2 = temp_hi;
lcd_data();
temp2 = temp_low;
lcd_data();
adc_temp = (int)(adc_temp*100);
i=100;
for(a=0;a<4;a++)
{
buf[a] = adc_temp / i;
adc_temp -= buf[a] * i;
buf[a] += '0';
i /= 10;
}
buf[3] = buf[2];
buf[2] = buf[1];
buf[1] = '.';
buf[4] = '\0';
temp1 = 0xC0;
lcd_comm(); // Displaying at 1st line of LCD
for(i=0;i<10;i++)
{
temp2 = arr2[i];
for(i=0;(buf[i]!='\0');i++)
{
temp2 = buf[i];
lcd_data();
}
} // end of while(1)
}
Result:
Thus the program was executed successfully and the output is seen.
9. Generate different waveforms Sine, Square, Triangular, Ramp etc. using DAC
interface to 8051; change the frequency and amplitude.
Aim: To interface DAC and to write a C program to generate sine, square, triangle and ramp
waveforms
8051
P0 DAC Interface CRO
Module
}
}
#include<at89c51xd2.h>
// variables used:
// msg : a character array contains the string to output
// on to lcd
// cptr : character pointer used to point to msg array
// required to pass to function lcd_outstr()
void delay(void);
//unsigned char xdata msg[]={"Square"};
while(1)
{
P0 = 0x0;
delay();
P0 = 0xff;
delay();
}
// output 0x7f to 0 to P0 port
for(count=0xff; count>0;count--)
{
P0=count;
}
}
}
Result:
Thus the program was executed successfully and the output is seen.
5V GND
8051
Stepper Motor
P0 Interface Stepper
Module Motor
**************************************************************************/
Program:
#include "at89c51xd2.h"
static bit Dir=0;
sbit buzzer = P0^5;
}
void delay(unsigned int x) /* Delay Routine */
{
for(;x>0;x--);
}
main()
{
unsigned char Val,i;
EA=0x1; /* Enable Interrupt flag and Interrupt 0 & Serial Interrupt */
EX0=0x1;
ES=1; /*since the monitor is using the serial interrupt it has to
be enabled*/
while(1)
{
if(Dir) //* If Dir Clockwise
{
Val = 0x08;
for(i=0;i<4;i++)
{
P0 = Val; //* Write data for clock wise direction
Val = Val>>1;
delay(575);
}
}
else // AntiClockwise Direction
{
Val = 0x01;
for(i=0;i<4;i++)
{
P0 = Val; // Write data for anticlock wise direction
Val = Val<<1;
delay(575);
}
}
}
}
12. b) DC motor
8051
DC Motor
P0 Interface DC Motor
Module
#include "at89c51xd2.h"
off_time = 1000;
on_time = 1000;
while(1)
{
Result:
Thus the program was executed successfully and the output is seen.
8051
P0 Elevator
Interface
P1 Module
void main(void)
{
AUXR = 0x10; /* Accesiing Ful XRAM */
P1 = 0x00;
P1 = 0x0f0;
while(1)
{
P0 = 0x0f; /* Configure Port as i/p */
ReqFlr = P0 | 0x0f0; /* Append '1' at the Higher nibble position */
while(ReqFlr == 0x0ff)
ReqFlr = P0 | 0x0f0; /* Read Request Floor from P0 */
ReqFlr = ~ReqFlr; /* Complement to get the proper input */
Result: Thus the program was executed successfully and the output is seen.