Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

LAB2 – Using the 8051 Timers in polling mode Overview The purpose of this lab is

ID: 2080144 • Letter: L

Question

LAB2 – Using the 8051 Timers in polling mode

Overview

The purpose of this lab is to control and program the MC8051 Timers of the micro-controller in a given sequence. The program reads port 1 (P1) and outputs its initial status on port 2 (P2). The initial P1 input is incremented at a controlled rate and displayed on P2. Display update takes place once at the end of a sequence including Timer0 overflow followed by Timer1 overflow. Timer0 and Timer1 are programmed using the polling mode, no interrupts. The status of TF0 and TF1 are displayed on Port 3 bit 0 (P3.0) and bit 1 (P3.1) respectively.

Steps

First, configure and initialize the required parallel ports; Timer 0 to mode 1, and Timer1 to mode 1. The Main program starts at code memory address 40H, The main program only function is reading P1, updating P2, and displaying the two overflow flags on port 3.

Second, in the main program configure the two timers, Timer0 and Timer1, for Mode 1 with maximum possible delay time. Enable the Timer0 and Timer1 interrupts, start Timer0, read port P1, and display its initial value on P2. Continue updating port P2 and the status of TF0 & TF1 on P3.0 and P3.1.

Third, configure the debugger display to include the Timer0, Timer1, P1, P2, P3, and the Clock Control windows. Make sure that the Timers windows are configured for no external interrupts and no external pin clocks. The clock window can be used to control the CPU clock speed, which can help during the debugging process.

Fourth, set port 1 (P1) to the desired input value for the up counting on port 2 (P2). Run the program and monitor all displayed windows. Verify the operation of the two timers, TF0 & TF1, and the two display ports. Repeat for different initial P1 value and a varying values during the program execution.

Test and debug your program. Also document and submit your final report along with the well documented list file. You can slow the Timers and Ports update by controlling the MC clock using the clock window in the PREPHERALS selection.

Explanation / Answer

MOV TMOD, #40H ; put timer 1 in event counting mode
SETB TR1 ; start timer 1

MOV DPL, #LOW(LEDcodes) ; | put the low byte of the start address of the
; | 7-segment code table into DPL

MOV DPH, #HIGH(LEDcodes) ; put the high byte into DPH

CLR P3.4 ; |
CLR P3.3 ; | enable Display 0
again:
CALL setDirection ; set the motor's direction
MOV A, TL1 ; move timer 1 low byte to A
CJNE A, #10, skip ; if the number of revolutions is not 10 skip next instruction
CALL clearTimer ; if the number of revolutions is 10, reset timer 1
skip:
MOVC A, @A+DPTR ; | get 7-segment code from code table - the index into the table is
; | decided by the value in A
; | (example: the data pointer points to the start of the
; | table - if there are two revolutions, then A will contain two,
; | therefore the second code in the table will be copied to A)

MOV C, F0 ; move motor direction value to the carry
MOV ACC.7, C ; and from there to ACC.7 (this will ensure Display 0's decimal point
; will indicate the motor's direction)

MOV P1, A ; | move (7-seg code for) number of revolutions and motor direction
; | indicator to Display 0

JMP again ; do it all again

setDirection:
PUSH ACC ; save value of A on stack
PUSH 20H ; save value of location 20H (first bit-addressable
; location in RAM) on stack
CLR A ; clear A
MOV 20H, #0 ; clear location 20H
MOV C, P2.0 ; put SW0 value in carry
MOV ACC.0, C ; then move to ACC.0
MOV C, F0 ; move current motor direction in carry
MOV 0, C ; and move to LSB of location 20H (which has bit address 0)

CJNE A, 20H, changeDir ; | compare SW0 (LSB of A) with F0 (LSB of 20H)
; | - if they are not the same, the motor's direction needs to be reversed

JMP finish ; if they are the same, motor's direction does not need to be changed
changeDir:
CLR P3.0 ; |
CLR P3.1 ; | stop motor

CALL clearTimer ; reset timer 1 (revolution count restarts when motor direction changes)
MOV C, P2.0 ; move SW0 value to carry
MOV F0, C ; and then to F0 - this is the new motor direction
MOV P3.0, C ; move SW0 value (in carry) to motor control bit 1
CPL C ; invert the carry

MOV P3.1, C ; | and move it to motor control bit 0 (it will therefore have the opposite
; | value to control bit 1 and the motor will start
; | again in the new direction)
finish:
POP 20H ; get original value for location 20H from the stack
POP ACC ; get original value for A from the stack
RET ; return from subroutine

clearTimer:
CLR A ; reset revolution count in A to zero
CLR TR1 ; stop timer 1
MOV TL1, #0 ; reset timer 1 low byte to zero
SETB TR1 ; start timer 1
RET ; return from subroutine