Driving vintage HP HDSP-2000 Alphanumeric LED displays with a retro EPROM 8051 Microcontroller.

Similar projects worth following
Showing off the beauty and functionality of Vintage Alphanumeric LED displays.

I made this project because I love Vintage Hardware and wanted to make something cool with some HDSP-2000 LED displays and an old 8051 that I had acquired.

End goal is to implement LCD emulation on the GPIO so it can act as a drop in HD44780/HD66702 based Character LCD replacement.

I also wanted to take on the challenge of optimizing the code to run fast enough with the limited speed and peripherals of the 8051 Microcontroller. As a result, I got to learn the 8051's memory map with more detail in order take advantage of the bit-addressable RAM on the chip for a fast bit-banged SPI output, which was pretty fun.

View the Code and Documentation on Github here:


  • Can display the US ASCII character set, as well as Japanese Katakana and Hiragana using a custom 5x7 pixel font stored in the program ROM. (I love Japanese, so had to get it in there!)
  • The ROM character sets are based off the those in the HD66702 LCD driver chip found in many Character LCDs.
  • Communicates with the displays through an optimized Bit-Banged SPI-like protocol utilizing the the 8051's bit-addressable memory for speed. Based on code found here but modified for SDCC.
  • Written in C and compiled using the Open Source Small Device C Compiler (sdcc)

Work in Progress:

  • Full HD44780/HD66702 LCD Driver emulation via GPIO ports.
  • Serial UART control.

References and Datasheets:

Vintage Beauty Demo:

The demo displays the messages "Vintage Beauty." or 「ビンテージのうつくしさ。」in Japanese on the displays. The message is selected based on the value of GPIO P0.3 at reset, being HIGH for English, or LOW for Japanese. Make sure to use an external pull-up resistor of around 10k Ohms on that pin as it lacks an internal pull-up.

This is meant to show the basic functionality of the code to display a programmed internal message.


Basic Demo:

Japanese Demo:

Top View for the Hardware Setup:

Hardware setup:

  • Port 2 bits P2.0-P2.4 are used for driving the 5 display columns via NPN transistors.
  • P1.6 is used as SPI Serial Data Out to the displays, entering at the left-most display.
  • P1.7 is used for SPI Clock output to the displays, shared Clock signal by all displays.
  • P0.3 is the message selection pin which is read on Reset. HIGH == English, LOW == Japanese. Pulled-up by an external 10k Ohm resistor (Port 0 has no internal pull-up resistors).
  • The 8051's RESET pin is pulled low by an external 10k Ohm resistor and also tied to the negative terminal of a 10uF Capacitor, with it's positive terminal at +5V to generate a Power-On Reset. A push-button switch that connects RESET to +5V can optionally be added as an external Reset Switch.
  • A 0.1uF decoupling capacitor is recommended between +5V and GND near to the 8051 Microcontroller.

Programming Information:

For the Code, I used the Open Source Small Device C Compiler (sdcc) for compilation. I used a Mac this time, but it should work on Linux as well. Don't know much for Windows, but it's probably similar. On Mac this can be installed using HomeBrew with brew install sdcc. On Linux, you can use your package manager, or just install from source.

To select a different ROM Character set, and configure other settings related to the ROM, you can change the values defined in the ascii5x7.h file. ROM_CODE can be set to ROM_CODE_A00, ROM_CODE_A01, or ROM_CODE_A02 which relate the the ROMs of the common HD66702 LCD Driver.


First compile the ascii5x7.c file with the character ROM data:

sdcc -c ascii5x7.c

Then compile the main program along with the relation file to include the library:

sdcc main.c ascii5x7.rel

After compilation you need to convert the Intel Hex *.ihx output to a regular hex file *.hex. You can do this using the packihx tool that comes with SDCC.

To convert the main.ihx file and write the output to the new file main.hex:

packihx main.ihx > main.hex

Flashing the Microcontroller:

To Flash the Microcontroller I used the TL866CS MiniPro Programmer, which seems to be able to flash almost any MCU or EPROM I've found. Any TL866 version should work. I use this programmer because it has a great Open Source tool available for it called minipro which you can find here:

