30 Jahre später: Die Wiederbelebung meines alten 80535 Mikrocontroller Boards

Vor über 30 Jahren tüftelte ich mit einem Freund an einem kleinen Projekt. Wir wollten damals ein inverses Pendel bauen, ähnlich dem, wie wir es im Deutschen Museum in München schon ehrfürchtig bewundert hatten. Aus dem Projekt ist leider nichts geworden und seit damals lag das Mikrocontroller Board zuhause bei meinen Eltern in einer Schachtel herum, bis es schließlich völlig in Vergessenheit geraten ist. Bei meinem letzten Besuch fiel es mir aber wieder in die Hände und plötzlich machte sich eine Frage breit, die mich nicht mehr losließ: Funktioniert es noch?

80535 Board with Cables

Inzwischen liegt das Board bei mir in Wien und ich habe mich die letzten Abende ein wenig damit beschäftigt. Witzigerweise kann ich mich nicht im Geringsten daran erinnern, woher dieses Board eigentlich kommt. Habe ich es gekauft, oder mein Vater? Er weiß aber auch nichts mehr. Habe ich es zusammengelötet? So ein Blackout ist fast schon ein wenig beunruhigend.

Das 80C535-Compuboard

Leider gab es auch keinerlei gedruckte Dokumentation wie Bücher oder Zeitschriften, zumindest konnte ich keine finden. Noch so ein Mysterium. Woher hatte ich damals die Informationen? Das Internet war 1992 noch keine Option. Selbst heute sind im Netz die Informationen darüber sehr spärlich. Zumindest habe ich herausgefunden, dass es ein Projekt der Zeitschrift Elektor war, das im Heft 9/92 veröffentlicht wurde.

Ein Blick auf das Board zeigt seine wichtigsten Eigenschaften:

  • Siemens SAB-80C535-N Mikrocontroller
  • HY62256ALP 32Kx8bit CMOS SRAM
  • M27C256B 256 Kbit EPROM
  • 12Mhz Takt
  • RS-232 Schnittstelle

Der SAB-80C535-N von Siemens ist ein 8-Bit-Mikrocontroller aus der 8051-Familie. Er wurde 1983 eingeführt und ist eine erweiterte Version des 8051, der wiederum 1980 von Intel vorgestellt wurde. Seine wichtigsten Eigenschaften sind

  • 256 Byte On-Chip-RAM
  • Externer Programm und Datenspeicher bis zu je 64 Kbyte erweiterbar
  • Sechs parallele 8-Bit-E/A-Anschlüsse
  • Ein Eingangsport für digitale Eingänge
  • Serielle Vollduplex-Schnittstelle, 4 Betriebsarten, feste oder variable Baudraten
  • Drei 16-Bit-Timer/Zähler
  • 16-Bit Reload, Compare, Capture Funktion
  • A/D-Wandler, 8 gemultiplexte Analogeingänge, programmierbare Referenzspannungen
  • 16-Bit-Watchdog-Timer
  • Idle und Power-Down Modus
  • Power-Down-Versorgung für 40 Byte RAM
  • Boolescher Prozessor
  • 256 direkt adressierbare Bits
  • 12 Interrupt-Quellen (7 externe, 5 interne), 4 Prioritätsstufen
  • Stack-Tiefe bis zu 256 Byte
  • Die meisten Befehle werden in 1µs (750 ns) bei 12-MHz-Betrieb ausgeführt
  • 4 µs Multiplizieren und Dividieren
  • Kompatibel mit Standard SAB 8080/8085 Peripherie und Speicher

Die folgende Tabelle zeigt einen Vergleich mit dem inzwischen auch schon in Jahre gekommenen ESP32 DevKit C V4 Board von Espressif:

  80535 Compuboard ESP32 DevKit C V4
 Jahr 1992 2016
 SoC SAB-80C535-N ESP32
 Typ  8051 (8 Bit) Tensilica Xtensa LX6 (32 Bit)
 Kerne 1 2 + 1
 Takt 12 MHz 240 Mhz
 RAM 256 B + 32 KB 520 KB
 ROM 32 KB -
 Flash - 4 MB external
 WLAN - 2,4 GHz, 802.11b/g/n
 Bluetooth - 4.2 BR/EDR & BLE
 GPIO 48 34
 Timer 3 x 16 Bit 4 x 64 Bit
 ADC 1  x 8 Bit 2 x 12 Bit
 SPI - 4
  I2C - 2
 UART 1 3

 

Erster Test

Gleich zu Beginn stellte sich eine sehr wichtige Frage. Welche Versorgungsspannung braucht das Board? Im Datenblatt des 80535 steht hier -0.5 to 6.5 V. Da auf dem Board augenscheinlich kein Spannungsregler verbaut ist, habe ich einfach 5 Volt versucht.

Es gab aber noch ein Problem. Das Board hat nur eine RS 232 Schnittstelle. Die gibt es auf modernen PCs schon seit Jahren nicht mehr. Damals war es jedoch Stand der Technik, der USB Standard wurde erst 1996 eingeführt. Für solche Fälle gibt es aber USB auf Seriell Adapter, also habe ich mir so einen bestellt. 

