Thursday, January 12, 2006

8051: Example 4

Timer T0 in Split mode

Similarly to the previous example, the program spends most of its time in a loop called LOOP1. Since 16-bit Timer T0 is split into two 8-bit timers, there are also two interrupt sources.
The first interrupt is generated after timer T0 reset. Routine TIM0_ISR in which logic zero (0) bit on port P1 rotates is executed. Outside looking, it seems that LEDs move.
Another interrupt is generated upon Timer T1 reset. Routine TIM1_ISR in which the bit state DIRECTION inverts is executed. Since this bit determines direction of bit rotation then the moving direction of LED is also changed.
If you press a push button T1 at some point, a logic zero (0) on the P3.2 output will disable Timer T1.
;************************************************************************
;* PROGRAM NAME : Split.ASM
;* DESCRIPTION: Timer TL0 rotates bit on port P1, while TL1 determines
;* the rotation direction. Both timers operate in mode
;* 3. Logic zero (0) on output P3.2 disables rotation on port P1.
;************************************************************************

;BASIC DIRECTIVES

$MOD53
$TITLE(SPLIT.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;DECLARATION OF VARIABLES

        BSEG    AT    0

;DECLARATION OF BIT-VARIABLES

SEMAPHORE:      DBIT    8
DIRECTION       BIT     SEMAPHORE

;STACK
        DSEG    AT    03FH
STACK_START:    DS    040H

;RESET VECTORS

        CSEG    AT    0
        JMP     XRESET                    ; Reset vector
        ORG     00BH

        JMP     TIM0_ISR                  ; Timer T0 reset vector

        ORG     01BH
        JMP     TIM1_ISR                  ; Timer T1 reset vector

        ORG     100H
XRESET: MOV     SP,#STACK_START           ; Define Stack pointer
        MOV     TMOD,#00001011B           ; Define MOD3
        MOV     A,#0FFH
        MOV     P1,#0FFH
        MOV     R0,#30D
        SETB    TR0                       ; TL0 is turned on
        SETB    TR1                       ; TL1 is turned on
        MOV     IE,#08AH                  ; Interrupt enabled
        CLR     C
        CLR     DIRECTION                 ; Rotate to the right

LOOP1:  SJMP    LOOP1                     ; Remain here

TIM0_ISR:
        DJNZ    R0,LAB3                   ; Slow down rotation by 256 times
        JB      DIRECTION,LAB1
        RRC     A                         ; Rotate contents of Accumulator to the right through
                                          ; Carry flag

        SJMP    LAB2
LAB1:   RLC     A                         ; Rotate contents of Accumulator to the left through
                                          ; Carry flag
LAB2:   MOV     P1,A                      ; Contents of Accumulator is moved to port P1
LAB3:   RETI                              ; Return from interrupt

TIM1_ISR:
        DJNZ    R1,LAB4                   ; Slow down direction of rotation by 256 times
        DJNZ    R2,LAB4                   ; When time expires, change rotation direction
        CPL     SMER
        MOV     R2,#30D
LAB4:   RETI

        END                               ; End of program