Microcontrollers Lab
Microcontrollers Lab
LABORATORY MANUAL
Syllabus
PART A: 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. Conditional CALL & RETURN
6. Code conversion: BCD-ASCII; ASCII-Decimal; Decimal-ASCII; HEX-Decimal and
Decimal-Hex
7. Programs to generate delay, Programs using serial port and on-Chip Timer counter.
PART B: INTERFACING
(Write C programs to interface 8051 chip to interfacing modules to develop single chip
solutions)
8. Simple calculator using 6 digit seven segment display and Hex keyboard
9. Interface to 8051
10. Alphanumeric LCD panel and Hex keyboard interface to 8051
11. External ADC and Temperature control interface to 8051
12. Generate different waveforms Sine, Square, Triangular, Ramp etc... Using DAC
13. Interface to 8051, change the frequency and amplitude
14. Stepper and DC motor control interface to 8051
15. Elevator interface to 8051
Microcontroller
External interrupts
On-chip Timer/Counter
CPU
Bus Serial
4 I/O Ports
OSC Control Port
P0 P1 P2 P3 TxD RxD
Address/Data
Introduction to Keil C
5. Click ‘Save’
6. Select Atmel
9. Click ‘No’
10. Target 1 (Red Circled) has been created
13.
14. Click ‘Save the active document’
29. If Keil is evaluation version, this message will appear. Click ‘OK’
30. You can see Registers, Code view of your program, Command Window and Memory Window
37.
38.
39.
40
41.
42.
43.
44.
45.
46.
47.
48.
53.
54.
55.
1. Write an ALP to transfer a block of data bytes from source memory to destination
memory using 8051.
Program:
MOV R0,#50H // Initialize the source memory pointer
MOV R1,#60H // Initialize the destination memory pointer
MOV R2, #05H // Initialize Iteration counter
BACK: MOV A,@R0 // Get the data from source memory pointer
MOV @R1,A // Store the data into destination memory pointer
INC R0 // Increment the source memory pointer
INC R1 // Increment the destination memory pointer
DJNZ R2, BACK // Decrement iteration count and if it is not zero, go to relative
Address and repeat the same process until count become zero.
END
Memory Window:
Before execution: After execution:
D: 0x50H: 22 AB 3D 44 55 00 D: 0x50H: 22 AB 3D 44 55 00
D: 0X60H: 22 AB 3D 44 55 00 D: 0X60H: 00 00 00 00 00 00
Program:
MOV R0,#50H // Initialize the source memory pointer
MOV R1,#60H // Initialize the destination memory pointer
MOV R2,#05H // Initialize Iteration counter
BACK: MOV A,@R0 // Get the data from source memory pointer and Load into Accumulator
XCH A,@R1 // Exchange data between Accumulator and destination memory
pointer
MOV @R0,A //Store the data into source memory pointer
INC R0 // Increment the source memory pointer
INC R1 // Increment the destination memory pointer
DJNZ R2, BACK /* Decrement iteration count and if it is not zero, go to relative
Address and repeat the same process until count become zero*/
END
Memory Window:
Before execution: After execution:
D:0x50H : 01 02 03 04 05 00 D:0x50H : 06 07 08 09 10 00
D:0X60H: 06 07 08 09 10 00 D:0X60H: 01 02 03 04 05 00
PROGRAM:
MOV R0,#50H //Initialize input1 memory pointer
MOV R1,#60H // Initialize input2 memory pointer and store output also same
memory pointer
MOV R2,#02H // Initialize iteration count
BACK: MOV A,@R0 //Get lower bytes data in first iteration, upper bytes data in
second iteration, add them with carry and store in memory
pointer2.
ADDC A,@R1
MOV @R1,A
INC R0 // Increment memory pointer1 & 2 to get upper bytes
INC R1
DJNZ R2,BACK /* Decrement iteration count and if it is not zero, go to relative
address and repeat the same process until count become zero.*/
CLR A //Store the carry
ADDC A,#00H
MOV @R1,A
END
Before execution:
D:0x50H : FA F3 00 00 00 00 D:0X60H: 02 14 00 00 00 00
After execution :
D:0x50H : FA F3 00 00 00 00 D:0X60H: FC 07 01 00 00 00
5. WRITE AN ALP TO PERFORM SUBTRACTION (16-bit by 16-bit)
PROGRAM:
MOV R0,#50H //Initialize input1 memory pointer
MOV R1,#60H // Initialize input2 memory pointer and store output also same
memory pointer
MOV R2,#02H // Initialize iteration count
BACK: MOV A,@R0 /*Get lower bytes data in first iteration, upper bytes data in
SUBB A,@R1 second iteration ,subtract from minuend to subtrahend with borrow
Before execution:
D:0x50H : FA F4 00 00 00 00 D:0X60H: 02 F5 00 00 00 00
After execution:
D:0x50H : FA F4 00 00 00 00 D:0X60H: F8 FF 01 00 00 00
Before execution :
D:0x50H : 25 26 00 00 00 00 D:0X60H: 11 11 00 00 00 00
After execution :
D:0x50H : 03 04 00 00 00 00 D:0X60H: 11 11 00 00 00 00
Program :
MOV R2,#0H // QUOTIENT
BACK: MOV R0,#50H // 50H and 51HH will have dividend
MOV R1,#60H // 60H and 61H WILL have the divider
// LOWER BYTE:
MOV A,@R0 // Get lower byte dividend
MOV B,@R1 // Get lower byte divider
SUBB A,B // Subtract from lower byte dividend to lower byte divider
MOV @R0,A // Store in same lower byte dividend
// UPPER BYTE:
INC R0 // Increment dividend memory pointer
INC R1 // Increment divider memory pointer
MOV A,@R0 // Get upper byte dividend
MOV B,@R1 // Get upper byte divider
SUBB A,B // Subtract from upper byte dividend to upper byte divider
MOV @R0,A // Store in same upper byte dividend
JC NEXT // If carry generates, go to relative address
INC R2 // Increment quotient value
SJMP BACK // Go to BACK
Program:
MOV R0, #50H // Initialize the source memory pointer
MOV R2, #05H // Initialize Iteration counter
MOV B, #0FFH // Use B Register to store smallest value and initially load
maximum value
BACK: MOV A,@R0 /* Get the data from source memory pointer and Load
into accumulator*/
CJNE A, B, LOOP // Compare data if not equal, go to relative address (LOOP)
LOOP: JNC LOOP1 // If no carry, go to relative address (LOOP1)
MOV B, A // Store smallest value into B-register
INC R0 // Increment the source memory pointer
DJNZ R2, BACK /* Decrement iteration count and if it is not zero, go to relative
address and repeat the same process until count become zero.*/
SJMP NEXT // Go to NEXT
LOOP1: INC R0 // Increment the source memory pointer
DJNZ R2,BACK /* Decrement iteration count and if it is not zero, go to relative
address and repeat the same process until count become zero.*/
NEXT: MOV 60H, B // Store the smallest value into memory location 60H.
END
Memory Window: Before execution:
D:0x50H : 22 AB 3D 44 55 00 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H : 22 AB 3D 44 55 00 D:0X60H: 22 00 00 00 00 00
9. Write an ALP to arrange N 8-bit numbers in ascending order.
Program:
MOV R2, #05H // Initialize the iteration counter
DEC R2 // Decrement the iteration count
BACK1: MOV R0, #50H // Initialize memory pointer1
MOV R1, #51H // Initialize memory pointer2
MOV A, R2 // Store outer loop count
MOV R3, A // Store inner loop count
BACK: MOV A,@R0 // Get the data from memory pointer1
MOV B,@R1 // Get the data from memory pointer2
CJNE A, B, LOOP // Compare if not equal go to relative address (LOOP)
LOOP: JC LOOP1 // If carry generates, go to relative address (LOOP1)
MOV @R0,B // Exchange the data in memory pointer
MOV @R1, A
LOOP1: INC R0 // Increment the memory pointer1
INC R1 // Increment the memory pointer2
DJNZ R3, BACK // Decrement inner loop count if not zero go to back
DJNZ R2, BACK1 // Decrement outer loop count if not zero go to back1
END
Before execution:
D:0x50H : 06 04 03 07 02 01 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H : 01 02 03 04 06 07 D:0X60H: 00 00 00 00 00 00
11. Write an ALP to check the given string of data is palindrome or not
Program:
MOV R0, #50H Initialize the source memory pointer
MOV R1, #55H Initialize the destination memory pointer
MOV R2, #03H Initialize Iteration counter
BACK: MOV A,@R0 Get the string from source memory pointer
MOV B,@R1 Get the string from destination memory pointer
CJNE A, B, LOOP Compare the string if not equal, go to LOOP
INC R0 Increment the source memory pointer
DEC R1 Decrement the destination memory pointer
DJNZ R2, BACK Decrement the iteration count if not zero,
Go to the relevant address until count becomes zero.
MOV 60H, #01H Store 01 in memory location 60h if it is palindrome
SJMP LOOP1 Go to loop1
LOOP: MOV 60H, #0FFH Store FF in memory location 60h if it is not palindrome
LOOP1: NOP No operation
END
Note:
The output will be 01 if it is palindrome.
The output will be FF if it is not palindrome
Example 1 : It is palindrome .
Before execution:
D:0x50H : 32 AB 3D 3D AB 32 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H : 32 AB 3D 3D AB 32 D:0X60H: 01 00 00 00 00 00
Example 2 : It is not palindrome .
Before execution:
D: 0x50H: 32 4B 3D 3D 4B 22 D: 0X60H: 00 00 00 00 00 00
After execution:
D: 0x50H: 22 4B 3D 3D 4B 22 D: 0X60H: FF 00 00 00 00 00
12. Write an ALP to convert given BCD to ASCII Code using 8051
Program:
MOV R0,#50H // Initialize the source memory pointer
MOV R1, #70H // Initialize the destination memory pointer
MOV R3,#03H // Initialize Iteration counter
BACK: MOV A,@R0 // Get the data from source memory pointer
MOV R2,A // Save the packed BCD
ANL A,#0F0H // Mask the lower nibble of BCD number
SWAP A // Exchange the upper and lower nibble
ORL A,#30H // Add the offset value(30h)
MOV @R1,A // Store the data into destination memory pointer
INC R1 // Increment the destination memory pointer
MOV A,R2 // Get the packed BCD.
ANL A, #0FH // Mask the lower nibble of BCD number
ORL A,#30H // Add the offset value(30h)
MOV @R1, A // Store the data into destination memory pointer
INC R1 // Increment the destination memory pointer
INC R0 // Increment the source memory pointer
DJNZ R3, BACK /* Decrement iteration count and if it is not zero, go to relative
address and repeat the same process until count become zero.*/
END
After execution:
D:0x50H : 29 38 47 00 00 00
D:0X70H: 32 39 33 38 34 37
13. Write an ALP to convert given Decimal to HEX Code using 8051
Program:
MOV R0,#50H // Initialize the source memory pointer
MOV B,@R0 // Get the Decimal number from source memory pointer
NEXT: ADD A,#1 // Increment the counter
DA A // Decimal adjustment of accumulator
INC R1 // Increment the hex value
CJNE A,B,NEXT // Compare the data if not equal, go to relative address(LOOP)
MOV 60H,R1 // Store the Hex value into output memory pointer
END
Memory Window:
Before execution:
D:0x50H : 99 00 00 00 00 00 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H : 99 00 00 00 00 00 D:0X60H: 63 00 00 00 00 00
14. Write an ALP to convert given ASCII to BCD Code using 8051 Program:
Program:
MOV R0, #50H // Initialize the source memory pointer
MOV R1, #70H // Initialize the destination memory pointer
MOV R3, #03H // Initialize Iteration counter
BACK: MOV A,@R0 // Get the data from source memory pointer
ANL A, #0FH // Mask the lower nibble of ASCII number
SWAP A // Exchange the upper and lower nibble
MOV R4, A // Store the data in temporary register
INC R0 // Initialize the source memory pointer
MOV A,@R0 // Get the data from source memory pointer
ANL A, #0FH // Mask the lower nibble of ASCII number
ORL A, R4 // Add the data
MOV @R1, A // Store the data into destination memory pointer
INC R1 // Increment the destination memory pointer
INC R0 // Increment the source memory pointer
DJNZ R3, BACK /* Decrement iteration count and if it is not zero, go to relative
address and repeat the same process until count become zero.*/
END
/* Memory Window : Before execution:
D: 0x50H : 32 39 33 38 34 37 00
D: 0X70H: 00 00 00 00 00 00 00
After execution:
D: 0x50H: 32 39 33 38 34 37 00
D: 0X70H: 29 38 47 00 00 00 00 */
15. Write an ALP to convert given HEX to Decimal Code using 8051
Program:
MOV R0, #50H // Initialize the source memory pointer
MOV R1,#62H // Initialize the destination memory pointer
MOV R2, #03H // Initialize Iteration counter
MOV A, @R0 // Get the Hex number from source memory pointer
BACK: MOV B, #10 // Load B with 10 decimal
DIV AB // Divide the number with 10
MOV @R1, B // Store the remainder in destination memory pointer
DEC R1 // Decrement the destination memory pointer
DJNZ R2, BACK /* Decrement iteration count and if it is not zero, go to relative
address and repeat the same process until count become zero.*/
END
Memory Window:
Before execution:
D:0x50H : FF 00 00 00 00 00 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H : FF 00 00 00 00 00 D:0X60H: 02 05 05 00 00 00
16. Find the number is odd or even
The output will be 01 if the number is even.
The output will be FFH if the number is odd
Program:
MOV R0,#50H // Initialize the source memory pointer
MOV A,@R0 // Get the data from source memory pointer
RRC A // Rotate accumulator right through the carry
JC LOOP1 // If carry generate, go to relative Loop1
MOV 60H,#01H // Store the number is EVEN
SJMP $ // Go to end
LOOP1: MOV 60H, #0FFH // Store the number is ODD
END
Example 1: The number is odd.
Before execution:
D:0x50H : 11 00 00 00 00 00 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H : 12 00 00 00 00 00 D:0X60H: FF 00 00 00 00 00
Example 1: The number is even. Before execution:
D:0x50H : 12 00 00 00 00 00 D:0X60H: 00 00 00 00 00 00
After execution:
D:0x50H: 12 00 00 00 00 00 D:0X60H: 01 00 00 00 00 00
Program:
ORG 0000H // Organization of code memory from 0000h
CLR 50H // Clear upper byte counter
CLR 51H // Clear lower byte counter
UP: ACALL DELAY // Call the subroutine to provide delay between two counter value
// LOWER BYTE COUNTER
MOV A, 51H // Get the current lower counter
ADD A, #01H // Add 01h with previous value to get next counter
MOV 51H,A // Store the counter in lower byte
JNZ UP // If lower count value not zero, go to relative address (UP)
// UPPER BYTE COUNTER
MOV A,50H // If lower byte reaches zero, get the current upper counter
ADD A,#01H // Add 99h to previous value to get next counter
MOV 50H,A // Store the counter in upper byte
JNZ UP // If upper count value not zero, go to relative address (UP)
SJMP UP // Repeat this counter until stop running// Provide delay
between two counter value
DELAY: MOV DPTR, #04FFH // Initialize the memory pointer
L2: INC DPTR // Increment the memory pointer
MOV A, DPL // Add higher byte and lower byte address
ORL A, DPH
JNZ L2 // If it is not zero, go to relative address (L2)
RET // Return to main program
END
Program:
MOV 50H,#0FFH // Initialize upper byte of HEX counter with FFh
MOV 51H,#0FFH // Initialize lower byte of HEX counter with FFh
UP: ACALL DELAY // Call the subroutine to provide delay between two Counter value
// LOWER BYTE COUNTER
DEC 51H // Decrement lower byte counter
MOV A, 51H // Store the lower byte counter into accumulator
JNZ UP // If lower count value not zero, go to relative address (UP)
// UPPER BYTE COUNTER
DEC 50H //Decrement upper byte counter
SJMP UP // Repeat this counter until stop running
// provide delay between two counter value
DELAY: MOV DPTR, #04FFH // Initialize the memory pointer
L2: INC DPTR // Increment the memory pointer
MOV A, DPL // Add higher byte and lower byte address
ORL A, DPH
JNZ L2 // If it is not zero, go to relative address(L2)
RET // Return to main program
END
During execution:
D:0x50H : (FFH to 00H ) (FFH to 00H) 00 00 00 00
Program:
ORG 0000H // Organization of code memory from 0000h
CLR 50H // Clear upper byte counter
CLR 51H // Clear lower byte counter
UP: ACALL DELAY // Call the subroutine to provide delay between two counter value
// LOWER BYTE COUNTER
MOV A, 51H // Get the current lower counter
ADD A, #01H // Add 01h to previous value to get next counter
DA A // Convert hex value to decimal
MOV 51H, A // Store the counter in lower byte
JNZ UP // If lower count value not zero, go to relative address (UP)
// UPPER BYTE COUNTER
MOV A, 50H // If lower byte reaches zero, get the current upper counter
ADD A, #01H // Add 99h to previous value to get next counter
DA A // Convert hex value to decimal
MOV 50H, A // Store the counter in upper byte
JNZ UP // If upper count value not zero, go to relative address (UP)
SJMP UP // Repeat this counter until stop running
// provide delay between two counter value
DELAY: MOV DPTR, #04FFH // Initialize the memory pointer
L2: INC DPTR // Increment the memory pointer
MOV A, DPL // Add higher byte and lower byte address
ORL A, DPH
Program:
ORG 0000H // Organization of code memory from 0000h
MOV 50H, #99H // Initialize upper byte of BCD counter with 99h
MOV 51H, #99H // Initialize lower byte of BCD counter with 99h
UP: ACALL DELAY // Call the subroutine to provide delay between two counter value
// LOWER BYTE COUNTER
MOV A, 51H // Get the current lower counter
ADD A, #99H // Add 99h to previous value to get next counter
DA A // Convert hex value to decimal
MOV 51H,A // Store the counter in lower byte
JNZ UP // If lower count value not zero, go to relative address (UP)
// UPPER BYTE COUNTER
MOV A, 50H // If lower byte reaches zero, get the current upper counter
ADD A, #99H // Add 99h to previous value to get next counter
DA A // Convert hex value to decimal
MOV 50H,A // Store the counter in upper byte
JNZ UP // If upper count value not zero, go to relative address (UP)
SJMP UP // Repeat this counter until stop running
// Provide delay between two counter value
DELAY: MOV DPTR, #04FFH // Initialize the memory pointer
L2: INC DPTR // Increment the memory pointer
MOV A, DPL // Add higher byte and lower byte address
ORL A, DPH
JNZ L2 // If it is not zero, go to relative address(L2)
RET // Return to main program
END
During execution: D:0x50H : (99H to 00H) (99H to 00H) 00 00 00 00
‘C’ LANGUAGE INTERFACING PROGRAMS
#include "c:\ride\inc\51\reg51.h"
unsigned char test;
unsigned int i,j;
unsigned char phase[4]={0x0b,0x07,0x0e,0x0d}; // For Clockwise
unsigned char phase1[4]={0x0d,0x0e,0x07,0x0b}; // For AntiClockwise
void main ()
{
while(1)
{
test = P1; //For Clockwise OR AntiClockwise through switch2(p1.6)
test = test & 0x40;
if(test == 0x40) // For Clockwise
for(j=0;j<4;j++)
{
P2=phase[j];
for(i=0;i<=4000;i++); //For delay
}
else
for(j=0;j<4;j++) // For AntiClockwise
{
P2=phase1[j];
for(i=0;i<=4000;i++); //For delay
}
}
}
II) DC MOTOR
#include "C:\ride\inc\51\reg51.h"
sbit RPM=P2^4;
unsigned int i,j;
void main()
{
while(1)
{
RPM=0; for(i=0;i<1000;i++);
RPM=1; for(j=0;j<1000;j++);
}
}
2. Generate different waveforms Sine, Square, Triangular, Ramp etc...Using DAC
Interface to 8051, change the frequency and amplitude
1) SQUARE
#include "c:\RIDE\INC\51\REG51.H"
idata unsigned int r;
void main()
{
while(1)
{
P0 = 0x00; for(r=0;r<400;r++);
P0 = 0xff; for(r=0;r<400;r++);
}
}
2) TRIANGLE
#include "c:\ride\inc\51\reg51.h"
#define DAC_IN P0
void main ()
{
DAC_IN =0x00;
while(1)
{
while(DAC_IN < 0xff) { DAC_IN = DAC_IN + 0x01; }
while(DAC_IN > 0x00) { DAC_IN = DAC_IN - 0x01; }
}
}
3) STAIRCASE
#include "c:\RIDE\INC\51\REG51.H"
code unsigned char array[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
void main ()
{
unsigned char i,r;
while(1)
{
for(i=0;i<5;i++)
{
P0 = array[i];
for(r=0;r<40;r++);
}
}
}
4) POSITIVE RAMP
#include "c:\RIDE\INC\51\REG51.H"
void main ()
{
while(1)
{
P0 =P0 + 0x01;
}
}
5) NEGATIVE RAMP
#include "c:\RIDE\INC\51\REG51.H"
void main ()
{
while(1)
{
P0 =P0 - 0x01;
}
}
6) SINE WAVE
#include "c:\ride\inc\51\reg51.h"
#include<math.h>
unsigned char arr[62];
float x;
unsigned int i=0;
void main()
{
P0=0xFF;
for (x = 0; x < (2 * 3.1415); x += 0.1)
{
arr[i]=127+127 * sin(x);
i++;
}
P0=0X00;
while(1)
{
for (i=0;i<62;i++)
{
P0=arr[i];
}
}
}
3. Simple calculator using 6 digit seven segment display and Hex keyboard Interface to 8051
#include "c:\ride\inc\51\reg51.h"
void scan(void);
void get_key(void);
void isr (void);
void delay_ms(unsigned int);
idata unsigned char row,col,key,dg1,dg2,dg3,dg4,dg5,dg6;
if(df==1)
{ //P2 holding position of led from right & P0 holding value to be display
P2 =0x0f; P0 = dg4; df=2;
}
else if(df ==2)
{
P2 =0x1f; P0 = dg3; df=3;
}
else if(df ==3)
{
P2 =0x2f; P0 = dg2; df=1;
}
}
void main ()
{
TMOD = 0x01; TL0 = 0xcc; TH0 = 0xf8;
ET0 = 1; EA = 1; TR0 = 1;
df = 1;
// ind = 0;
operator = 0x00;
dg2 = 0x0; dg3 = 0x0; dg4 = 0x0;
P2=0x0f;
// get the first number
do{
get_key();
}while (number>9);
num1 = number;
dg4 = LEDCODE[number]; //display first bit in unit place
dg3=0x00;
delay_ms(500);
// get operator
do
{ //get next key
get_key();
}while(number<10||number>13);
operator =number;
dg4=LEDCODE[operator]; //display in unit place
dg3 = 0x0;
// get 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 EXEC key('E')
do
{
get_key();
}while( number != 14);//get next key
dg3 = 0x0;
dg4 = 0x0;
delay_ms(500);
//operator
//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
dg2=0x40;
}
#include "C:\ride\inc\51\reg51.h"
void lcd_init(void);
void lcd_com(void);
void lcd_data(void);
void delay_ms(unsigned char);
sbit rs=P2^4;
sbit rw=P2^5;
sbit en=P2^6;
idata unsigned char temp,flag,i;
unsigned char temp1,count,r,r1;
code unsigned char msg[16]={" gopinathan"};
void main ()
{
delay_ms(25);
lcd_init();
flag =0;
temp = 0x80; //first line address of display
lcd_com();
delay_ms(5);
for(i=0;i<16;i++)
{
if(i>7 && flag==0)
{
temp = 0xC0; // second line address of display
lcd_com();
delay_ms(5);
flag = 0xff;
}
temp = msg[i];
lcd_data();
delay_ms(5);
#include "C:\ride\inc\51\reg51.h"
void delay_ms();
idata unsigned char req,preq,freq,temp,fg,i,j,r1,PP;
void main ()
{
P0 = 0x0f;
delay_ms(20);
P0 = 0xf0;
P1 = 0xFF;
freq=0xf0;
while(1)
{
req = P1;
temp = req;
req = req & 0x0f;
PP=P0;
if(req == 0x0e) //Ground floor
{
for(j =PP;j>0xf0;j--) // Lift moving down
{ P0 = j;
delay_ms(20);
}
P0 = 0xE0; // Red light off at same time green light on
PP=0xf0; // Lift current position
}
If (req == 0x0d) //First floor
{
for(j =PP;j>0xf3;j--) // Lift moving down
{ P0 = j;
delay_ms(20);
}
for(j =PP;j<0xf3;j++) // Lift moving up
{ P0 = j;
delay_ms(20);
}
P0 = 0xD3; // Red light off at same time green light on
If (req == 0x0b) // Second floor
{
for(j =PP;j>0xf6;j--) // Lift moving down
{ P0 = j;
delay_ms(20);
}
for(j =PP;j<0xf6;j++) // Lift moving up
{ P0 = j;
delay_ms(20);
}
P0 = 0XB6; // Red light off at same time green light on
PP=0xf6; // Lift current position
}
if(req == 0x07) // third floor
{
for(j =PP;j<0xf9;j++) // Lift moving up
{ P0 = j;
delay_ms(20);
}
P0 = 0x79; // Red light off at same time green light on
PP=0xf6; // Lift current position
}
} // END OF WHILE LOOP
} // END OF MAIN LOOP
5. External ADC and temperature control
#include "C:\ride\inc\51\reg51.h"
void isr(void);
void delay(unsigned char);
sbit start=P3^5;
sbit ch_sel= P3^6;
sbit disp10=P1^0;
sbit disp11=P1^1;
if(msd_flag)
{
msd_flag=0;
disp10 = 0;
disp11 = 1;
P0=LSD;
}
else
{
disp10 = 1;
disp11 = 0;
P0=MSD;
msd_flag=0xff;
}
}
void main ()
{
TMOD = 0x01; //mode1 selection
TL0 = 0x00;
TH0 = 0xee; //for every 5msec there is interrupt
ET0 = 1;
EA = 1;
TR0 = 1;
msd_flag=0x00;
P2 = 0xff; // P0 as input
P3 = 0x08; // P2 upper as input
delay(200);
ch_sel = 0x01; // channel 1 selection Wr = 1 setb p3.6
start = 0; // clr p3.5
while(1)
{
start = 1;
delay(200);
start = 0;
do
{
temp1=P3;
temp1=temp1 & 0x08;
} while(temp1 != 0x08);
delay(200);// after eoc, read the adc data from P2
adc_val = P2;// display adc result on the data field
// delay(200);
// dtemp = ((pretemp/16) <<4 ) | ((pretemp%16) & 0x0f);
MSD = LED_CODE[adc_val/0x10];
LSD = LED_CODE[adc_val%0x10];
} // end of while(1)
}
TEMPERATURE CONTROL
#include "C:\ride\inc\51\reg51.h"
void isr(void);
void scan(void);
void get_key(void);
void delay_ms(unsigned char);
idata unsigned char row,t;
code unsigned char scan_code[4]={ 0x17,0x1b,0x27,0x2b};
//code unsigned char LED_CODE[4]= {0x4f,0x66,0x06,0x5b};
code unsigned char CODE[4]= {45,50,35,40};
idata unsigned char temp3,res1,flag,i,result;
unsigned char count,pre_key;
sbit start=P3^5;
sbit relay = P3^7;
sbit ch_sel=P3^6;
sbit disp10=P1^0;
sbit disp11=P1^1;
idata unsigned char adc_val,pretemp,temp,temp1,temp2,msd_flag;
idata unsigned char settemp,MSD,LSD,fg;
xdata unsigned char table[100]={ 0x00,0x03,0x05,0x08,0x0a,0x0d,0x0f,0x11,0x14,0x16,
0x19,0x1c,0x1e,0x21,0x24,0x27,0x2a,0x2c,0x2e,0x32,
0x34,0x36,0x39,0x3c,0x3f,0x42,0x45,0x48,0x4a,0x4c,
0x4e,0x50,0x52,0x54,0x56,0x58,0x5b,0x61,0x64,0x67,
0x6a,0x6d,0x70,0x72,0x74,0x77,0x7a,0x7d,0x7f,0x82,
0x85,0x87,0x8a,0x8d,0x90,0x92,0x95,0x97,0x9a,0x9d,
0xa0,0xa2,0xa5,0xa8,0xaa,0xad,0xaf,0xb0,0xb3,0xb6,
0xb9,0xbc,0xbf,0xc1,0xc4,0xc6,0xc9,0xcc,0xcf,0xd0,
0xd2,0xd5,0xd7,0xda,0xdc,0xdf,0xe0,0xe2,0xe5,0xe7,
0xe9,0xeb,0xee,0xf1,0xf4,0xf6,0xf9,0xfc,0xff};
ET0 = 1;
EA = 1;
TR0 = 1;
fg = 0xff;
msd_flag = 0x00;
P2 = 0xff; // P2 as input
P3 = 0x08; // P3 lower as input
ch_sel = 0x00; // channel 0 selection Wr = 1 setb p3.6
count=500;
while(count>0)
count--;
relay = 1;
get_key();
// temp2 = 30;
while(1)
{
settemp = temp2;
start = 1;
count=500;
while(count>0)
count--;
start = 0;
do
{
temp1= P3;
temp1=temp1 & 0x08;
} while(temp1 != 0x08);
count=500;
while(count>0)
count--;// after eoc, read the adc data from P2
// MSD = LED_CODE[adc_val/0x10];
// LSD = LED_CODE[adc_val%0x10];
}
delay_ms(25);
delay_ms(5);
}// end of while (1)
} //end of main()
void get_key(void)
{
unsigned char j;
P1=0xf0;
flag = 0x00;
while(1)
{
if(row == 0) //check which bit is low in row
{
temp3=0xfb; //store particular value in temp3
P1 = temp3; //assign that value to P1 port
scan();
delay_ms(10);
row =1;
if(flag == 0xff)
break;
}
else
{
temp3=0xf7;
P1 = temp3;
scan();
delay_ms(10);
row = 0;
if(flag == 0xff)
break;
}
} // end of while
for(j=0;j<4;j++)
{
if(scan_code[j] == res1) //position of scan code is find
{ //according to the res1 value
temp2 = CODE[j];
break;
}
void scan(void)
{
temp2 = P1;
if(temp2 == 0x20)
{
delay_ms(30); // debounce delay
delay_ms(30);
if(temp2 == 0x20)
{
flag = 0xff;
res1 = temp2;
t = temp3 & 0x0f;
res1 = res1 | t; //store the scan code in res1
}
else
{
flag = 0x00;
}
}
else{
temp2 = P1;
if(temp2 == 0x10)
{
delay_ms(30);
delay_ms(30);
temp2 = P1;
}
}
} // end of scan()
void delay_ms(unsigned char r)
{
unsigned char r1;
for(r1=0;r1<r;r1++);
}
Instruction Set for 8051
Expected viva questions and answers
Questions
Address Bus
Microcontroller :
• A smaller computer
• On-chip RAM, ROM, I/O ports...
• Example:Motorola’s 6811, Intel’s 8051, Zilog’s Z8 and PIC 16X
Block Diagram
External Interrupts
CPU
OSC Bus
4 I/O Ports Serial
Control
P0 P2 P1 P3 TXD RXD
Addr/Data
Addressing Modes
• Register
• Direct
• Register Indirect
• Immediate
• Relative
• Absolute
• Long
• Indexed
Direct Addressing Mode
Although the entire of 128 bytes of RAM can be
accessed using direct addressing mode, it is most often
used to access RAM loc. 30 – 7FH.
MOV @R1,B
SJMP
ACALL,AJMP
LCALL,LJMP
Indexed Addressing Mode
• This mode is widely used in accessing data
elements of look-up table entries located in the
program (code) space ROM at the 8051
MOVC A,@A+DPTR
(A,@A+PC)
A= content of address A +DPTR from ROM
Note:
Because the data elements are stored in the
program (code ) space ROM of the 8051, it uses
the instruction MOVC instead of MOV. The “C”
means code.
JB Jump if bit=1
LJMP(long jump)
LJMP is an unconditional jump. It is a 3-byte instruction. It
allows a jump to any memory location from 0000 to FFFFH.
AJMP(absolute jump)
In this 2-byte instruction, It allows a jump to any memory
location within the 2k block of program memory.
SJMP(short jump)
In this 2-byte instruction. The relative address range of 00-
FFH is divided into forward and backward jumps, that is ,
within -128 to +127 bytes of memory relative to the address of
the current PC.
CALL Instructions
Another control transfer instruction is the CALL instruction,
which is used to call a subroutine.
• LCALL(long call)
This 3-byte instruction can be used to call subroutines
located anywhere within the 64K byte address space
of the 8051.
• ACALL (absolute call)
ACALL is 2-byte instruction. the target
address of the subroutine must be within 2K
byte range.
Machine cycle
• Find the machine cycle for
• (a) XTAL = 11.0592 MHz
• (b) XTAL = 16 MHz.
• Solution:
P
S Z X H X V N C
S Sign Flag (1:negativ)*
Z Zero Flag (1:Zero)
H Half Carry Flag (1: Carry from Bit 3 to Bit 4)**
P Parity Flag (1: Even)
V Overflow Flag (1:Overflow)*
N Operation Flag (1:previous Operation wassubtraction)**
C Carry Flag (1: Carry from Bit n-1 to Bit n,
with n length of operand)
DATA registers
CONTROL registers
•Timers
•Serial ports
•Interrupt system
•Analog to Digital converter Addresses 80h – FFh
•Digital to Analog converter
•Etc. Direct Addressing used to access
SPRs
Program Status Word (PSW)
Stack
• Stack-oriented data transfer
– Only one operand (direct addressing)
– SP is other operand – register indirect - implied
• Direct addressing mode must be used in Push and Pop
Note: can only specify RAM or SFRs (direct mode) to push or pop. Therefore,
to push/pop the accumulator, must use acc, not a
Stack (push,pop)
• Therefore
Push a ;is invalid
Push r0 ;is invalid
Push r1 ;is invalid
push acc ;is correct
Push psw ;is correct
Push b ;is correct
Push 13h
Push 0
Push 1
Pop 7
Pop 8
Push 0e0h ;acc
Pop 0f0h ;b
Stack in the 8051
7FH
• The register used to access Scratch pad RAM
the stack is called SP
(stack pointer) register. 30H
2FH
Bit-Addressable RAM
• The stack pointer in the 20H
8051 is only 8 bits wide, 1FH Register Bank 3
which means that it can 18H
17H
take value 00 to FFH. 10H Register Bank 2
Decimal Adjust
DA a ; decimal adjust a
Example:
mov a, #23h
mov b, #29h
add a, b ; a 23h + 29h = 4Ch (wanted 52)
DA a ; a a + 6 = 52
Bitwise Logic
Examples:
ANL AND 00001111
ORL OR ANL 10101100
00001100
XRL XOR
CPL Complement 00001111
ORL 10101100
10101111
00001111
XRL 10101100
10100011
CPL 10101100
01010011
Why Subroutines?
Interrupts
• EA : Global enable/disable.
• --- : Undefined.
• ET2 :Enable Timer 2 interrupt.
• ES :Enable Serial port interrupt.
• ET1 :Enable Timer 1 interrupt.
• EX1 :Enable External 1 interrupt.
• ET0 : Enable Timer 0 interrupt.
• EX0 : Enable External 0 interrupt.
Interrupt Process
If interrupt event occurs AND interrupt flag for that event is
enabled, AND interrupts are enabled, then:
1. Current PC is pushed on stack.
2. Program execution continues at the interrupt vector
address for that interrupt.
3. When a RETI instruction is encountered, the PC is popped
from the stack and program execution resumes where it left
off.
Interrupt Vectors
Interrupt Vector Address
System Reset 0000H
External 0 0003H
Timer 0 000BH
External 1 0013H
Timer 1 001BH
Serial Port 0023H
Timer 2 002BH
Interrupt Sources
Interrupt SFRs
Interrupt Control
16 bits 16 bits
Timer 0 Timer 1
TX (transmit)
Serial
Port RX (receive)
Embedded System
(8051 Application)
• Keyboard
• Printer
• video game player
• MP3 music players
• Embedded memories to keep configuration
information
• Mobile phone units
• Domestic (home) appliances
• Data switches
• Automotive controls
******************************