Jetzt wurde es ernst. Zum Überwachen der seriellen Schnittstelle habe ich den Serial Monitor der PlatformIO IDE verwendet. Also Board an die Stromversorgung angeschlossen, USB Adapter verbunden und den Reset Knopf gedrückt. Passiert ist.... nichts. In diesem Moment war ich zugegeben etwas enttäuscht. Dann habe ich zunächst die Baudrate kontrolliert. Die stand auf 115200 Baud. Viel zu viel für so ein altes Board. Also habe ich 9600 Baud eingestellt, was damals ein recht üblicher Wert war. Wieder den Reset Knopf gedrückt. Und siehe da!

Baud Rate 9600

Es tut sich zumindest etwas am seriellen Port. Jetzt habe ich es noch mit 4800 Baud versucht.

Baud Rate 4600

Unfassbar. Nach 32 Jahren funktioniert das Board noch. In diesem Moment hatte ich tatsächlich ein bisschen Herzklopfen. Es ist nämlich alles andere als selbstverständlich, dass die Hardware nach so vielen Jahren nicht beschädigt ist. Das Elektrolyt der Kondensatoren könnte inzwischen ausgelaufen sein, oder einige Bits des EPROMs könnten gekippt sein.

Das erste Programm auf dem 80535

Jetzt wollte ich natürlich auch ein Programm auf das 80535 Board laden. Aber wie? Zum Glück habe ich ein gut funktionierendes Backup Konzept. Daher habe ich noch alle Programme, die ich damals für den 80535 geschrieben habe. In diesem Ordner befinden sich auch einige Programme und Beispiele, die damals scheinbar von Elektor mit dem Compuboard mitgeliefert wurden. Darunter auch ein kleines Programm zur Kommunikation mit dem Board. Die EXE-Datei funktioniert jedoch inzwischen unter 64-Bit-Windows nicht mehr. Netterweise hat der Elektor Verlag auch den Pascal Source Code mitgeliefert. Damit konnte ich zwar auch nicht viel anfangen, aber gemeinsam mit ChatGPT und Google Bard Gemini habe ich den Code sehr schnell nach Python migriert. Das Ergebnis sieht folgendermaßen aus:

import serial
import time
import sys
import msvcrt


# Functions for communication via the serial port
def sndbyt(ser, byte):
    while ser.out_waiting > 0:
        time.sleep(0.001)  # Wait until the buffer is empty
    ser.write(bytes([byte]))


def getbyt(ser):
    if ser.in_waiting > 0:  # Check whether data is available in the receive buffer
        return ser.read(1)[0]  # Read and return the received byte
    else:
        return None  # Return None if no byte is present


def setcom(ser, speed):
    # Change baud rate
    ser.baudrate = speed

    # Change parity
    ser.parity = serial.PARITY_NONE

    # Change data bits
    ser.bytesize = serial.EIGHTBITS

    # Change stop bits
    ser.stopbits = serial.STOPBITS_ONE

    # Apply configurations
    ser.apply_settings(d={})


# Main function for file transfer
def download(ser, fname, intel):
    print("DOWNLOAD OF:", fname)
    try:
        hex_f = open(fname, 'r')
    except FileNotFoundError:
        print("ERROR: FILE", fname, "NOT FOUND")
        return

    for line in hex_f:
        if line.strip():  # Check that the line is not empty
            print("<<", line.strip(), ">>")
            ok = down_line(ser, line.strip(), intel)
            print('.')
            if not ok:
                print("ERROR DOWNLOADING FILE!")
                return

    print("FILE TRANSFER COMPLETED")
    ser.write(b'\r')  # Forces an EMON51 prompt
    hex_f.close()

def down_line(ser, line, intel):
    error = False
    ack = 6

    if not intel:
        sndbyt(ser, ord('h'))  # Sending the 'h' command to EMON51
        received = get_in_time(ser)
        if received == ack:  # Waiting for the ACK byte from EMON51
            for ch in line:
                sndbyt(ser, ord(ch))  # Sending the remaining line
            sndbyt(ser, ord(' '))  # Sending a trailing space to end the hexadecimal number
            if get_in_time(ser) != ack:  # Waiting for a new ACK
                error = True
        else:
            error = True
    else:
        for ch in line:
            sndbyt(ser, ord(ch))  # Send each character of the line
    return not error


def get_in_time(ser, timeout=1000):
  start_time = time.time()
  while time.time() - start_time < timeout / 1000:
    if ser.in_waiting:
      return ser.read(1)[0]
  return -1

