Microcontroller Lab

42
MICROCONTROLLER LAB PART I: PROGRAMMING LAB 1 Working with KEIL uVision3: Project, New uVision Project, M1, Save, Atmel, AT89C51ED2, OK, Yes File, New, (enter program code), Save, File-name=M1.ASM, Save Target1, Source Group1, Add Files to Group ‘Source Group1’, M1.ASM, Add, Close Project, Options for Target ‘Target1’ XTAL(MHz) = 11.0592 Use On-chip ROM (0 – FFFF) Use On-chip XRAM (0 – 06FF) OK Project, Options for Target ‘Target1’ Debug Use Simulator Load Application at Startup OK Project, Build Target Debug, Start/Stop Debug Session, OK Reset, Run, Stop Running View, Memory Window, C:0000H, X:0000H, I:00H View Disassembly Window (Come out of Debug to edit) ASSEMBLY LANGUAGE PROGRAMS ; 8-BIT ones complement : ORG 0000H MOV R0, #00H MOVX A,@R0 CPL A INC R0 MOVX @R0, A SJMP $ END

description

8051 Micro controller programming with Keil

Transcript of Microcontroller Lab

Page 1: Microcontroller Lab

MICROCONTROLLER LAB

PART I: PROGRAMMING

LAB 1

Working with KEIL uVision3:

Project, New uVision Project, M1, Save, Atmel, AT89C51ED2, OK, YesFile, New, (enter program code), Save, File-name=M1.ASM, SaveTarget1, Source Group1, Add Files to Group ‘Source Group1’, M1.ASM, Add, CloseProject, Options for Target ‘Target1’

XTAL(MHz) = 11.0592Use On-chip ROM (0 – FFFF)Use On-chip XRAM (0 – 06FF)OK

Project, Options for Target ‘Target1’DebugUse SimulatorLoad Application at StartupOK

Project, Build TargetDebug, Start/Stop Debug Session, OKReset, Run, Stop Running View, Memory Window, C:0000H, X:0000H, I:00HView Disassembly Window(Come out of Debug to edit)

ASSEMBLY LANGUAGE PROGRAMS

; 8-BIT ones complement: ORG 0000H

MOV R0, #00HMOVX A,@R0CPL AINC R0MOVX @R0, A

SJMP $END

; input: X:0000H = 6AH; output: X:0001H = 95H

Page 2: Microcontroller Lab

; BLOCK MOVE: WAP to transfer a block of 10 bytes of data from XRAM locations ; 0000H-0009H to XRAM locations 0010H-0019H .

ORG 0000HMOV R0,#00H ; source pointerMOV R1,#10H ; destination pointerMOV R7,#0AH ; counter

LOC1: MOVX A,@R0MOVX @R1, AINC R0INC R1DJNZ R7,LOC1

SJMP $END

; input: Put 10 bytes from X:0000H ; output: Observe the 10 bytes from X:0010H

;Assignment: Write BLOCK MOVE code without using R1.

; BLOCK EXCHANGE: WAP to exchange a block of 10 bytes of data from XRAM ; locations 0000H-0009H with the data from XRAM locations 0010H-0019H.

ORG 0000HMOV R0,#00H ; source pointerMOV R1,#10H ; destination pointerMOV R7,#0AH ; counter

LOC1: MOVX A,@R0PUSH 0E0H ; push A onto stackMOVX A,@R1 MOVX @R0,APOP 0E0HMOVX @R1,AINC R0INC R1DJNZ R7,LOC1

SJMP $END

; input: Put 10 bytes from X:0000H and 10 bytes from X:0010H ; output: Observe the exchanged bytes.

;Assignment: 1)Write BLOCK EXCHANGE code without using R1.; 2)Can you make the above program work using XCH A,@R1 ?

Page 3: Microcontroller Lab

LAB 2; BUBBLE SORT(Ascending order): WAP to sort 10 unsigned numbers(bytes) stored in; INTERNAL RAM locations 40H-49H.

ORG 0000HMOV 32H,#09H ; count = length-1MOV 33H,32H ; additional counter

LOC4: MOV R0,#40H ; pointerMOV R1,#41H ; make R1=R0+1MOV 34H,#00H ; Interchange flag

LOC2: MOV A,@R0 CLR C

SUBB A,@R1 ; compare two successive numbersJZ LOC1JC LOC1MOV A,@R0XCH A,@R1MOV @R0,AMOV 34H,#0FFH

LOC1: INC R0INC R1DJNZ 32H,LOC2MOV A,34H ; Is Interchange flag still 00H ?JZ LOC3DEC 33HMOV A,33HJZ LOC3MOV 32H,33HSJMP LOC4

LOC3: SJMP $END

; input: Put 10 bytes from I:40H ; output: Observe the 10 sorted bytes from I:40H

;Assignment: 1)Write BUBBLE SORT code for DESCENDING order.; 2)Modify the above program using R2,R3,R4 instead of 32H,33H,34H.; 3)Modify the above program without INTERCHANGE FLAG.; 4)What is the use of JZ LOC1 in the above program?

; LARGEST ELEMENT IN AN ARRAY: WAP to find the largest element in an array of 10;unsigned numbers(bytes) stored in INTERNAL RAM locations 40H-49H and store the ;result at location 30H.

ORG 0000HMOV R0,#40H ; pointerMOV R7,#0AH ; counterMOV 30H,@R0 ; get first number into 30H

LOC3: MOV A,@R0CJNE A,30H,LOC1

LOC1: JC LOC2 ; if 30H is greater, go to LOC2MOV 30H,A

LOC2: INC R0

Page 4: Microcontroller Lab

DJNZ R7,LOC3SJMP $END

; input: Put 10 bytes from I:40H ; output: Observe the largest element at I:30H

;Assignment: Modify the above program without using CJNE.

; 16-BIT ADDITION: WAP to add two 16-bit numbers ABCDH and 1234H and store ; the 16-bit result in internal RAM locations 30H and 31H.

ORG 0000HMOV A,#0CDH ; ABCDH + 1234H = BE01H ADD A,#34HMOV 30H,AMOV A,#0ABHADDC A,#12HMOV 31H,ASJMP $ END

; output: Observe the result BE01H as follows:; I:30H = 01H; I:31H = BEH