Read more »

  • 1 × Intel 87C51 Intel 8051 8-bit Microcontroller with EPROM
  • 4 × HDSP-2000 Alphanumeric LED Display
  • 5 × 2n2222 Discrete Semiconductors / Transistors, MOSFETs, FETs, IGBTs

  • LCD emulation progress log #0

    Ethan Durrant08/14/2019 at 20:36 0 comments

    Tl;dr: Progress for LCD emulation via the GPIO is currently in the research/planning stage, and support of the HD66702 LCD Driver Character ROM is complete.

    GPIO Mapping:

    After studying the pinout of a standard Character LCD (shown below) I've got a general idea of how I want them mapped on the 8051's GPIO:

    Current plan is as follows:

    • Data Bus (D0-D7) mapped to Port 0 for bidirectional data flow.
      • D7 on P0.7 is also used as the Busy State output pin in to manage data flow. This will be important, as the emulating 8051 will not be as fast a native LCD Driver chip.
    • Register Select (RS) on P1.1
    • Read/Write (RW) on P1.0
    • Enable (E) on P3.3 allowing use of the 8051's External Interrupt 1 (INT1) in hardware. As the Enable pin is active HIGH and the 8051's External Interrupt is active LOW or transition to LOW, the signal will have to be inverted before fed to P3.3. This will be used so we can handle/save requests from the control MPU/MCU as quickly as possible via an interrupt service routine.

    Handling Contrast:

    Contrast is an Analog input, and the 8051 has no ADC. The HP LED displays have a Vb input that can be used to strobe the displays with PWM and change the apparent brightness.

    One solution could be to use a 555 Timer based circuit to take the analog input and generate a varying PWM brightness output from it. This would also stick with classic components! Who doesn't love a 555?


    To handle the multiple tasks in emulating an LCD Driver the current firmware will need some further modification. Currently the main loop just handles updating the display columns when triggered by a flag set in a Timer Interrupt at 500Hz.

    To implement multitasking I plan to have several separate simple "tasks" executing when required, within each "tick" of the main loop, with some tasks only running when given a flag via an Interrupt.

    Main tasks are as follows:

    • Refreshing display columns from internal display output buffer at a rate of 500Hz. Triggered by flag set in a Timer Interrupt.
    • Interpreting commands given from the master MPU/MCU on the GPIO ports and sets the Busy Flag to 1. Triggered by a flag set in an External Interrupt on Enable (E) transition to HIGH.
    • Updating and modifying the internal display output buffer based on given commands and system state. Probably be implemented with a state machine of sorts. Manage blinking of the cursor if required.
    • Returning any requested data to the master MPU/MCU.

    Character ROM:

    All three Character ROM codes of the HD66702 are available in the `ascii5x7.c` and `ascii5x7.h` files. Japanese Hiragana can optionally be included alongside any of the ROM codes.


    As much as I'd love to continue developing this soon, I will be away from my humble college dorm workbench for a few weeks, and then will be returning to face an intense Fall Semester of Engineering classes.

    Needless to say, time will be limited, but I'll certainly continue development when I can!

    Happy Hacking :)

View project log

Enjoy this project?



Larry wrote 02/24/2023 at 19:43 point

Love these old displays, very nice. I must be missing something in the pictures. How are you driving the columns with NPN transistors? I would expect PNP.

  Are you sure? yes | no

Ken Yap wrote 02/24/2023 at 20:38 point

Emitter follower?

  Are you sure? yes | no

Larry wrote 02/24/2023 at 22:59 point

I guess that is the only explanation. In the picture it looks like the resistor is from the 8051 pin to the base. I thought you would need an additional resistor on the emitter to ground. Perhaps the internal of the display equates that?

I have used these displays per the HP app note with PNP and they are not as bright as I think they should be.  Would be nice to get them brighter and stay within the recommended spec.

  Are you sure? yes | no

Ken Yap wrote 08/09/2019 at 05:39 point

Nice, a retro hacker after my heart. 👍 The 8051 is still available in pin compatible versions such as the Atmel 89C51, which has EEPROM so no UV eraser needed for retries, but your display may be harder for others to replicate.

  Are you sure? yes | no

Ethan Durrant wrote 08/09/2019 at 05:58 point

Yes, I actually used an Atmel 89C51 for prototyping! Much easier that way, then used the EPROM 87c51 one for the final result. Love messing with the 8051 though! It has a refreshing simplicity.

I used the AT89C51 in another of my recent projects here:

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates