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?
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!
Es tut sich zumindest etwas am seriellen Port. Jetzt habe ich es noch mit 4800 Baud versucht.
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.
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.
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.