; Assignment: Modify the above program to get 24-bit result with MS byte at 32H.

; 16-BIT SUBTRACTION: WAP to subtract two 16-bit numbers ABCDH and 1234H and store ; the 16-bit result in internal RAM locations 30H and 31H.

ORG 0000HCLR CMOV A,#0CDH ; ABCDH - 1234H = 9999HSUBB A,#34HMOV 30H,AMOV A,#0ABHSUBB A,#12HMOV 31H,ASJMP $ END

; output: Observe the result 9999H as follows:; I:30H = 99H; I:31H = 99H

; Assignment: Modify the above program to get 24-bit result with MS byte at 32H.

Page 5: Microcontroller Lab

LAB 3;16-BIT MULTIPLICATION : WAP to multiply two 16-bit unsigned numbers at internal ;RAM locations 30H, 31H and 32H,33H and place the 16-bit result at locations 34H,35H.

ORG 0x0000 MOV R4,0x30 ;first number

MOV R5,0x31 MOV R6,0x32 ;second number MOV R7,0x33 LCALL MULTIPLY MOV 0x34,R6 ;16-bit result MOV 0x35,R7

SJMP $MULTIPLY:

MOV A,R7 MOV B,R5 MUL AB MOV R0,B XCH A,R7 MOV B,R4 MUL AB ADD A,R0 XCH A,R6 MOV B,R5 MUL AB ADD A,R6 MOV R6,A RET

END

;input: ; I:30H = 12H ; I:31H = 34H; I:32H = 56H; I:33H = 78H;Output: ; I:34H = 00H; I:35H = 60H

;Assignment: Modify the above program to get 32-bit result.

;16-BIT SQUARE: WAP to square a 16-bit unsigned number at internal RAM locations ;30H,31H and place the 16-bit result at locations 34H,35H.

ORG 0x0000 MOV R4,0x30 ;first number

MOV R5,0x31 MOV R6,0x30 ;second number = first number MOV R7,0x31 LCALL MULTIPLY MOV 0x34,R6 ;16-bit result MOV 0x35,R7

Page 6: Microcontroller Lab

SJMP $MULTIPLY:

MOV A,R7 MOV B,R5 MUL AB MOV R0,B XCH A,R7 MOV B,R4 MUL AB ADD A,R0 XCH A,R6 MOV B,R5 MUL AB ADD A,R6 MOV R6,A RET

END

;input: ; I:30H = 12H ; I:31H = 34H;Output: ; I:34H = 5AH; I:35H = 90H;Assignment: Modify the above program to get 32-bit result.;16-BIT CUBE: WAP to cube a 16-bit unsigned number at internal RAM locations;30H,31H and place the 16-bit result at locations 34H,35H.

ORG 0x0000 MOV R4,0x30 ;first number

MOV R5,0x31 MOV R6,0x30 ;second number = first number MOV R7,0x31 LCALL MULTIPLY

LCALL MULTIPLY ;multiply again MOV 0x34,R6 ;16-bit result MOV 0x35,R7

SJMP $MULTIPLY:

MOV A,R7 MOV B,R5 MUL AB MOV R0,B XCH A,R7 MOV B,R4 MUL AB ADD A,R0 XCH A,R6 MOV B,R5 MUL AB ADD A,R6 MOV R6,A RET

Page 7: Microcontroller Lab

END

;input: ; I:30H = 12H ; I:31H = 34H;Output: ; I:34H = 85H; I:35H = 40H

;16-BIT DIVISION: WAP to divide a 16-bit unsigned number at internal RAM locations;30H,31H by a 16-bit unsigned number at locations 32H,33H and store the 16-bit quotient ;at locations 34H,35H and the remainder at locations 36H,37H.

ORG 0x0000 MOV R4,0x32 ;divisor MOV R5,0x33 MOV R6,0x30 ;dividend MOV R7,0x31 LCALL DIVIDE MOV 0x34,R6 ;quotient MOV 0x35,R7 MOV 0x36,R4 ;remainder MOV 0x37,R5 SJMP $

DIVIDE: CJNE R4,#0x00,LOC1 CJNE R6,#0x00,LOC2 MOV A,R7 MOV B,R5 DIV AB MOV R7,A MOV R5,B RET

LOC1: CLR A XCH A,R4 MOV R0,A MOV B,#0x08

LOC4: MOV A,R7 ADD A,R7 MOV R7,A MOV A,R6 RLC A MOV R6,A MOV A,R4 RLC A MOV R4,A MOV A,R6 SUBB A,R5 MOV A,R4 SUBB A,R0 JC LOC3 MOV R4,A

Page 8: Microcontroller Lab

MOV A,R6 SUBB A,R5 MOV R6,A INC R7

LOC3: DJNZ B,LOC4 CLR A XCH A,R6 MOV R5,A RET

LOC2: MOV A,R5 MOV R0,A

MOV B,A MOV A,R6 DIV AB JB OV,LOC5 ;test overflow flag MOV R6,A MOV R5,B MOV B,#0x08

LOC8: MOV A,R7 ADD A,R7 MOV R7,A MOV A,R5 RLC A MOV R5,A JC LOC6 SUBB A,R0 JNC LOC7 DJNZ B,LOC8 RET

LOC6: CLR C SUBB A,R0

LOC7: MOV R5,A INC R7 DJNZ B,LOC8

LOC5: RET END

;input: ; dividend:; I:30H = 12H ; I:31H = 34H; divisor:; I:32H = 56H ; I:33H = 78H;Output: ; quotient:; I:34H = 00H ; I:35H = 00H; remainder:; I:36H = 12H ; I:37H = 34H;Assignment: Modify the above program to perform 16-bit by 8-bit division.

Page 9: Microcontroller Lab

LAB 4;DECIMAL(PACKED BCD) TO ASCII: WAP to convert the packed BCD byte at location 40H;to ASCII and place the result at locations 41H,42H.

ORG 0x0000 MOV A,0x40

ANL A,#0x0F ;mask off upper 4 bits ORL A,#0x30 ;convert to ASCII MOV 0x42,A MOV A,0x40 ANL A,#0xF0 ;mask off lower 4 bits SWAP A ORL A,#0x30 ;convert to ASCII MOV 0x41,A

SJMP $ END

