COSMAC CDP1802 LED Display Counter


Introduction to the COSMAC CDP1802 LED Display Counter

The COSMAC CDP1802 LED Display is a six segment display on the CDP1802 Microprocessor kit. Your kit also has a place to add an LCD display as well, however, I like the appearance of the LED display. In order to use this in projects, you need to understand how to address each of the 7 segments on each digit.

For this post, I’ll be using the programming example for the LED display. I’ve used the examples in the programming book for this unit. From my location, that link seems to be down from time to time, but you can also find it on the Wayback Machine.

Introduction to the A18 Assembler for COSMAC

Digits Vs. Segments for LED Display

The display has six digits. In the programming book, we create two arrays. One array is for the digit. We simply set a bit number within a memory location to turn on a specific digit. Then we write the segment data to that digit. Keep in mind that you are just turning on one digit at a time. The idea is to scan through the digits so fast that the user does not notice.

For the digits, you will be creating six words. Each word will contain the bit number of the display you want to turn on at any given time. The codes come out to be 20H, 10H, 8, 4, 2, and 1.

We also need to write segment data to each digit. This is the hard part. We will be creating an array to store the segment data for each digit. Let’s look at one element of the segment array in detail. Remember, we just need to set particular bits to energize a certain segment of a digit.

This is not straight ASCII or or numeric data. Each bit that you set within a word turns on a specific segment.

Bit 0:  Lower Left
Bit 1:  Center Segment (horizontal)
Bit 2:  Upper Left
Bit 3:  Top Segment
Bit 4:  Top Right
Bit 5:  Lower Right
Bit 6:  Dot - Period - Decimal Point
Bit 7:  Bottom Segment

Numeric Codes (Hex data):
0 - BD
1 - 30
2 - 9B
3 - BA
4 - 36
5 - AE
6 - AF
7 - 38
8 - BF
9 - 3E

The best way I’ve found to determine the codes is to write out a 7 segment display on paper with the bit number that energizes that display. Label the top of your page from 7 to 0 for the bit numbers. Just mark a 1 on any segment you wish to energize at any given time. After that, simply convert your binary data into hex.

Program for COSMAC CDP1802 LED Display

Take a look at Program 8 in the book by Wichit Sirichote. You can use the A18 Assembler to build this project. Simply enter the code into a standard text editor (minus line numbers and object code). After you save your work, you can run the assembler to produce an Intel Hex file, which you can load (paste) directly into your unit from your terminal program.

Basically, he’s just setting up some aliases, loading some addresses, and looping through the digits. 803D is where the database starts that writes the segments. Using the chart above, you can experiment with different values for each of the 6 digits.

EF1-EF4 Checks

We can access these 4 input lines directly in the program. We’ll use EF1 and EF2 in this project. Basically, when we ground one of these pins, we know the user is pressing a button. In our program, we can check for this condition. For example, B1 will branch when the user presses EF1. On the other hand, BN1 branches when the user is not pressing EF1. BN1 $ will hold on the current line as long as EF1 is high, which means the user is not pressing the button. The logic of the wiring is negative. Program 6 in the book by Wichit Sirichote has a good program to demonstrate this. You will use B2/BN2 for EF2, and so on.

Counter Program

I’ve modified the LED Display timer, and added some logic to create a counter. Use EF1 to increment the counter. On the other hand, EF2 resets the counter. As you can see, when a user presses EF1, $8100 increments. We must then convert the value we store in 8100 to a code that represents the numeric value. We do that with the Values database. At this point, simply add the value of the counter to the address of the first element of the value database, then we get the code that represents our number we wish to display. After that, we store this code to the appropriate buffer location. The main code is always updating the display with the data in the buffers.

Once a user presses the button, Q is set. I’m using this as a flag to indicate that we’ve already taken action on the button press. The user must release the button (resetting Q), then press it before our value will increment again.

If the value of the ones place exceeds 9, then we need to reset the ones, and increment the tens place, which is at $8101.


GPIO1:      EQU 7000H
SEGMENT:    EQU 7102H
DIGIT:      EQU 7101H
ONES:       EQU 8100H
TENS:       EQU 8101H
BREAK:      EQU 2756H

    org    8000H        ;have to start somewhere ...
R0    EQU    0
R1    EQU    1
R2    EQU    2
R3    EQU    3
R4    EQU    4
R5    EQU    5
R6    EQU    6
R7    EQU    7
R8    EQU    8
R9    EQU    9
RA    EQU    10
RB    EQU    11
RC    EQU    12
RD    EQU    13
RE    EQU    14
RF    EQU    15

START:  LOAD    R3, DELAY
        LOAD    R4, SEGMENT
        LOAD    R5, DIGIT
        LDI     00H
        LOAD    RC, ONES
        LDI     00H
        STR     RC
        LOAD    RD, TENS
        LDI     00H
        STR     RD
MAIN:   LOAD    RA, BUFFER5
        LOAD    R9, VALUE0
        BR      COUNT
CONT:   LOAD    RB, SCAN_DIGIT
        LDI     6
        PLO     R8      ;LOOP COUNT
LOOP:   LDN     RB      ;GET DIGIT CONTROL
        XRI     0FFH    ;COMPLEMENT IT
        STR     R5      ;WRITE TO DIGIT
        LDN     RA      ;GET BYTE FROM BUFFER
        STR     R4      ;WRITE TO SEGMENT
        SEP     R3      ;DELAY
        LDI     0       ;TURN OFF DISPLAY
        STR     R4
        INC     RA
        INC     RB
        DEC     R8
        GLO     R8
        BNZ     LOOP    ;UNTIL 6 DIGITS
        BR      MAIN
RET_DELAY: SEP  R0
DELAY:  LDI     1
        PLO     R7
DELAY1: DEC     R7
        GLO     R7
        BNZ     DELAY1
        BR      RET_DELAY
BUFFER5:     DB 0BDH
BUFFER4:     DB 0BDH
BUFFER3:     DB 0BDH
BUFFER2:     DB 0BDH
BUFFER1:     DB 0BDH
BUFFER0:     DB 0BDH
SCAN_DIGIT: DB 20H, 10H, 8, 4, 2, 1
VALUE0:     DB 0BDH
VALUE1:     DB 030H
VALUE2:     DB 09BH
VALUE3:     DB 0BAH
VALUE4:     DB 036H
VALUE5:     DB 0AEH
VALUE6:     DB 0AFH
VALUE7:     DB 038H
VALUE8:     DB 0BFH
VALUE9:     DB 03EH


COUNT:  BQ      CHKEF
UP:     BN1     ZERO    ;INCREMENT AND STORE COUNTER
        LDN     RC
        SEX     RD
        ADD
        XRI     12H
        BZ      CONT
        LDI     01H
        SEQ
        SEX     RC
        ADD     ;INCREMENT COUNTER
        STR     RC
        XRI     0AH
        BZ      ITENS
        BR      UPDB

ZERO:   BN2     CONT
        LDI     00H
        STR     RC
        STR     RD
        STR     RE
        STR     RF
        SEQ
        BR      UPDB

ITENS:  LDI     0H
        STR     RC  ; RC NOW CONTAINS A ZERO
        SEX     RD
        LDI     01H
        ADD
        STR     RD ; RD NOW CONTAINS THE TENS VALUES
        BR      UPDB



CHKEF:  B1      CONT
        B2      CONT
        REQ
        BR      CONT


UPDB:   LOAD    R9, VALUE0
        SEX     RC
        GLO     R9
        ADD
        PLO     R9  ;R9 NOW SET TO WHERE WE NEED DATA FOR ONES
        LOAD    R6, BUFFER0
        LDN     R9
        STR     R6
UTENS:  LOAD    R9, VALUE0
        SEX     RD
        GLO     R9
        ADD
        PLO     R9  ;R9 NOW SET TO WHERE WE NEED DATA FOR TENS
        LOAD    R6, BUFFER1
        LDN     R9
        STR     R6
        BR      CONT
        END

Just modify the program to include your own preferences, then run that through the A18 Assembler to get the Intel Hex file. After that, you can upload this hex file to your kit! Here’s the hex file for the program above.

:20800000F880B3F850A3F871B4F802A4F871B5F801A5F800F881BCF800ACF8005CF881BD78
:20802000F801ADF8005DF880BAF859AAF880B9F865A9306FF880BBF85FABF806A80BFBFF62
:20804000550A54D3F800541A1B28883A3D3026D0F801A727873A53304FBDBDBDBDBDBD20E4
:208060001008040201BD309BBA36AEAF38BF3E319B3C860CEDF4FB123234F8017BECF45C39
:20808000FB0A329130A23D34F8005C5D5E5F7B30A2F8005CEDF801F45D30A2343435347A72
:2080A0003034F880B9F865A9EC89F4A9F880B6F85EA60956F880B9F865A9ED89F4A9F880C8
:0880C000B6F85DA60956303444
:0080C801B7

For more information, visit the COSMAC Category Page!

— Ricky Bryce

Leave a comment

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