8051 asm Codes

;This program adds value 3 to the ACC ten times
MOV A,#0 ;A=0, clear ACC
MOV R2,#10 ;load counter R2=10
AGAIN: ADD A,#03 ;add 03 to ACC
DJNZ R2,AGAIN ;repeat until R2=0,10 times
MOV R5,A ;save A in R5
;Write a program to (a) load the accumulator with the value 55H, and
;(b) complement the ACC 700 times
MOV A,#55H ;A=55H
MOV R3,#10 ;R3=10, outer loop count
NEXT: MOV R2,#70 ;R2=70, inner loop count
AGAIN: CPL A ;complement A register
DJNZ R2,AGAIN ;repeat it 70 times
DJNZ R3,NEXT
;Find the sum of the values 79H, F5H, E2H. Put the sum in registers
R0 (low byte) and R5 (high byte).
MOV A,#0 ;A=0
MOV R5,A ;clear R5
ADD A,#79H ;A=0+79H=79H
JNC N_1 ;if CY=0, add next number
INC R5 ;if CY=1, increment R5
N_1: ADD A,#0F5H ;A=79+F5=6E and CY=1
JNC N_2 ;jump if CY=0
INC R5 ;if CY=1,increment R5 (R5=1)
N_2: ADD A,#0E2H ;A=6E+E2=50 and CY=1
JNC OVER ;jump if CY=0
INC R5 ;if CY=1, increment 5
OVER: MOV R0,A ;now R0=50H, and R5=02
;LCALL Example
ORG 0
BACK: MOV A,#55H ;load A with 55H
MOV P1,A ;send 55H to port 1
LCALL DELAY ;time delay
MOV A,#0AAH ;load A with AA (in hex)
MOV P1,A ;send AAH to port 1
LCALL DELAY
SJMP BACK ;keep doing this indefinitely
;———- this is delay subroutine ————
ORG 300H ;put DELAY at address 300H
DELAY: MOV R5,#0FFH ;R5=255 (FF in hex), counter
AGAIN: DJNZ R5,AGAIN ;stay here until R5 become 0
RET ;return to caller (when R5 =0)
END
;Use PUSH/POP in Subroutine
ORG 0
BACK: MOV A,#55H ;load A with 55H
MOV P1,A ;send 55H to p1
MOV R4,#99H
MOV R5,#67H
LCALL DELAY ;time delay
MOV A,#0AAH ;load A with AA
MOV P1,A ;send AAH to p1
LCALL DELAY
SJMP BACK ;keeping doing this
;——-this is the delay subroutine——
ORG 300H
DELAY: PUSH 4 ;push R4
PUSH 5 ;push R5
MOV R4,#0FFH;R4=FFH
NEXT: MOV R5,#0FFH;R5=FFH
AGAIN: DJNZ R5,AGAIN
DJNZ R4,NEXT
POP 5 ;POP into R5
POP 4 ;POP into R4
RET ;return to caller
END
;The following code will continuously send out to port 0 the
;alternating value 55H and AAH
BACK: MOV A,#55H
MOV P0,A
ACALL DELAY
MOV A,#0AAH
MOV P0,A
ACALL DELAY
SJMP BACK
;——-this is the delay subroutine——
DELAY: MOV R5,#0FFH ;R5=255 (FF in hex), counter
AGAIN: DJNZ R5,AGAIN ;stay here until R5 become 0
RET ;return to caller (when R5 =0)
;Port 0 is configured first as an input port by writing 1s to it, and then
;data is received from that port and sent to P1
MOV A,#0FFH ;A=FF hex
MOV P0,A ;make P0 an i/p port
;by writing it all 1s
BACK: MOV A,P0 ;get data from P0
MOV P1,A ;send it to port 1
SJMP BACK ;keep doing it
;The following code will continuously send out to port 0 the
;alternating value 55H and AAH
MOV A,#55H
BACK: MOV P1,A
ACALL DELAY
CPL A
SJMP BACK
;——-this is the delay subroutine——
DELAY: MOV R5,#0FFH ;R5=255 (FF in hex), counter
AGAIN: DJNZ R5,AGAIN ;stay here until R5 become 0
RET ;return to caller (when R5 =0)
;Port 1 is configured first as an input port by writing 1s to it, then data
;is received from that port and saved in R7 and R5
MOV A,#0FFH ;A=FF hex
MOV P1,A ;make P1 an input port
;by writing it all 1s
MOV A,P1 ;get data from P1
MOV R7,A ;save it to in reg R7
ACALL DELAY ;wait
MOV A,P1 ;another data from P1
MOV R5,A ;save it to in reg R5
;——-this is the delay subroutine——
DELAY: MOV R5,#0FFH ;R5=255 (FF in hex), counter
AGAIN: DJNZ R5,AGAIN ;stay here until R5 become 0
RET ;return to caller (when R5 =0)
;Write the following programs.
;Create a square wave of 50% duty cycle on bit 0 of port 1.
HERE: SETB P1.0 ;set to high bit 0 of port 1
LCALL DELAY ;call the delay subroutine
CLR P1.0 ;P1.0=0
LCALL DELAY
SJMP HERE ;keep doing it
;;Another way to write the above program is:
;HERE: CPL P1.0 ;set to high bit 0 of port 1
;LCALL DELAY ;call the delay subroutine
;SJMP HERE ;keep doing it
;——-this is the delay subroutine——
DELAY: MOV R5,#0FFH ;R5=255 (FF in hex), counter
AGAIN: DJNZ R5,AGAIN ;stay here until R5 become 0
RET ;return to caller (when R5 =0)
;Write a program to perform the following:
;(a) Keep monitoring the P1.2 bit until it becomes high
;(b) When P1.2 becomes high, write value 45H to port 0
;(c) Send a high-to-low (H-to-L) pulse to P2.3
SETB P1.2 ;make P1.2 an input
MOV A,#45H ;A=45H
AGAIN: JNB P1.2,AGAIN ; get out when P1.2=1
MOV P0,A ;issue A to P0
SETB P2.3 ;make P2.3 high
CLR P2.3 ;make P2.3 low for H-to-L
;Assume that bit P2.3 is an input and represents the condition of an
;oven. If it goes high, it means that the oven is hot. Monitor the bit
;continuously. Whenever it goes high, send a high-to-low pulse to port
;P1.5 to turn on a buzzer.
HERE: JNB P2.3,HERE ;keep monitoring for high
SETB P1.5 ;set bit P1.5=1
CLR P1.5 ;make high-to-low
SJMP HERE ;keep repeating
;A switch is connected to pin P1.7. Write a program to check the status
;of SW and perform the following:
;(a) If SW=0, send letter ‘N’ to P2
;(b) If SW=1, send letter ‘Y’ to P2
SETB P1.7 ;make P1.7 an input
AGAIN: JB P1.2,OVER ;jump if P1.7=1
MOV P2,’N’ ;SW=0, issue ‘N’ to P2
SJMP AGAIN ;keep monitoring
OVER: MOV P2,#’Y’ ;SW=1, issue ‘Y’ to P2
SJMP AGAIN ;keep monitoring
;A switch is connected to pin P1.7. Write a program to check the status
;of SW and perform the following:
;(a) If SW=0, send letter ‘N’ to P2
;(b) If SW=1, send letter ‘Y’ to P2
;Use the carry flag to check the switch status.
SETB P1.7 ;make P1.7 an input
AGAIN: MOV C,P1.2 ;read SW status into CF
JC OVER ;jump if SW=1
MOV P2,#’N’ ;SW=0, issue ‘N’ to P2
SJMP AGAIN ;keep monitoring
OVER: MOV P2,#’Y’ ;SW=1, issue ‘Y’ to P2
SJMP AGAIN ;keep monitoring
;Example 4-7
;A switch is connected to pin P1.0 and an LED to pin P2.7. Write a
;program to get the status of the switch and send it to the LED
SETB P1.7 ;make P1.7 an input
AGAIN: MOV C,P1.0 ;read SW status into CF
MOV P2.7,C ;send SW status to LED
SJMP AGAIN ;keep repeating
;Example 5-1
;Write code to send 55H to ports P1 and P2, using
;(a) their names (b) their addresses
;Solution :
;(a)
MOV A,#55H ;A=55H
MOV P1,A ;P1=55H
MOV P2,A ;P2=55H
;(b) From Table 5-1, P1 address=80H; P2 address=A0H
MOV A,#55H ;A=55H
MOV 80H,A ;P1=55H
MOV 0A0H,A ;P2=55
;Example 5-2
;Show the code to push R5 and A onto the stack and then pop them
;back them into R2 and B, where B = A and R2 = R5
;Solution:
PUSH 05 ;push R5 onto stack
PUSH 0E0H ;push register A onto stack
POP 0F0H ;pop top of stack into B
;now register B = register A
POP 02 ;pop top of stack into R2
;now R2=R6
;Example 5-3
;Write a program to copy the value 55H into RAM memory locations
;40H to 41H using
;(a) direct addressing mode, (b) register indirect addressing mode
;without a loop, and (c) with a loop
;Solution:
;(a)
MOV A,#55H ;load A with value 55H
MOV 40H,A ;copy A to RAM location 40H
MOV 41H,A ;copy A to RAM location 41H
;(b)
MOV A,#55H ;load A with value 55H
MOV R0,#40H ;load the pointer. R0=40H
MOV @R0,A ;copy A to RAM R0 points to
INC R0 ;increment pointer. Now R0=41h
MOV @R0,A ;copy A to RAM R0 points to
;(c)
MOV A,#55H ;A=55H
MOV R0,#40H ;load pointer.R0=40H,
MOV R2,#02 ;load counter, R2=3
AGAIN: MOV @R0,A ;copy 55 to RAM R0 points to
INC R0 ;increment R0 pointer
DJNZ R2,AGAIN ;loop until counter = zero
;Example 5-4
;Write a program to clear 16 RAM locations starting at RAM address 60H
;Solution:
CLR A ;A=0
MOV R1,#60H ;load pointer. R1=60H
MOV R7,#16 ;load counter, R7=16
AGAIN: MOV @R1,A ;clear RAM R1 points to
INC R1 ;increment R1 pointer
DJNZ R7,AGAIN ;loop until counter=zero
;Example 5-5
;Write a program to copy a block of 10 bytes of data from 35H to 60H
;Solution:
MOV R0,#35H ;source pointer
MOV R1,#60H ;destination pointer
MOV R3,#10 ;counter
BACK: MOV A,@R0 ;get a byte from source
MOV @R1,A ;copy it to destination
INC R0 ;increment source pointer
INC R1 ;increment destination pointer
DJNZ R3,BACK ;keep doing for ten bytes
;Example 5-6
;In this program, assume that the word “USA” is burned into ROM
;locations starting at 200H. And that the program is burned into ROM
;locations starting at 0. Analyze how the program works and state
;where “USA” is stored after this program is run.
;Solution:
ORG 0000H ;burn into ROM starting at 0
MOV DPTR,#200H ;DPTR=200H look-up table addr
CLR A ;clear A(A=0)
MOVC A,@A+DPTR ;get the char from code space
MOV R0,A ;save it in R0
INC DPTR ;DPTR=201 point to next char
CLR A ;clear A(A=0)
MOVC A,@A+DPTR ;get the next char
MOV R1,A ;save it in R1
INC DPTR ;DPTR=202 point to next char
CLR A ;clear A(A=0)
MOVC A,@A+DPTR ;get the next char
MOV R2,A ;save it in R2
Here: SJMP HERE ;stay here
;Data is burned into code space starting at 200H
ORG 200H
MYDATA:DB “USA”
END ;end of program
;Example 5-8
;Write a program to get the x value from P1 and send x2 to P2,
;continuously
;Solution:
ORG 0
MOV DPTR,#300H ;LOAD TABLE ADDRESS
MOV A,#0FFH ;A=FF
MOV P1,A ;CONFIGURE P1 INPUT PORT
BACK: MOV A,P1 ;GET X
MOVC A,@A+DPTR ;GET X SQAURE FROM TABLE
MOV P2,A ;ISSUE IT TO P2
SJMP BACK ;KEEP DOING IT
ORG 300H
XSQR_TABLE: DB 0,1,4,9,16,25,36,49,64,81
END
;Example 5-10
;Write a program to toggle P1 a total of 200 times. Use RAM
;location 32H to hold your counter value instead of registers R0 – R7
;Solution:
MOV P1,#55H ;P1=55H
MOV A, P1
MOV 32H,#200 ;load counter value into RAM loc 32H
LOP1: CPL A ;toggle P1
MOV P1, A
ACALL DELAY
DJNZ 32H,LOP1 ;repeat 200 times
;——-this is the delay subroutine——
DELAY: MOV R5,#0FFH ;R5=255 (FF in hex), counter
AGAIN: DJNZ R5,AGAIN ;stay here until R5 become 0
RET ;return to caller (when R5 =0)
;Example 5-24
;A switch is connected to pin P1.7. Write a program to check the status
;of the switch and make the following decision.
;(a) If SW = 0, send “0” to P2
;(b) If SW = 1, send “1“ to P2
;Solution:
SW EQU P1.7
MYDATA EQU P2
HERE: MOV C,SW
JC OVER
MOV MYDATA,#’0′
SJMP HERE
OVER: MOV MYDATA,#’1′
SJMP HERE
END
;Example 5-27
;Assume that the on-chip ROM has a message. Write a program to
;copy it from code space into the upper memory space starting at
;address 80H. Also, as you place a byte in upper RAM, give a copy to
;P0.
;Solution:
ORG 0
MOV DPTR,#MYDATA
MOV R1,#80H ;access the upper memory
B1: CLR A
MOVC A,@A+DPTR ;copy from code ROM
MOV @R1,A ;store in upper memory
MOV P0,A ;give a copy to P0
JZ EXIT ;exit if last byte
INC DPTR ;increment DPTR
INC R1 ;increment R1
SJMP B1 ;repeat until last byte
EXIT: SJMP $ ;stay here when finished
;—————
ORG 300H
MYDATA: DB “The Promise of World Peace”,0
END
;Assume that RAM locations 40 – 44H have the following values.
;Write a program to find the sum of the values. At the end of the
;program, register A should contain the low byte and R7 the high byte.
;40 = (7D)
;41 = (EB)
;42 = (C5)
;43 = (5B)
;44 = (30)
;Solution:
MOV R0,#40H ;load pointer
MOV R2,#5 ;load counter
CLR A ;A=0
MOV R7,A ;clear R7
AGAIN: ADD A,@R0 ;add the byte ptr to by R0
JNC NEXT ;if CY=0 don’t add carry
INC R7 ;keep track of carry
NEXT: INC R0 ;increment pointer
DJNZ R2,AGAIN ;repeat until R2 is zero
;Write a program to add two 16-bit numbers. Place the sum in R7 and
;R6; R6 should have the lower byte.
;Solution:
CLR C ;make CY=0
MOV A, #0E7H ;load the low byte now A=E7H
ADD A, #8DH ;add the low byte
MOV R6, A ;save the low byte sum in R6
MOV A, #3CH ;load the high byte
ADDC A, #3BH ;add with the carry
MOV R7, A ;save the high byte sum
;Assume that 5 BCD data items are stored in RAM locations starting
;at 40H, as shown below. Write a program to find the sum of all the
;numbers. The result must be in BCD.
;40=(71)
;41=(11)
;42=(65)
;43=(59)
;44=(37)
;Solution:
MOV R0,#40H ;Load pointer
MOV R2,#5 ;Load counter
CLR A ;A=0
MOV R7,A ;Clear R7
AGAIN: ADD A,@R0 ;add the byte pointer to by R0
DA A ;adjust for BCD
JNC NEXT ;if CY=0 don’t accumulate carry
INC R7 ;keep track of carries
NEXT: INC R0 ;increment pointer
DJNZ R2,AGAIN ;repeat until R2 is 0
;Assume that register A has packed BCD, write a program to convert
;packed BCD to two ASCII numbers and place them in R2 and R6.
MOV A,#29H ;A=29H, packed BCD
MOV R2,A ;keep a copy of BCD data
ANL A,#0FH ;mask the upper nibble (A=09)
ORL A,#30H ;make it an ASCII, A=39H(‘9’)
MOV R6,A ;save it
MOV A,R2 ;A=29H, get the original data
ANL A,#0F0H ;mask the lower nibble
RR A ;rotate right
RR A ;rotate right
RR A ;rotate right
RR A ;rotate right
ORL A,#30H ;A=32H, ASCII char. ’2’
MOV R2,A ;save ASCII char in R2
;Example 9-7
;Find the delay generated by timer 0 in the following code, using both
;of the Methods of Figure 9-4. Do not include the overhead due to
;instruction.
CLR P2.3 ;Clear P2.3
MOV TMOD,#01 ;Timer 0, 16-bitmode
HERE: MOV TL0,#3EH ;TL0=3Eh, the low byte
MOV TH0,#0B8H ;TH0=B8H, the high byte
SETB P2.3 ;SET high timer 0
SETB TR0 ;Start the timer 0
AGAIN: JNB TF0,AGAIN ;Monitor timer flag 0
CLR TR0 ;Stop the timer 0
CLR TF0 ;Clear TF0 for next round
CLR P2.3
;Solution:
;(a) (FFFFH – B83E + 1) = 47C2H = 18370 in decimal and 18370 ×
;1.085 us = 19.93145 ms
;(b) Since TH – TL = B83EH = 47166 (in decimal) we have 65536 –
;47166 = 18370. This means that the timer counts from B38EH to
;FFFF. This plus Rolling over to 0 goes through a total of 18370 clock
;cycles, where each clock is 1.085 us in duration. Therefore, we have
;18370 × 1.085 us = 19.93145 ms as the width of the pulse.
;Example 9-8
;Modify TL and TH in Example 9-7 to get the largest time delay
;possible. Find the delay in ms. In your calculation, exclude the
;overhead due to the instructions in the loop.
;Solution:
;To get the largest delay we make TL and TH both 0. This will count
;up from 0000 to FFFFH and then roll over to zero.
CLR P2.3 ;Clear P2.3
MOV TMOD,#01 ;Timer 0, 16-bitmode
HERE: MOV TL0,#0 ;TL0=0, the low byte
MOV TH0,#0 ;TH0=0, the high byte
SETB P2.3 ;SET high P2.3
SETB TR0 ;Start timer 0
AGAIN: JNB TF0,AGAIN ;Monitor timer flag 0
CLR TR0 ;Stop the timer 0
CLR TF0 ;Clear timer 0 flag
CLR P2.3
;Making TH and TL both zero means that the timer will count from
;0000 to FFFF, and then roll over to raise the TF flag. As a result, it
;goes through a total Of 65536 states. Therefore, we have delay =
;(65536 – 0) × 1.085 us = 71.1065ms.
;Example 9-9
;The following program generates a square wave on P1.5 continuously
;using timer 1 for a time delay. Find the frequency of the square
;wave if XTAL = 11.0592 MHz. In your calculation do not
;include the overhead due to Instructions in the loop.
MOV TMOD,#10;Timer 1, mod 1 (16-bitmode)
AGAIN: MOV TL1,#34H ;TL1=34H, low byte of timer
MOV TH1,#76H ;TH1=76H, high byte timer
SETB TR1 ;start the timer 1
BACK: JNB TF1,BACK ;till timer rolls over
CLR TR1 ;stop the timer 1
CPL P1.5 ;comp. p1. to get hi, lo
CLR TF1 ;clear timer flag 1
SJMP AGAIN ;is not auto-reload
;Solution:
;Since FFFFH – 7634H = 89CBH + 1 = 89CCH and 89CCH = 35276
;clock count and 35276 × 1.085 us = 38.274 ms for half of the
;square wave. The frequency = 13.064Hz.
;Also notice that the high portion and low portion of the square wave
;pulse are equal. In the above calculation, the overhead due to all
;the instruction in the loop is not included.
;Example 9-10
;Assume that XTAL = 11.0592 MHz. What value do we need to load
;the timer’s register if we want to have a time delay of 5 ms
;(milliseconds)? Show the program for timer 0 to create a pulse width
;of 5 ms on P2.3.
;Solution:
;Since XTAL = 11.0592 MHz, the counter counts up every 1.085 us.
;This means that out of many 1.085 us intervals we must make a 5 ms
;pulse. To get that, we divide one by the other. We need 5 ms / 1.085
;us = 4608 clocks. To Achieve that we need to load into TL and TH
;the value 65536 – 4608 = EE00H. Therefore, we have TH = EE and TL = 00.
CLR P2.3 ;Clear P2.3
MOV TMOD,#01 ;Timer 0, 16-bitmode
HERE: MOV TL0,#0 ;TL0=0, the low byte
MOV TH0,#0EEH ;TH0=EE, the high byte
SETB P2.3 ;SET high P2.3
SETB TR0 ;Start timer 0
AGAIN: JNB TF0,AGAIN ;Monitor timer flag 0
CLR TR0 ;Stop the timer 0
CLR TF0 ;Clear timer 0 flag
;Example 9-11
;Assume that XTAL = 11.0592 MHz, write a program to generate a
;square wave of 2 kHz frequency on pin P1.5.
;Solution:
;This is similar to Example 9-10, except that we must toggle the bit to
;generate the square wave. Look at the following steps.
;(a) T = 1 / f = 1 / 2 kHz = 500 us the period of square wave.
;(b) 1 / 2 of it for the high and low portion of the pulse is 250 us.
;(c) 250 us / 1.085 us = 230 and 65536 – 230 = 65306 which in hex
;is FF1AH.
;(d) TL = 1A and TH = FF, all in hex. The program is as follow.
MOV TMOD,#01 ;Timer 0, 16-bitmode
AGAIN: MOV TL1,#1AH ;TL1=1A, low byte of timer
MOV TH1,#0FFH ;TH1=FF, the high byte
SETB TR1 ;Start timer 1
BACK: JNB TF1,BACK ;until timer rolls over
CLR TR1 ;Stop the timer 1
CLR P1.5 ;Clear timer flag 1
CLR TF1 ;Clear timer 1 flag
SJMP AGAIN ;Reload timer
;Example 9-12
;Assume XTAL = 11.0592 MHz, write a program to generate a square
;wave of 50 kHz frequency on pin P2.3.
;Solution:
;Look at the following steps.
;(a) T = 1 / 50 = 20 ms, the period of square wave.
;(b) 1 / 2 of it for the high and low portion of the pulse is 10 ms.
;(c) 10 ms / 1.085 us = 9216 and 65536 – 9216 = 56320 in decimal,
;and in hex it is DC00H.
;(d) TL = 00 and TH = DC (hex).
MOV TMOD,#10H ;Timer 1, mod 1
AGAIN: MOV TL1,#00 ;TL1=00,low byte of timer
MOV TH1,#0DCH ;TH1=DC, the high byte
SETB TR1 ;Start timer 1
BACK: JNB TF1,BACK ;until timer rolls over
CLR TR1 ;Stop the timer 1
CLR P2.3 ;Comp. p2.3 to get hi, lo
SJMP AGAIN ;Reload timer, mode 1 isn’t auto-reload
;Example 9-14
;Assume XTAL = 11.0592 MHz, find the frequency of the square
;wave generated on pin P1.0 in the following program
MOV TMOD,#20H ;T1/8-bit/auto reload
MOV TH1,#5 ;TH1 = 5
SETB TR1 ;start the timer 1
BACK: JNB TF1,BACK ;till timer rolls over
CPL P1.0 ;P1.0 to hi, lo
CLR TF1 ;clear Timer 1 flag
SJMP BACK ;mode 2 is auto-reload
;Solution:
;First notice the target address of SJMP. In mode 2 we do not need to
;reload TH since it is auto-reload. Now (256 – 05) × 1.085 us =
;251 × 1.085 us = 272.33 us is the high portion of the pulse. Since
;it is a 50% duty cycle square wave, the period T is twice that; as
;a result T = 2 × 272.33 us = 544.67 us and the frequency =
;1.83597 kHz
;Example 9-15
;Find the frequency of a square wave generated on pin P1.0.
;Solution:
MOV TMOD,#2H ;Timer 0, mod 2 (8-bit, auto reload)
MOV TH0,#0
AGAIN: MOV R5,#250 ;multiple delay count
ACALL DELAY
CPL P1.0
SJMP AGAIN
DELAY: SETB TR0 ;start the timer 0
BACK: JNB TF0,BACK ;stay timer rolls over
CLR TR0 ;stop timer
CLR TF0 ;clear TF for next round
DJNZ R5,DELAY
RET
;T = 2 ( 250 × 256 × 1.085 us ) = 138.88ms, and frequency = 72 Hz
;Example 9-18
;Assuming that clock pulses are fed into pin T1, write a program
;for counter 1 in mode 2 to count the pulses and display the state
;of the TL1 count on P2, which connects to 8 LEDs.
;Solution:
MOV TMOD,#01100000B ;counter 1, mode 2, C/T=1 external pulses
MOV TH1,#0 ;clear TH1
SETB P3.5 ;make T1 input
AGAIN: SETB TR1 ;start the counter
BACK: MOV A,TL1 ;get copy of TL
MOV P2,A ;display it on port 2
JNB TF1,Back ;keep doing, if TF = 0
CLR TR1 ;stop the counter 1
CLR TF1 ;make TF=0
SJMP AGAIN ;keep doing it
;Write a program for the 8051 to transfer letter “A” serially at 4800
;baud, continuously.
;Solution:
MOV TMOD,#20H ;timer 1,mode 2(auto reload)
MOV TH1,#-6 ;4800 baud rate
MOV SCON,#50H ;8-bit, 1 stop, REN enabled
SETB TR1 ;start timer 1
AGAIN: MOV SBUF,#”A” ;letter “A” to transfer
HERE: JNB TI,HERE ;wait for the last bit
CLR TI ;clear TI for next char
SJMP AGAIN ;keep sending A
;Write a program for the 8051 to transfer “YES” serially at 9600
;baud, 8-bit data, 1 stop bit, do this continuously
;Solution:
MOV TMOD,#20H ;timer 1,mode 2(auto reload)
MOV TH1,#-3 ;9600 baud rate
MOV SCON,#50H ;8-bit, 1 stop, REN enabled
SETB TR1 ;start timer 1
AGAIN: MOV A,#”Y” ;transfer “Y”
ACALL TRANS
MOV A,#”E” ;transfer “E”
ACALL TRANS
MOV A,#”S” ;transfer “S”
ACALL TRANS
SJMP AGAIN ;keep doing it
;serial data transfer subroutine
TRANS: MOV SBUF,A ;load SBUF
HERE: JNB TI,HERE ;wait for the last bit
CLR TI ;get ready for next byte
RET
;Write a program for the 8051 to receive bytes of data serially, and
;put them in P1, set the baud rate at 4800, 8-bit data, and 1 stop bit
;Solution:
MOV TMOD,#20H ;timer 1,mode 2(auto reload)
MOV TH1,#-6 ;4800 baud rate
MOV SCON,#50H ;8-bit, 1 stop, REN enabled
SETB TR1 ;start timer 1
HERE: JNB RI,HERE ;wait for char to come in
MOV A,SBUF ;saving incoming byte in A
MOV P1,A ;send to port 1
CLR RI ;get ready to receive next byte
SJMP HERE ;keep getting data
;Example 10-5
;Assume that the 8051 serial port is connected to the COM port of
;IBM PC, and on the PC, we are using the terminal.exe program to
;send and receive data serially. P1 and P2 of the 8051 are connected
;to LEDs and switches, respectively. Write an 8051 program to (a)
;send to PC the message “We Are Ready”, (b) receive any data send
;by PC and put it on LEDs connected to P1, and (c) get data on
;switches connected to P2 and send it to PC serially. The program
;should perform part (a) once, but parts (b) and (c) continuously, use
;4800 baud rate.
;Solution:
ORG 0
MOV P2,#0FFH ;make P2 an input port
MOV TMOD,#20H ;timer 1, mode 2
MOV TH1,#0FAH ;4800 baud rate
MOV SCON,#50H ;8-bit, 1 stop, REN enabled
SETB TR1 ;start timer 1
MOV DPTR,#MYDATA ;load pointer for message
H_1: CLR A
MOVC A,@A+DPTR ;get the character
JZ B_1 ;if last character get out
ACALL SEND ;otherwise call transfer
INC DPTR ;next one
SJMP H_1 ;stay in loop
B_1: MOV a,P2 ;read data on P2
ACALL SEND ;transfer it serially
ACALL RECV ;get the serial data
MOV P1,A ;display it on LEDs
SJMP B_1 ;stay in loop indefinitely
;—-serial data transfer. ACC has the data——
SEND: MOV SBUF,A ;load the
H_2: JNB TI,H_2 ;stay here until last bit gone
CLR TI ;get ready for next
RET ;return to caller
;—-Receive data serially in ACC—————-
RECV: JNB RI,RECV ;wait here for char
MOV A,SBUF ;save it in ACC
CLR RI ;get ready for next char
RET ;return to caller
;—–The message—————
MYDATA: DB “We Are Ready”,0
END
;Example 10-6
;Assume that XTAL = 11.0592 MHz for the following program,
;state (a) what this program does, (b) compute the frequency used
;by timer 1 to set the baud rate, and (c) find the baud rate of the data transfer.
;Solution:
;(a) This program transfers ASCII letter B (01000010
;binary) continuously
;(b) With XTAL = 11.0592 MHz and SMOD = 1 in the
;above program, we have:
;11.0592 / 12 = 921.6 kHz machine cycle frequency.
;921.6 / 16 = 57,600 Hz frequency used by timer 1
;to set the baud rate.
;57600 / 3 = 19,200, the baud rate.
MOV A,PCON ;A=PCON
MOV ACC.7 ;make D7=1
MOV PCON,A ;SMOD=1, double baud rate with same XTAL freq.
MOV TMOD,#20H ;timer 1, mode 2
MOV TH1,-3 ;19200 (57600/3 =19200)
MOV SCON,#50H ;8-bit data, 1 stop bit, RI enabled
SETB TR1 ;start timer 1
MOV A,#”B” ;transfer letter B
A_1: CLR TI ;make sure TI=0
MOV SBUF,A ;transfer it
H_1: JNB TI,H_1 ;stay here until the last bit is gone
SJMP A_1 ;keep sending “B” again
;Example 10-10
;Write a program to send the message “The Earth is but One
;Country” to serial port. Assume a SW is connected to pin P1.2.
;Monitor its status and set the baud rate as follows:
;SW = 0, 4800 baud rate
;SW = 1, 9600 baud rate
;Assume XTAL = 11.0592 MHz, 8-bit data, and 1 stop bit.
;Solution:
SW BIT P1.2
ORG 0H ;starting position
MAIN:
MOV TMOD,#20H
MOV TH1,#-6 ;4800 baud rate (default)
MOV SCON,#50H
SETB TR1
SETB SW ;make SW an input
S1: JNB SW,SLOWSP ;check SW status
MOV A,PCON ;read PCON
SETB ACC.7 ;set SMOD high for 9600
MOV PCON,A ;write PCON
SJMP OVER ;send message
SLOWSP:
MOV A,PCON ;read PCON
SETB ACC.7 ;set SMOD low for 4800
MOV PCON,A ;write PCON
OVER: MOV DPTR,#MESS1 ;load address to message
FN: CLR A
MOVC A,@A+DPTR ;read value
JZ S1 ;check for end of line
ACALL SENDCOM ;send value to serial port
INC DPTR ;move to next value
SJMP FN ;repeat
;————
SENDCOM:
MOV SBUF,A ;place value in buffer
HERE: JNB TI,HERE ;wait until transmitted
CLR TI ;clear
RET ;return
;————
MESS1: DB “The Earth is but One Country”,0
END
;Example 11-2
;Write a program that continuously get 8-bit data from P0 and sends it
;to P1 while simultaneously creating a square wave of 200 μs period
;on pin P2.1. Use timer 0 to create the square wave. Assume that
;XTAL = 11.0592 MHz.
;Solution:
;We will use timer 0 in mode 2 (auto reload). TH0 = 100/1.085 us = 92
;–upon wake-up go to main, avoid using
;memory allocated to Interrupt Vector Table
ORG 0000H
LJMP MAIN ;by-pass interrupt vector table
;
;–ISR for timer 0 to generate square wave
ORG 000BH ;Timer 0 interrupt vector table
CPL P2.1 ;toggle P2.1 pin
RETI ;return from ISR
;–The main program for initialization
ORG 0030H ;after vector table space
MAIN: MOV TMOD,#02H ;Timer 0, mode 2
MOV P0,#0FFH ;make P0 an input port
MOV TH0,#-92 ;TH0=A4H for -92
MOV IE,#82H ;IE=10000010 (bin) enable Timer 0
SETB TR0 ;Start Timer 0
BACK: MOV A,P0 ;get data from P0
MOV P1,A ;issue it to P1
SJMP BACK ;keep doing it loop unless interrupted by TF0
END
;Example 11-3
;Rewrite Example 11-2 to create a square wave that has a high portion
;of 1085 us and a low portion of 15 us. Assume XTAL=11.0592MHz.
;Use timer 1.
;Solution:
;Since 1085 us is 1000 × 1.085 we need to use mode 1 of timer 1.
;–upon wake-up go to main, avoid using
;memory allocated to Interrupt Vector Table
ORG 0000H
LJMP MAIN ;by-pass int. vector table
;–ISR for timer 1 to generate square wave
ORG 001BH ;Timer 1 int. vector table
LJMP ISR_T1 ;jump to ISR
;–The main program for initialization
ORG 0030H ;after vector table space
MAIN: MOV TMOD,#10H ;Timer 1, mode 1
MOV P0,#0FFH ;make P0 an input port
MOV TL1,#018H ;TL1=18 low byte of -1000
MOV TH1,#0FCH ;TH1=FC high byte of -1000
MOV IE,#88H ;10001000 enable Timer 1 int
SETB TR1 ;Start Timer 1
BACK: MOV A,P0 ;get data from P0
MOV P1,A ;issue it to P1
SJMP BACK ;keep doing it
;Timer 1 ISR. Must be reloaded, not auto-reload
ISR_T1: CLR TR1 ;stop Timer 1
MOV R2,#4 ; 2MC
CLR P2.1 ;P2.1=0, start of low portion
HERE: DJNZ R2,HERE ;4×2 machine cycle 8MC
MOV TL1,#18H ;load T1 low byte value 2MC
MOV TH1,#0FCH;load T1 high byte value 2MC
SETB TR1 ;starts timer1 1MC
SETB P2.1 ;P2.1=1,back to high 1MC
RETI ;return to main
END
;Example 11-5
;Assume that the INT1 pin is connected to a switch that is normally
;high. Whenever it goes low, it should turn on an LED. The LED is
;connected to P1.3 and is normally off. When it is turned on it should
;stay on for a fraction of a second. As long as the switch is pressed low,
;the LED should stay on.
;Solution:
ORG 0000H
LJMP MAIN ;by-pass interrupt vector table
;–ISR for INT1 to turn on LED
ORG 0013H ;INT1 ISR
SETB P1.3 ;turn on LED
MOV R3,#255
BACK: DJNZ R3,BACK ;keep LED on for a while
CLR P1.3 ;turn off the LED
RETI ;return from ISR
;–MAIN program for initialization
ORG 30H
MAIN: MOV IE,#10000100B ;enable external INT 1
HERE: SJMP HERE ;stay here until get interrupted
END
;Assume that pin 3.3 (INT1) is connected to a pulse generator, write a
;program in which the falling edge of the pulse will send a high to
;P1.3, which is connected to an LED (or buzzer). In other words, the
;LED is turned on and off at the same rate as the pulses are applied to
;the INT1 pin.
;Solution:
ORG 0000H
LJMP MAIN
;–ISR for hardware interrupt INT1 to turn on LED
ORG 0013H ;INT1 ISR
SETB P1.3 ;turn on LED
MOV R3,#255
BACK: DJNZ R3,BACK ;keep the buzzer on for a while
CLR P1.3 ;turn off the buzzer
RETI ;return from ISR
;——MAIN program for initialization
ORG 30H
MAIN: SETB TCON.2 ;make INT1 edge-triggered int.
MOV IE,#10000100B ;enable External INT 1
HERE: SJMP HERE ;stay here until get interrupted
END
;Example 11-8
;Write a program in which the 8051 reads data from P1 and writes it to
;P2 continuously while giving a copy of it to the serial COM port to be
;transferred serially. Assume that XTAL=11.0592. Set the baud rate at 9600.
;Solution:
ORG 0000H
LJMP MAIN
ORG 23H
LJMP SERIAL ;jump to serial int ISR
ORG 30H
MAIN: MOV P1,#0FFH ;make P1 an input port
MOV TMOD,#20H ;timer 1, auto reload
MOV TH1,#0FDH ;9600 baud rate
MOV SCON,#50H ;8-bit,1 stop, ren enabled
MOV IE,10010000B ;enable serial int.
SETB TR1 ;start timer 1
BACK: MOV A,P1 ;read data from port 1
MOV SBUF,A ;give a copy to SBUF
MOV P2,A ;send it to P2
SJMP BACK ;stay in loop indefinitely
;—————–SERIAL PORT ISR
ORG 100H
SERIAL: JB TI,TRANS;jump if TI is high
MOV A,SBUF ;otherwise due to receive
CLR RI ;clear RI since CPU doesn’t
RETI ;return from ISR
TRANS: CLR TI ;clear TI since CPU doesn’t
RETI ;return from ISR
END
;Example 11-9
;Write a program in which the 8051 gets data from P1 and sends it to
;P2 continuously while incoming data from the serial port is sent to P0.
;Assume that XTAL=11.0592. Set the baud rata at 9600.
;Solution:
ORG 0000H
LJMP MAIN
ORG 23H
LJMP SERIAL ;jump to serial int ISR
ORG 30H
MAIN: MOV P1,#0FFH ;make P1 an input port
MOV TMOD,#20H ;timer 1, auto reload
MOV TH1,#0FDH ;9600 baud rate
MOV SCON,#50H ;8-bit,1 stop, ren enabled
MOV IE,10010000B ;enable serial int.
SETB TR1 ;start timer 1
BACK: MOV A,P1 ;read data from port 1
MOV P2,A ;send it to P2
SJMP BACK ;stay in loop indefinitely
;—————–SERIAL PORT ISR
ORG 100H
SERIAL: JB TI,TRANS;jump if TI is high
MOV A,SBUF ;otherwise due to receive
MOV P0,A ;send incoming data to P0
CLR RI ;clear RI since CPU doesn’t
RETI ;return from ISR
TRANS: CLR TI ;clear TI since CPU doesn’t
RETI ;return from ISR
END
;Example 11-10
;Write a program using interrupts to do the following:
;(a) Receive data serially and sent it to P0,
;(b) Have P1 port read and transmitted serially, and a copy given to
;P2,
;(c) Make timer 0 generate a square wave of 5kHz frequency on P0.1.
;Assume that XTAL-11,0592. Set the baud rate at 4800.
;Solution:
ORG 0
LJMP MAIN
ORG 000BH ;ISR for timer 0
CPL P0.1 ;toggle P0.1
RETI ;return from ISR
ORG 23H ;
LJMP SERIAL ;jump to serial interrupt ISR
ORG 30H
MAIN: MOV P1,#0FFH ;make P1 an input port
MOV TMOD,#22H;timer 1,mode 2(auto reload)
MOV TH1,#0F6H;4800 baud rate
MOV SCON,#50H;8-bit, 1 stop, ren enabled
MOV TH0,#-92 ;for 5kHZ wave
MOV IE,10010010B ;enable serial int.
SETB TR1 ;start timer 1
SETB TR0 ;start timer 0
BACK: MOV A,P1 ;read data from port 1
MOV SBUF,A ;give a copy to SBUF
MOV P2,A ;send it to P2
SJMP BACK ;stay in loop indefinitely
;—————–SERIAL PORT ISR
ORG 100H
SERIAL:JB TI,TRANS;jump if TI is high
MOV A,SBUF ;otherwise due to receive
MOV P0,A ;send serial data to P0
CLR RI ;clear RI since CPU doesn’t
RETI ;return from ISR
TRANS: CLR TI ;clear TI since CPU doesn’t
RETI ;return from ISR
END

Leave a Reply

Your email address will not be published. Required fields are marked *