;input: ; I:40H = 56H ;Output: ; I:41H = 35H ; I:42H = 36H;Assignment: Write the above program without using SWAP A instruction.

;ASCII TO DECIMAL(PACKED BCD): WAP to convert the two ASCII codes(hex) ( of numeric ;characters 0 to 9 ) stored at locations 40, 41H into a packed BCD byte and store the result at 42H.

ORG 0x0000 MOV A,0x40 ANL A,#0x0F SWAP A MOV R7,A MOV A,0x41 ANL A,#0x0F ORL A,R7 MOV 0x42,A

SJMP $ END

;input: ; I:40H = 35H ; I:41H = 36H ;Output: ; I:42H = 56H;Assignment: Write the above program without using ORL A,R7 instruction.

;HEX TO DECIMAL(UNPACKED BCD): WAP to convert the HEX byte at location 40H;into DECIMAL (unpacked BCD) and store the result at 41H,42H,43H.

ORG 0x0000 MOV A,0x40

MOV B,#0x0A DIV AB

Page 10: Microcontroller Lab

MOV 0x43,B ;digit3 MOV B,#0x0A DIV AB

MOV 0x42,B ;digit2 MOV 0x41,A ;digit1

SJMP $ END;input: ; I:40H = FEH ;Output: ; I:41H = 02H ; I:42H = 05H; I:43H = 04H ;DECIMAL(UNPACKED BCD) TO HEX: WAP to convert the DECIMAL (UNPACKED BCD) ;number at locations 40H,41H,42H into HEX and store the result at 43H. ORG 0x0000

MOV A,0x41 MOV B,#0x0A MUL AB MOV R7,A MOV A,0x40 MOV B,#0x64 MUL AB ADD A,R7 ADD A,0x42 MOV R7,A SWAP A ANL A,#0x0F MOV R6,A MOV A,R7 ANL A,#0x0F MOV R7,A MOV A,R6 SWAP A ANL A,#0xF0 ORL A,R7 MOV 0x43,A SJMP $ END;input: ; I:40H = 02H ; I:41H = 05H; I:42H = 04H ;output: ; I:43H = FEH

Page 11: Microcontroller Lab

LAB 5;DECIMAL UP/DOWN COUNTER WITH DELAY: WAP for decimal up/down counter on port ;P1 to count from 00 to 99 and then from 99 to 00 continuously with a delay of 25 milliseconds ;between counts. Use Timer1 in mode 1 to generate the delay.

ORG 0000START: MOV R0,#0x00LOC1: LCALL HEX_TO_DEC ;convert HEX to PACKED BCD and output thru port P1

LCALL DELAY25MS INC R0 ;up count MOV A,R0 CLR C SUBB A,#0x63 ; 99 decimal JC LOC1 MOV R0,#0x63

LOC2: MOV A,R0 SETB C SUBB A,#0x00 JC START LCALL HEX_TO_DEC LCALL DELAY25MS DEC R0 ;down count SJMP LOC2

HEX_TO_DEC: MOV A,R0

MOV B,#0x0A DIV AB MOV R1,B MOV B,#0x0A DIV AB MOV A,B SWAP A ANL A,#0xF0 ORL A,R1 MOV P1,A RET

DELAY25MS: MOV TMOD,#0x10 ;Timer1, mode 1 (16-BIT MODE) MOV TL1,#0xFE ;count = A5FE = 42494 MOV TH1,#0xA5 ; (65536 - 42494) x 1.085 uS = 25 ms SETB TR1 ;start Timer1

LOC3: JNB TF1,LOC3 ;wait till Timer1 rolls over CLR TR1 ;stop Timer1 CLR TF1 RET END

;output:; Go to 'Debug', 'Peripherals' and select the I/O port P1 and Timer1.; Run the program and observe port P1.; Also observe port P1 and Timer1 in STEPOVER MODE (Press F10 key continuously).

Page 12: Microcontroller Lab

;Assignment: Modify the program, for the up-count mode, by using DA A instruction and not ;using the subroutine HEX_TO_DEC. The down-count mode remains as it is.

;PROGRAMMING SERIAL PORT: WAP to send the message "MSRIT" serially at ;9600 baud rate.

ORG 0x0000 MOV TMOD,#0x20 ;Timer1, mode 2 (auto-reload) MOV TH1,#0xFD ;9600 baud rate MOV SCON,#0x40 ;serial mode 1: 1 start bit, 8-bit data, 1 stop bit SETB TR1 ;start Timer1

MOV DPTR,#MYDATALOC2: CLR A

MOVC A,@A+DPTR JZ LOC1

ACALL SEND INC DPTR SJMP LOC2

LOC1: SJMP $

SEND: MOV SBUF,AHERE: JNB TI, HERE

CLR TI RET

MYDATA: DB "MSRIT",0x00

END;output:; Run the program and proceed as follows:; View, Serial Window, UART #0; Observe the message "MSRIT" on the Serial Window.

;Assignment: 1)Modify the program for 4800 baud rate and without using ; double(or single) inverted commas for the message.; 2)Modify the program to send “MSRIT” exactly 5 times, with each line of the ; Serial Window containing “MSRIT” only once.

Page 13: Microcontroller Lab

LAB 6Alphanumeric LCD panel and Hex keypad(3x8) input interface to 8051:

Write a C program to display the pressed key's key code on the On-board LCD of the ESA MCB51. Use the LCD library to write on the LCD.

Connection : Connect the interface module to 26 pin FRC connector J7 of ESA MCB51.Output : Displays the pressed key's key code on the On-board LCD of the ESA MCB51

C program:

#include <REG51xD2.H>#include "lcd.h"unsigned char getkey();main(){ unsigned char key; InitLcd(); /* Initialise LCD */ WriteString("Key Pressed="); /* Display msg on LCD */ while(1) { GotoXY(12,0); /* Set Cursor Position */

key = getkey(); /* Call Getkey method */ } }