# Main function for V24 communication
def do_v24(ser, intel):
    filename = None
    esc_key = 27  # ASCII code for ESC
    ctrl_f_key = 6  # ASCII code for CTRL+F
    ctrl_d_key = 4  # ASCII code for CTRL+D

    while True:
        # Display received data
        while ser.in_waiting:
            received_byte = ser.read(1)[0]
            sys.stdout.write(chr(received_byte))
        sys.stdout.flush()

        # Check for key press
        if msvcrt.kbhit():
            inbyt = ord(msvcrt.getch())

            # Handle input
            if inbyt == esc_key:
                print("ESC key. Exiting...")
                break  # Exit loop on ESC

            elif inbyt == ctrl_f_key:
                filename = input("Enter filename: ")
                print("Start download with CTRL+D...")

            elif inbyt == ctrl_d_key:
                if filename is not None:  # Check if filename exists before calling download
                    download(ser, filename, intel)  # Start download
                else:
                    print("No filename entered.")

            else:
                sndbyt(ser, inbyt)

def main():
    fname = ""
    com_adr = "COM1"
    no_dialog = False
    exit_code = 0
    v24_speed = 4800
    intel = False

    # Parameter handling
    for arg in sys.argv[1:]:
        arg = arg.upper()
        if arg.startswith("-COM"):
            com_adr = arg[1:]  # Removes the "-" from the argument
        elif arg == "-1200":
            v24_speed = 1200
        elif arg == "-2400":
            v24_speed = 2400
        elif arg == "-4800":
            v24_speed = 4800
        elif arg == "-9600":
            v24_speed = 9600
        elif arg == "-NODIALOG":
            no_dialog = True
        elif arg == "-INTEL":
            intel = True
        else:
            fname = arg

    # Open serial interface
    ser = serial.Serial(com_adr, v24_speed, timeout=1)

    if intel:
        print("INTEL HEXFILE mode")

    # Setting the COM parameters
    setcom(ser, v24_speed)

    if no_dialog:
        download(ser, fname, intel)
    else:
        do_v24(ser, intel)

    ser.close()
    sys.exit(exit_code)

if __name__ == "__main__":
    main()


Das Skript wird einfach mit

python v25com.py -COM10 -4800

gestartet und wartet dann auf die Eingabe. Das folgende Video zeigt den Upload eines Beispiels, das den 80535 in den Power-Down-Modus versetzt:

Dieses Beispiel war auch gleich eine gute Gelegenheit, den Stromverbrauch des 80535 Boards mit meinem neuen  Power Profiler-Kit II zu messen. Das folgende Bild zeigt zunächst den Upload, die Peaks entsprechen der Ausgabe "ACTIVE" im Terminal und anschließend geht der 80535 in den Power-Down-Modus. 

Power Profiler-Kit II

Das Board verbraucht also normalerweise etwa 220 mA, im Power-Down-Modus sinkt der Wert auf 155 mA. Zum Vergleich, ein ESP32 verbraucht im Deep Sleep Modus nur 15 µA. 

Hello World mit dem Keil C-Compiler für 80535

Zum Abschluss wollte ich unbedingt noch ein eigenes Programm für das 80535 Compuboard schreiben. Allerdings nicht in Assembler, sondern in C. Meine damaligen Programme habe ich mit dem Keil C-Compiler übersetzt. Die Firma Keil gehört zwar seit 2004 zu ARM, den Compiler gibt es aber immer noch. Also habe ich mir die Testversion von Keil µVision heruntergeladen und installiert. Das Programm wirkt zwar etwas antiquiert, erfüllt aber seinen Zweck.

Keil µVision

Anfangs hatte ich etwas Probleme, das Programm zu starten. Die Ursache war der Speicheraufbau des Boards. Nach etwas Recherche fand ich heraus, wie das ROM und das RAM auf diesem Board aufgeteilt sind:

ROM  0x0000 – 0x3FFF
RAM  0x4000 – 0x7FFF
ROM  0x8000 – 0xBFFF
RAM  0xC000 – 0xFFFF

Erst nach richtiger Konfiguration des Compilers wurde das Programm dem richtigen Codesegment zugeordnet. Dazu muss in der Datei STARTUP.A51 die Zeile 

                CSEG    AT      0

in

                CSEG    AT      4000H

geändert werden. Damit weiß der Compiler, dass das Code Segment auf diesem Board bei 0x4000 beginnt.

Der Keil Compiler erzeugt Programme im Intel HEX-Format, daher muss diesmal das Upload Programm mit der Option -INTEL gestartet werden:

python v25com.py -COM10 -INTEL 4800

Das Video zeigt wieder den ganzen Ablauf:

Damit hat das Board bewiesen, dass es noch voll einsatzfähig ist. Ich hätte gerne noch ein etwas komplexeres Programm geschrieben, aber die Testversion des Compilers ist sehr eingeschränkt und erlaubt nur sehr kleine Programme. 

Fazit

Die vergangenen Abende waren für mich unglaublich spannend und machen eigentlich Lust auf mehr. Allerdings hat das Board auch einen großen Nachteil. Die Programme landen immer im RAM, das heißt, sobald die Stromversorgung abgeschaltet wird, müssen sie wieder neu hochgeladen werden. Dies schränkt den praktischen Nutzen erheblich ein, da es weder eine Puffer-Batterie noch Flash-Speicher oder ähnliche Möglichkeiten gibt. Dennoch war der Prozess, vom völlig unbekannten Board bis hin zu einem funktionsfähigen C-Programm zu gelangen, äußerst interessant und lehrreich.

Konversation wird geladen