Wednesday, January 25, 2006

8051: Example 12

LED display as a two digit counter

Things are getting complicated... In addition to two digit multiplexing, the microcontroller also performs other operations. In this example, contents of registers R2 and R3 are incremented in order to display number counting (97, 98, 99, 00, 01, 02...).
This time, transistors which activate displays remain turned on for 25mS. The soubroutine Delay is in charge of that. Even though digits shift much slower now, it is still not slow enough to make impression of simultaneous operation. After both digits of a number blink for 20 times, the number on displays is incremented by 1 and the whole procedure is repeated.
;************************************************************************
;* PROGRAM NAME : 7Seg4.ASM
;* DESCRIPTION: Program displays numbers 0-99 on 7-segment LED displays
;************************************************************************

;BASIC DIRECTIVES

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

;STACK
         DSEG      AT      03FH
STACK_START:       DS      040H

;RESET VECTORS
         CSEG      AT      0
         JMP       XRESET                   ; Reset vector

         ORG       100H

XRESET:  MOV       SP,#STACK_START          ; Define Stack pointer
         MOV       R2,#0                    ; Counter starting value
         MOV       R3,#0
         MOV       R4,#0

LOOP:    INC       R4                       ;Wait for display to be "refreshed" for 100 times 
         CJNE      R4,#20d,LAB1             ;before incrementing the counter
         MOV       R4,#0
         MOV       P1,#0                    ; Turn off all display segments 
         INC       R2                       ; Increment Register containing units by 1
         CJNE      R2,#10d,LAB1
         MOV       R2,#0                    ; Reset units
         INC       R3                       ; Increment Register with tens by 1
         CJNE      R3,#10d,LAB1             ;
         MOV       R3,#0                    ; Reset tens

LAB1:
         MOV       P3,#20h                  ; Activate display D4
         MOV       A,R2                     ; Copy Register containing units to A
         LCALL     Disp                     ; Call mask for that digit
         MOV       P1,A                     ; Write units on display D4
         LCALL     Delay                    ; 25ms delay
         MOV       P1,#0                    ; Turn off all display segments
         MOV       P3,#10h                  ; Activate display D3
         MOV       A,R3                     ; Copy Register contaning tens to A
         LCALL     Disp                     ; Call mask for that digit
         MOV       P1,A                     ; Write tens on display D3
         LCALL     Delay                    ; 25ms delay
         SJMP      LOOP

Delay:
         MOV       R1,#50                   ; 5 ms delay
F01:     MOV       R0,#250
         DJNZ      R0,$
         DJNZ      R1,F01
         RET

Disp:                                       ; Subroutine for displaying digits
         INC       A
         MOVC      A,@A+PC
         RET
         DB        3FH                      ; Digit 0 mask
         DB        06H                      ; Digit 1 mask
         DB        5BH                      ; Digit 2 mask
         DB        4FH                      ; Digit 3 mask
         DB        66H                      ; Digit 4 mask
         DB        6DH                      ; Digit 5 mask
         DB        7DH                      ; Digit 6 mask
         DB        07H                      ; Digit 7 mask
         DB        7FH                      ; Digit 8 mask
         DB        6FH                      ; Digit 9 mask

         END                                ; End of program