unsigned char getkey() { unsigned char i,j,k,indx,t;

Page 14: Microcontroller Lab

P0 = 0xff; /* Make all columns high, also P0 is input port */ P2 = 0x00; /* P2 as Output port */ indx = 0x00; /* Index for storing the first value */ for(i=0x01; i<=0x04; i<<=1) { P2 = ~ i; /* write data to rows */

t = ~ P0; /* Read columns connected to P0*/

if(t > 0) /* If key press is true */ { for(j=0; j<=7; j++) /* Check for 8 columns */ { t >>= 1;

if(t == 0) /* if get pressed key*/ { k = indx + j; /* Display that by converting to Ascii */ t = k >>4;

t += 0x30; WriteChar(t); /* Write upper nibble */

t = k & 0x0f; if (t > 9) t += 0x37; else t += 0x30; WriteChar(t); /* write lower nibble */

return(indx + j); /* Return index of the key pressed */ }

} } indx += 8; /* If no key pressed, then increment index */

} }

Assignment:1)Why is P0 initialized to 0xff ?2)Why is resetting of ESA MCB 51 essential everytime before downloading the program into the flash of 89C51ED2?3)Which is the actual step wherein downloading takes place?4)Modify the above program without inverting the variable i inside the “for” loop.

Page 15: Microcontroller Lab

/* Header file for supporting On-Board LCD of ESA MCB 51 */sbit RS = P3^7; //Register selectsbit RW = P3^6; //Read (1) or Write (0) sbit E = P3^5; //LCD Enablevoid InitLcd();/*Description : Initializes LCD for minimum settings

i.e.Func Set-8-bit data, 2lines of display, 5x8 dots clear display, disp on & normal cursor & address of first line

*/void LcdCmdWrite(unsigned char);/*Description : Writes a command to Instruction Register.Argument : Command Value.*/unsigned char LcdCmdRead();/*Description : Reads LCD's Instruction Register.Return Vale : Instruction Register content */void LcdDataWrite(unsigned char);/*Description : Writes a Value into RAM.Argument : Character value . (INPUT)*/void ClrLcd();/*Description : Clear LCD. */void WriteChar(unsigned char);/*Description : output a character in current Cursor.Argument : Character value - Character to be output in LCD. (INPUT)*/void WriteString(char *);/*Description : Output character string in current Cursor.Argument : Character string's Pointer - Character to be output in LCD. (INPUT)*/void BusyWait();/*Description : Wait & Check LCD to be ready.*/void LcdDelay(unsigned int);void HomeCursor(void);/*Description : Move Cursor to first Column.*/void SetCursorType(unsigned char type);Description : Decide Cursor type.Argument : type - Cursor type(INPUT)

type=0- No Cursor; type=1-Normal Cursor; type=2-No Cursor, Blink type=3-Normal Cursor & Blink

void ShiftCursor(unsigned char dir, unsigned char num);Description : Shift to Left and Right current Cursor.Argument : dir - Decide direction to be Shift.(INPUT) dir !=0 -> Right Shift,

dir == 0 -> Left Shiftvoid GotoXY(unsigned char x, unsigned char y);Description : Move Cursor to X Column, Y Row.Argument : x - Column to move(INPUT), y - Row to move(INPUT), Note : LCD to be offered by ESA is '2*16' Dimension, so Row(Argument y) is not above 1.

Page 16: Microcontroller Lab

LAB 7Simple Calculator using Hex Keypad(3x8) and 4-digit Seven segment Display interfaces to 8051:

Write a C program to perform Single Digit Calculation using (i) the Hex Keypad(3x8) interface,

and (ii) the 4-digit Seven segment Display interface,both connected to ESA MCB 51 . Assume each of the two numbers to be between 0 and 9 and theresult ( of the 4 basic operations) to be of 2 digits.

Connections : Keypad interface to 26 pin FRC connector J7 on ESA MCB 51, 7 segment Display interface to J1, J2 and J4 using the cable given by ESA.

Working procedure: Enter number1 ( 0-9 ) Enter Opcode ( +,-,/,*)

if you give '+' it displays 'A' (Add) '-' it displays '-' (Subtract) '*' it displays 'M' (Multiply) '/' it displays 'd' (Divide)

Enter number2 ( 0-9)Press '=' -> displays result Press 'AC' to clear the displayRepeat the same .

C program:

#include <REG51xD2.H>void DispChar(unsigned char ch);void ClrLED();unsigned char getkey();unsigned char getnum();unsigned char getOp();

sbit Clk = P3^4; /* Clock line for 7 segment display */sbit Dat = P0^0; /* Data line for 7 segment display */

main(){ unsigned char tmp=0x0ff,n1=0,n2,Op,Res; unsigned char NumTab[10] = { 0x0c0,0x0f9,0x0a4,0xb0,0x99,0x92,0x82,0x0f8,0x80,0x90 }; unsigned char OpTab[4] = { 0x88,0x0Bf,0xc8,0x0a1}; bit Neg=0; ClrLED(); /* Clear 7 segment display */ while(1) { Neg = 0; /* Negative flag */

n1=getnum(); /* Get 1st number */if(n1==0x10)

{ClrLED(); /*if pressed key is AC then Clear LED*/continue;

}DispChar(NumTab[n1]); /* Display number */

Op = getOp() - 0x0B; /* Get Opcode. 0x0b is keycode of '+'(see keyboard schematics)*/

if(Op==0x10){

ClrLED(); /*if pressed key is AC then Clear LED*/

Page 17: Microcontroller Lab

continue;}

DispChar(OpTab[Op]);n2=getnum(); /* Get 2nd number */

if(n2==0x10){

ClrLED(); /*if pressed key is AC then Clear LED*/continue;

} DispChar(NumTab[n2]);

while(getkey()!=0x13); /* wait for '=' key */ClrLED();switch(Op) /* Perform corresponding operation */{ case 0: Res = n1 + n2; break; case 1: if(n2>n1) /* check for negativity */ { Neg = 1;

Res = n2 - n1; break;}Res = n1 - n2;

break; case 2: Res = n1 * n2; break; case 3: Res = n1 / n2; break;}DispChar(NumTab[Res%10]); /* Display number */DispChar(NumTab[Res/10]);if(Neg) /* if negative result display '-' */ DispChar(0x0Bf);while(getkey()!= 0x10); /* wait for 'AC' key */{

ClrLED();}

}}

void DispChar(unsigned char ch) /* Routine to display char on 7 segment */{ unsigned char i,tmp; P0=0x00; P2=0xff; for(i=0;i<8;i++) /* for all bits */ { tmp = ch & 0x80;

if(tmp) /* write data depending on MSB */ Dat = 1; else Dat = 0;Clk = 0; /* Give Clk Pulse for synchronization */Clk = 1;ch = ch << 1; /* Get next bit */

}}void ClrLED(){

Page 18: Microcontroller Lab

unsigned char i; for(i=0;i<4;i++) DispChar(0xff); /* 0xff for clear segment */}

