Skip to main content

Display 99 to 00 on seven segment

Write 8051 program and draw circuit diagram to display number from 99 to 00 in seven segment display. The program should write in both assembly and C.

Circuit

Two common-cathode seven-segment displays: units digit on Port 1, tens digit on Port 2, each segment through a 330 ohm resistor.

 8051                    Tens display   Units display
 P2.0-P2.6 --[330R x7]--> a b c d e f g
 P1.0-P1.6 --[330R x7]------------------> a b c d e f g
                          common cathode  common cathode
                               |                |
                              GND              GND

The segment code for each digit (gfedcba, common cathode) is: 0=3F, 1=06, 2=5B, 3=4F, 4=66, 5=6D, 6=7D, 7=07, 8=7F, 9=6F. The count is kept as packed BCD in R0 and decremented using ADD A,#99H followed by DA A (adds 99H, which equals subtracting 1 in BCD).

Assembly program

        ORG 0000H
MAIN:   MOV R0,#99H          ; BCD count, start at 99
SHOW:   MOV DPTR,#SEGTAB
        MOV A,R0
        ANL A,#0FH           ; units digit
        MOVC A,@A+DPTR
        MOV P1,A             ; units display on Port 1
        MOV A,R0
        SWAP A
        ANL A,#0FH           ; tens digit
        MOVC A,@A+DPTR
        MOV P2,A             ; tens display on Port 2
        ACALL DELAY          ; about 0.5 s
        MOV A,R0
        JZ MAIN              ; after 00 start again from 99
        ADD A,#99H           ; A = A + 99H, then DA A gives BCD A - 1
        DA A
        MOV R0,A
        SJMP SHOW

DELAY:  MOV R5,#4
D1:     MOV R6,#250
D2:     MOV R7,#250
D3:     DJNZ R7,D3
        DJNZ R6,D2
        DJNZ R5,D1
        RET

SEGTAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH   ; common cathode codes
        END

Checked in a simulator: the sequence 99, 98, ... 90, 89, ... 00 is displayed, then restarts at 99.

C program

#include <reg51.h>

unsigned char code seg[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void delay_ms(unsigned int ms)
{
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 120; j++);          /* about 1 ms at 12 MHz */
}

void main(void)
{
    signed char n;                          /* must be signed: loop ends at -1 */
    while (1) {
        for (n = 99; n >= 0; n--) {
            P2 = seg[n / 10];               /* tens digit on Port 2  */
            P1 = seg[n % 10];               /* units digit on Port 1 */
            delay_ms(500);
        }
    }
}

✓ Answer checked by Claude Opus 5.5 (high effort)

All Embedded System chapter 9 questions →