unsigned char getkey() { unsigned char i,j,indx,t; P0 = 0xff; /* Make all columns high, also P0 is input port */ P2 = 0x00; /* P2 as Output port */ indx = 0x00; /* Index for storing the first value */ while(1) { for(i=0x01; i<=0x04; i<<=1) { P2 = ~ i; /* write data to rows */

t = ~ P0; /* Read columns connected to P0*/

if(t > 0) /* If key press is true */ { for(j=0; j<=7; j++) /* Check for 8 columns */ { t >>= 1;

if(t == 0) /* if get pressed key*/ { return(indx + j); /* Return index of the key pressed */ }

} } indx += 8; /* If no key pressed, then increment index */

} }}

unsigned char getnum() /* Method for getting number */{ unsigned char tmp; while(1) { tmp = getkey(); if(tmp < 0x0a || tmp==0x10) /* if pressed key is number, return */ return(tmp); }

}

unsigned char getOp() /* Method for getting Operator */{ unsigned char tmp; while(1) { tmp = getkey(); if((tmp > 0x0a && tmp <0x0f)|| tmp==0x10)

/* if pressed key is a Operator, return */ return(tmp); }}--------------------------------Assignment:1)The function “getkey()” used above, and the function “getkey()” used in HEX KEYPAD INTERFACE (LAB 6), have 3 differences between them. Identify them. Give reasons why they have been made different in LAB 7. 2)Explain the use of the four, 74LS164 ICs in the 7-Segment Display Interface module.

Page 19: Microcontroller Lab

3)Each of the three 10-pin Connectors J1, J2, and J4, corresponds to different port lines of 89C51ED2. Identify those port lines. How many of those port lines are multifunction lines in 89C51ED2 ?

LAB 8

Stepper Motor Interface to 8051:

Write a C program to rotate the stepper motor connected to ESA MCB51, clockwise, and to change the direction , it should use P3.2/INTO* interrupt available as a button on ESA MCB51. Display “Clockwise”/”Anti-clockwise” on the on-board LCD.

Connection : Connect the interface module to 26 pin FRC connector J7 of ESA MCB51.Output: Whenever you run the program the motor rotates clockwise.

If you want to change the direction, press the interrupt button ( P3.2/INTO*). When you press the button, INT0* interrupts the main program and changes the direction of the motor .

Description: The stepper motor interface uses four transistor pairs (SL100 & 2N3055) in a darlington pair

configuration. Each darlington pair is used to excite a particular winding of the motor connected. The inputs to these transistors are from the P0 I/O lines of the ESA MCB51. P0 lower nibble(P0.0 to P0.3) are the four lines brought out to the interface module. The free-wheeling diode across each winding protects the transistor from switching transients.

The stepper motor is reversible with a torque of 3 kg-cm. The power requirement is +5V DC @ 1.2 A current per winding at full torque. The step angle is 1.8* i.e., for every single excitation, the motor shaft rotates by 1.8*. For the motor to rotate one full revolution(360*), the number of steps required is 200.

C program:

#include <REG51xD2.H>#include "lcd.h"

static bit Dir=1; /* clockwise direction */

void delay(unsigned int x) /* Delay Routine */{ for(;x>0;x--);}

void ChangeDir(void) interrupt 0 /* Int Vector at 000BH, Reg Bank 1 */{ Dir = ~Dir; /* Complement the Direction flag */ ClrLcd(); if(Dir) { WriteString("Clockwise"); delay(32000); } else {WriteString("Anti-Clockwise");

delay(32000); }}

Page 20: Microcontroller Lab

main(){ unsigned char Val,i; IEN0 = 0x81 ; /* IEN0 (of 89C51ED2, SFR address 0xA8) is the equivalent of IE reg of 8051.

EX0 =1: Enable External interrupt 0 (INT0). Also EA=1. */

P0 = 0x00; /* P0 is made output */ InitLcd(); /* Initialise LCD */ WriteString("Clockwise"); /* Write to LCD */ while(1) { if(Dir) /* If Dir Clockwise */

{ Val = 0x11; for(i=0;i<4;i++) { P0 = Val; /* Write data for clock wise direction*/ Val = Val<<1; /* left shift for clockwise */ delay(575); }}else /* AntiClockwise Direction */{ Val = 0x88; for(i=0;i<4;i++) { P0 = Val; /* Write data for anticlock wise direction*/ Val = Val>>1; /* right shift for anticlockwise */ delay(575); } }

}}

Assignment:

1)Modify the above program such that the shaft rotates clockwise at 60 RPM for one minute and then stops. (You can use timers to generate accurate delays).

2)Modify the given program such that the shaft rotates anti-clockwise at 40 RPM for 30 seconds, and then rotates clockwise at 3 RPM for 90 seconds and then stops.

Page 21: Microcontroller Lab

LAB 9

Elevator Interface to 8051:

Write a C program to operate the elevator as follows: Initially, the elevator is at GF(Ground Floor) and all service requests are cleared. When a service

request is detected, the elevator moves to that floor and it stays at that floor until a request from another floor is made. When such a request is detected, it moves to that floor. The program will be in the loop and to come out, press RESET key.

Connection : Connect the interface module to 26 pin FRC connector J7 of ESA MCB51.Output: Can be viewed on the Elevator Interface.

C program:

#include <REG51xD2.H>

Page 22: Microcontroller Lab

void delay(unsigned int x){ for(;x>0;x--);}main(){ unsigned char Flr[9] = {0xff,0x00,0x03,0xff,0x06,0xff,0xff,0xff,0x09}; unsigned char FClr[9] = {0xff,0xE0,0xD3,0xff,0xB6,0xff,0xff,0xff,0x79}; unsigned char ReqFlr,CurFlr = 0x01,i,j;

P0 = 0x00; P0 = 0xf0; while(1) { P1 = 0x0f; ReqFlr = P1 | 0xf0; while(ReqFlr == 0xff)

ReqFlr = P1 | 0xf0; /* Read Request Floor from P1 */ReqFlr = ~ReqFlr; if(CurFlr == ReqFlr) /* If Request floor is equal to Current Floor */{ P0 = FClr[CurFlr]; /* Clear Floor Indicator */ continue; /* Go up to read again */}else if(CurFlr > ReqFlr) /* If Current floor is > request floor */{ i = Flr[CurFlr] - Flr[ReqFlr]; /* Get the no of floors to travel */ j = Flr[CurFlr]; for(;i>0;i--) /* Move the indicator down */ { P0 = 0xf0|j; j--; delay(25000); }}else /* If Current floor is < request floor */{ i = Flr[ReqFlr] - Flr[CurFlr]; /* Get the no of floors to travel */ j = Flr[CurFlr]; for(;i>0;i--) /* Move the indicator Up */ { P0 = 0xf0 | j; j++; delay(25000); }}CurFlr = ReqFlr; /* Update Current floor */P0 = FClr[CurFlr]; /* Clear the indicator */

}}

Assignment:

Modify the above program to perform the following: If a service request is not detected at any floor(1st, 2nd, or 3rd) for a time = 25 x t where t = delay generated

by the delay function in the program listing shown, the elevator should automatically move to the GF and wait at GF for any further request.

Page 23: Microcontroller Lab

LAB 10DC Motor Interface to 8051:

Write a C program to run the DC motor connected to ESA MCB51, at around 45 rps (for a pedestal value of 110 ). It should also measure the speed of the motor and display it on the on-board LCD using P3.2/INTO* interrupt available as a button on ESA MCB51.

Connection : Connect the interface module to 26 pin FRC connector J7 of ESA MCB51.Output: Run the program.

Wait for about 10 sec. for the motor to settle at the desired speed. Press the interrupt button (P3.2/INTO*). Observe the speed on the on-board LCD.

Description: The PWM technique is used to vary the speed of the DC motor (12V, 4W motor). The frequency of the

pulses is 120 Hz. Keeping frequency constant, the width of the pulses is used to change the speed. When the PW is minimum, the speed is minimum and when the PW is maximum, the speed is maximum (3600 rpm = 60 rps). The ramp and pedestal technique is used to change the PW and thereby the speed.

The different sections of the circuit are:1. Rectifier and Regulator2. Ramp generator3. DAC4. Motor drive section5. Timing and reference voltage generator6. Feedback section

DAC: This is where uC is active. The digital input to this 8-bit DAC is given from port P0. Depending on the digital value, the output of DAC varies and this analog value is the pedestal that controls the PW.Motor drive section: The ramp (120 Hz frequency) and the pedestal voltage are given to the two inputs of a comparator, the output of which is a PWM. Under program control, the PW can be changed and hence the speed of the motor.Timing and reference voltage generator: The 555 timer IC gives a square pulse with on time (high pulse) of 1 sec. This pulse is given to port pin P1_1 as a time reference to measure the speed of the motor. Feedback section: Square pulses obtained at the output represent the speed. These pulses are connected to P1_0. When P1_1 is high for 1 sec, the number of pulses on P1_0 will give the count, i.e., speed, in rps.

C program: #include <REG51xD2.H>#include "lcd.h"unsigned char pedestal,count1,count,rx;

void speed(){

while( P1_1); /* wait for P1_1 to become 0 */ while(!P1_1); /* wait for P1_1 to become 1 */ count=0x00; do { while( P1_0); while(!P1_0);

count++ ; /* increment after every pulse at P1_0 */

}while( P1_1); /* When P1_1 is high for 1 sec, the number of pulses on P1_0 will give the count i.e., speed,

in rotations per second. */

Page 24: Microcontroller Lab

return;}

void display() /* convert the count to ASCII for LCD display */{ if (count > 0x09)

{ count1 = count/10; } rx = (count - count1*10); GotoXY(0x08,0x0); WriteChar(count1 + 0x30); GotoXY(0x09,0x0); WriteChar(rx + 0x30); return;

}

void ISR(void) interrupt 0 /* Int Vector at 000BH, Reg Bank 1 */{

speed(); display();

}

void main(){

IEN0 = 0x81; /* IEN0 (of 89C51ED2, SFR address 0xA8) is the equivalent of IE reg of 8051.

EX0 =1: Enable External interrupt 0 (INT0). Also EA=1. */

P1 = 0xff; /* make P1 as input */ pedestal = 110; /* pedestal for 45 rps (= 2700 rpm)

(15 < pedestal < 150)

pedestal rps 15 57 110 45

150 32 */

P0=pedestal; /* send pedestal thru P0 */ InitLcd(); WriteString("SPEED = "); GotoXY(0x0c,0x0); WriteString("rps"); while(1); /* wait for interrupt INT0* */

}

Assignment:

1)It is found that for a pedestal value of 205, the speed is 5 rps. Will the above program display this properly? If not, modify the program to display it properly.2)Connect the DC motor interface to ESA MCB51. Switch on the power supply. The DC motor immediately starts running at maximum speed even without running the program. Why is this? Can you make the initial speed zero? If so how?3)What should be the pedestal values for 34 rps < speed < 51 rps ?

Page 25: Microcontroller Lab

LAB 11

16 –Channel ADC (ADC 0816 ) interface to 8051:

Write a C program which continuously reads the ADC output and displays it on the on-board LCD.

Connections : Connect the interface module to 26 pin FRC connector J7 of ESA MCB51.Connect the centre-tap of the 10K pot. to IN0 of ADC interface, and the other twoends to +5V and GND.Connect +12V to ADC interface.

Output: Run the program. Vary the pot. and observe the Digital value on the on-board LCD.

C program: #include <REG51xD2.H>#include "lcd.h"

sbit SOC = P0^5;sbit EOC = P2^0;sbit READ = P0^6;

unsigned char channel,result,x;

void ascii(x) /* convert to ASCII for LCD */{

Page 26: Microcontroller Lab

if (x > 9)WriteChar(x + 0x37);

elseWriteChar(x + 0x30);

}void convert(void) /* convert analog to digital */{

SOC = 1; /* Assert SOC */ SOC = 0; /* Pull down SOC */

while(EOC == 1); /* Wait for the EOC to become LOW */

READ = 1; /* make RD =1 */ result = P1; /* Read the Digital Value */

READ = 0; /* make RD = 0 */}

void main(){ InitLcd();

P1 = 0xff; /* P1 as input port */ EOC = 1; /* EOC AS input */

channel = 0; /* select one of the 16 input channels: IN0 to IN15) */P0 = channel;

while(1)

{ convert();

WriteString("Digital value=");GotoXY(0x0e,0);

ascii(result >> 4); /* display MS hex digit */

ascii(result & 0x0f); /* display LS hex digit */

LcdDelay(400); } }

Assignment:1) Write a C program to perform the following:

Connect two analog voltages V1,V2 (0 < V1 < 5V, 0 < V2 < 5V) to two different channels of the ADC interface. The program should convert each analog voltage to digital, and display their average on the on-board LCD. The display should update continuously as we vary V1 and/or V2.

Ex:Analog Voltage Digital Value

V1 = 2.5V (Channel 1) 7FHV2 = 4.5V (Channel 12) E5H

Average value = B2H

2) In the program given, inside the “main” function, insert one statement : P0 = 0xff; (just above InitLcd(); ). Run the program. The program looks as if it is working exactly the same way. But it is not. Check properly and identify the difference (or the coincidence).

Page 27: Microcontroller Lab

3) In the program given, “LcdDelay(400)” is used not to take care of the conversion time of ADC 0816. Then why is it used? Also, in the program, where and how is the conversion time of the ADC taken care ?

LAB 12

Dual DAC interface to 8051:

Write 3 different C programs to generate the following 3 waveforms at XOUT and YOUT on the Dual DAC interface connected to ESA MCB51. Also display the type of waveform (Square, Triangular, Sine) on the on-board LCD.

SINE WAVE SQUARE WAVE TRIANGULAR WAVE

A=4V A=4V A=4V f = 1/T = 1kHz T1=0.4mS, T2=0.6mS T1=10mS, T2=20mS(100Hz < f < 1kHz) (100Hz < f < 10kHz) (20Hz < f < 50Hz)

Connections : Connect the interface module to 26 pin FRC connector J7 of ESA MCB51.Connect +12V , -12V to Dual DAC interface.

Output: Run the program. Observe the waveforms at XOUT or YOUT on a CRO.

Description: There are 2, 8-bit DACs provided, based on DAC 0800. Ports P0 and P1 drive XOUT and YOUT

respectively. The analog output from the DACs are given to op-amps which act as I-to-V converters. Two 10k pots provide the offset balancing of op-amps.

The reference voltage needed for the DACs is obtained from the on-board voltage regulator uA723. The voltage generated by this regulator is about 8V. The outputs from the DACs vary between 0 and 5V corresponding to values between 00H and FFH. Different waveforms can be observed at the op-amp outputs depending on the digital input patterns.

Page 28: Microcontroller Lab

C program for Sine wave:

#include <REG51xD2.H>#include "lcd.h"

void delay() /* delay routine */{

TR1 = 1;while(TF1 == 0);TR1 = 0;TF1 = 0;return;

}void main(){ unsigned char i; unsigned int table[24] = {102,129,154,175,191,201,205,201,191,175,154,129, 102, 76, 51, 30, 14, 4, 0, 4, 14, 30, 51, 76 };

/*---------------------------------------------------- Value = A(1+sin0) x 25.6 A = peak-to-peak value of sine wave. 0 = angle in degrees (take at steps of 15*)

---------------------------------------------------------- */

InitLcd(); WriteString("Sine"); TMOD = 0x10; /* Timer 1 in mode 1 */ while(1) { for(i=0;i<24;i++) {

P0 = table[i]; P1 = table[i];

TL1 = 0xf0; TH1 = 0xff;

/*-------------------------------------------- To find count n in mode 1 use:

n = [65536 – (Period of sine wave / No. of entries) / 1.085 uS ] + 23 = [65536 – (1 mS / 24) /1.085 uS] + 23 = 65520 = FFF0H

The extra addition of 23 is to account for software overhead. --------------------------------------------------*/

delay(); } }}

Page 29: Microcontroller Lab

C program for Square wave:

#include <REG51xD2.H>#include "lcd.h"

void delay() /* delay routine */{

TR1 = 1;while(TF1 == 0);TR1 = 0;TF1 = 0;return;

}

void main(){ InitLcd(); WriteString("Square"); TMOD = 0x10; /* Timer 1 in mode 1 */

while(1) {

P0 = 0xcd; /* for 4V */ P1 = 0xcd; TL1 = 0xa6; TH1 = 0xfe;/*----------------------------------------------------

n = [65536 - delay / 1.085 uS] + 23 = [65536 – 0.4 mS / 1.085 uS] + 23 = 65190 = FEA6H----------------------------------------------------------- */

delay(); P0 = 0x00; /* for 0V */ P1 = 0x00; TL1 = 0xee; /* n = [65536 - 0.6 mS / 1.085 uS] + 23=65006 = FDEEH */ TH1 = 0xfd; delay(); }}

Page 30: Microcontroller Lab

C program for Triangular wave:#include <REG51xD2.H>#include "lcd.h"

void delay() /* delay routine */{

TR1 = 1;while(TF1 == 0);TR1 = 0;TF1 = 0;return;

} void main(){ unsigned char i; InitLcd(); WriteString("Triangular"); TMOD = 0x10; /* Timer 1 in mode 1 */ while(1) { for(i=0;i<0xcd;i++) /* rising ramp */ {

P0 = i; P1 = i;

TL1 = 0xea;TH1 = 0xff;

/*----------------------------------- n = [65536 – (Ramp interval time / No. of steps) / 1.085 uS] + 23 = [ 65536 – (10 mS/205) / 1.085 uS] + 23 ; 205 steps required for 4V. = 65514 = FFEAH------------------------------------------- */

delay();}

for(i=0xcd;i>0x00;i--) /* falling ramp */{

P0 = i; P1 = i;

TL1 = 0xbd; TH1 = 0xff;

/*----------------------------------- n = [65536 – (20 mS/205) / 1.085 uS] + 23 = 65469 = FFBDH------------------------------------------- */

delay(); } }}

Assignment:1)Write 4 separate programs to generate the following 4 waveforms:

1) Sine wave: A = 5V, f = 500Hz2) Square wave: A = 5V, f = 500Hz (T1 = T2)3)Triangular wave: A = 5V, f = 33Hz (T1 = T2)4) Sawtooth wave: A = 5V, f = 50Hz

Page 31: Microcontroller Lab

MICROCONTROLLER LAB

LAB EXAM QUESTION BANK

1a) Block Move : WAP to transfer a block of 10 bytes of data from XRAM locations 0000H-0009H to XRAM locations 0010H-0019H.1b) Alphanumeric LCD panel and Hex keypad(3x8) input interface to 8051: Write a C program to display the pressed key's key code on the on-board LCD of the ESA MCB51. Use the LCD library to write on the LCD.

2a) Block Exchange : WAP to exchange a block of 10 bytes of data from XRAM locations 0000H-0009H with the data from XRAM locations 0010H-0019H. 2b) Elevator Interface to 8051: Write a C program to operate the elevator as follows:

Initially, the elevator is at GF(Ground Floor) and all service requests are cleared. When a service request is detected, the elevator moves to that floor and it stays at that floor until a request from another floor is made. When such a request is detected, it moves to that floor. The program will be in the loop and to come out, press RESET key.

3a) Bubble Sort(Ascending order): WAP to sort 10 unsigned numbers(bytes) stored in INTERNAL RAM locations 40H-49H using Bubble sort algorithm.3b) Stepper Motor Interface to 8051: Write a C program to rotate the stepper motor connected to ESA MCB51, clockwise, and to change the direction , it should use P3.2/INTO* interrupt available as a button on ESA MCB51. Display “Clockwise”/ “Anti-clockwise” on the on-board LCD.

4a) Largest Element in an array: WAP to find the largest element in an array of 10 unsigned numbers(bytes) stored in INTERNAL RAM locations 40H-49H and store the result at location 30H. 4b) DC Motor Interface to 8051: Write a C program to run the DC motor connected to ESA MCB51, at around 45 rps (for a pedestal value of 110 ). It should also measure the speed of the motor and display it on the on-board LCD using P3.2/INTO* interrupt available as a button on ESA MCB51.

5a) 16-Bit Addition : WAP to add two 16-bit numbers ABCDH and 1234H and store the 16-bit result in internal RAM locations 30H and 31H. 5b) 16 –Channel ADC (ADC 0816 ) interface to 8051: Write a C program which continuously reads the ADC output and displays it on the on-board LCD.

Page 32: Microcontroller Lab

6a) 16-BIT Multiplication: WAP to multiply two 16-bit unsigned numbers at internal RAM locations 30H, 31H and 32H,33H and place the 16-bit result at locations 34H,35H. 6b) Dual DAC Interface: WAP to generate a SINE WAVE of peak-to-peak amplitude = 5V(0 to 5V), and f = 500Hz.

7a) 16-Bit Square: WAP to square a 16-bit unsigned number at internal RAM locations 30H,31H and place the 16-bit result at locations 34H,35H. 7b) Alphanumeric LCD panel and Hex keypad(3x8) input interface to 8051: Write a C program to display the pressed key's key code on the on-board LCD of the ESA MCB51. Use the LCD library to write on the LCD

8a) 16-Bit Cube: WAP to cube a 16-bit unsigned number at internal RAM locations 30H, 31H and place the 16-bit result at locations 34H,35H.8b) Elevator Interface to 8051: Write a C program to operate the elevator as follows:

Initially, the elevator is at GF(Ground Floor) and all service requests are cleared. When a service request is detected, the elevator moves to that floor and it stays at that floor until a request from another floor is made. When such a request is detected, it moves to that floor. The program will be in the loop and to come out, press RESET key.

9a) Decimal(Packed BCD) to ASCII: WAP to convert the packed BCD byte at location 40H to ASCII and place the result at locations 41H,42H.9b) Dual DAC Interface: WAP to generate a SQUARE WAVE of peak-to-peak amplitude = 5V(0 to 5V), and f = 500Hz(T1=T2).

10a) ASCII To Decimal(Packed BCD): WAP to convert the two ASCII codes(hex) ( of numeric characters 0 to 9 ) stored at locations 40, 41H into a packed BCD byte and store the result at 42H.10b) 16 –Channel ADC (ADC 0816 ) interface to 8051: Write a C program which continuously reads the ADC output and displays it on the on-board LCD

Page 33: Microcontroller Lab

11a) Hex To Decimal(Unpacked BCD): WAP to convert the HEX byte at location 40H into DECIMAL (unpacked BCD) and store the result at 41H,42H,43H.11b) DC Motor Interface to 8051: Write a C program to run the DC motor connected to ESA MCB51, at around 45 rps (for a pedestal value of 110 ). It should also measure the speed of the motor and display it on the on-board LCD using P3.2/INTO* interrupt available as a button on ESA MCB51.

12a) Decimal(Unpacked BCD To Hex: WAP to convert the Decimal(Unpacked BCD) number at locations 40H,41H,42H into HEX and store the result at 43H.12b) 16 –Channel ADC (ADC 0816 ) interface to 8051: Write a C program which continuously reads the ADC output and displays it on the on-board LCD.

13a) Decimal up/down counter with delay: WAP for decimal up/down counter on port P1 to count from 00 to 99 and then from 99 to 00 continuously with a delay of 25 milliseconds between counts. Use Timer1 in mode 1 to generate the delay.13b) Stepper Motor Interface to 8051: Write a C program to rotate the stepper motor connected to ESA MCB51, clockwise, and to change the direction , it should use P3.2/INTO* interrupt available as a button on ESA MCB51. Display “Clockwise”/ “Anti-clockwise” on the on-board LCD.

14a) Programming Serial Port: WAP to send the message "MSRIT" serially at 9600 baud rate.14b) Dual DAC Interface: WAP to generate a TRIANGULAR WAVE of peak-to-peak amplitude = 5V(0 to 5V), and f = 33Hz (T1=T2).

15a) 16-Bit Subtraction : WAP to subtract two 16-bit numbers and store the 16-bit result in internal RAM locations 30H and 31H.

Page 34: Microcontroller Lab

15b) Stepper Motor Interface to 8051: Write a C program to rotate the stepper motor connected to ESA MCB51, clockwise, and to change the direction , it should use P3.2/INTO* interrupt available as a button on ESA MCB51. Display “Clockwise”/ “Anti-clockwise” on the on-board LCD.