RS232 Version

Überblick

Hier erst einmal die technischen Daten in Kurzform:

  • SAB80C535 mit 12MHz Takt
  • 32 KB EPROM als Programmspeicher (Adressbereich: 0000h-7fff)
  • 32 KB RAM als Programm- und Datenspeicher nutzbar, Datenerhalt durch BackUp-Akku möglich
  • (Adressbereich: 8000-ffffh)
  • Anschlussmöglichkeit für ein LC-Display
  • 8 Kanal 8-Bit AD-Wandler
  • 28 freie digitale I/O-Leitungen
  • RS232 Schnittstelle ( Vollduplex )
  • On Board Spannungsüberwachung mit Watchdogtimer
  • 12 MHz Takt

Technische Unterlagen

Wie bereits erwähnt, habe ich diese Version nur bis zu einem funktionierenden Prototypen, der auf der RS485-Version basiert, entwickelt. D.h. für diese Version ist nur ein Schaltplan verfügbar.

Schaltplan der RS232-Version

Schaltungsbeschreibung

Wie bei der RS485-Version auch wird bei diesem Mikrocontroller- Board das RAM auch über ein NAND-Gatter (7a & 7b) durch das PSEN- und RD-Signal freigegeben. Das PSEN-Signal dient normaler Weise zur Freigabe des Speicherbereichs in dem der Programmcode untergebracht ist. Auf den Datenbereich wird im Gegensatz dazu mit den WR- und RD-Signal zugegriffen. Durch die Verknüpfung des RD- und PSEN-Signals kann der RAM-Baustein als Daten- und Programmspeicher genutzt werden. Dadurch ist es möglich, Programmcode über die serielle Schnittstelle des Boards nachzuladen ( vorausgesetzt ein Bootstraploader befindet sich im EPROM) und zu starten , wodurch die Softwareentwicklung vereinfacht wird.

Der Adressdekoder für das RAM besteht aus dem NAND-Gatter 7c, das zusammen mit dem Reset-Signal als Inverter beschaltet ist. Der RAM -Baustein wird also nur selektiert, wenn das RESET und das Signal A15 High-Potential führen. Durch diese Verknüpfung mit dem RESET-Signal werden Zugriffe auf den RAM-Baustein während des Einschaltvorgangs verhindert. Der RAM-Bereich wird in den Adressbereich 0x8000-0xffffh eingeblendet.

Die Versorgungsspannung bezieht der RAM-Baustein entweder über die +5V Versorgungsspannung, die z.B. an dem Stecker K8 angeschlossen werden kann, oder über eine Pufferenergiequelle, die sicherstellt, dass die Daten auch nach einem Ausfall der Versorgungsspannung erhalten bleiben. Für diesem Zweck eignen sich Batterien, Akkus oder auch große Kondensatoren ( z.B. Goldcaps). Der Anschluss der Pufferenergiequelle erfolgt über den IC19 , der auch die automatische Umschaltung bei Versorgungsspannungsabfall vornimmt. Wird ein Akku als Pufferquelle benutzt kann mit dem Widerstand R9 der Ladestrom festgelegt werden. Bei der Verwendung von Goldcap-Kondensatoren kann der Widerstand R9 überbrückt werden. Nicht bestückt werden darf R9, wenn eine Batterie als Energiequelle eingesetzt wird!

Das LC-Display wird bei dieser Schaltung direkt in den Adressraum des Datenbereichs des SAB80C535 eingeblendet. Dies hat den Vorteil, dass keine I/O-Leitungen durch das Display belegt werden. Allerdings hat diese Schaltungsvariante auch einen Nachteil: Die Datenleitungen, mit denen das Display angesteuert wird, sind nichts anderes als der Adress/Datenbus des Controllers. D.h. auf diesen Leitungen schalten Signale mit einer Frequenz von ca. 1Mhz. Aus Sicht der elektromagnetischen Verträglichkeit (EMV) ist es deshalb nicht sinnvoll das Display über mehrere Zentimeter lange Kabel anzuschließen! (Grundsätzlich war meine Planung einmal, das Display direkt auf die Mikrocontrollerplatine zu stecken.)

Die Dekodierung der Adresssignale für das LCD übernehmen die NAND-Gatter in IC14. Wenn kein LCD angesteuert werden soll muss dieser Baustein nicht bestückt werden. Um die Dekodierung einfach zu halten wird das LCD in die noch freien unteren 32 KB des Datenbereichs eingeblendet. Auf welchen Adressen die einzelnen Register des LCD angesprochen werden kann der Tabelle entnommen werden.

Adresse Funktion
0000h Befehlsregister Write
0001h Datenregister Write
0002h Befehlsregister Read
0003h Datenregister Read

Die Register des Displays sind im ganzen 32 KB Bereich gespiegelt. Mit dem Poti R3 kann der Kontrast des LC-Displays eingestellt werden.

Auf ein mögliches Problem bei der Ansteuerung des Displays sei hier noch hingewiesen, laut Datenblatt muss der Übernahmetakt (das E-Signal) mindestens für eine Dauer von 450ns lang High-Potential führen. Bei 12 MHz Takt ist das mit der Dekoderschaltung erzeugte Signal aber nur etwa 400ns lang. Im Allgemeinen führt dies zu keinen Problemen, falls das Display aber einmal nicht auf Befehle reagiert, sollte man zur Fehlersuche den 12 MHz Quarz durch einen 6 MHz Quarz ersetzen. Wenn das Display dann immer noch nicht funktioniert liegt der Fehler irgendwo anders.

Zur Spannungsüberwachung wird in dieser Schaltung ein MAX690 eingesetzt. Die Hauptaufgabe dieses Baustein ist es den Mikrocontroller mit Hilfe des RESET-Signals anzuhalten, wenn die Betriebsspannung unter 4.5 V gesunken ist. Der Vorteil des MAX690 gegenüber des MAX707, der in der RS485-Version verwendet wird, ist, das er einfacher erhältlich ist. Außerdem ist der Funktionsumfang des MAX690 größer. Eine der Funktionen, die automatische Umschaltung der RAM-Spannungsversorgung, wurde ja bereits oben erwähnt.

Außerdem enthält der Baustein noch einen Watchdog-Timer, der den RESET auslöst, wenn er länger als etwa 1.6 sek nicht zurückgesetzt wird. Über den Jumper K6 kann der Watchdog verschieden konfiguriert werden. Ist der Jumper offen, dann ist der Watchdogtimer abgeschaltet. Steckt man den Jumper zwischen die Pins 2 und 3 wird der Watchdog über das ALE-Signal zurückgesetzt. In diesem Modus wird quasi die korrekte Funktion der Hardware überprüft, da das ALE-Signal bei jedem Zugriff auf die externen Datenspeicher gesetzt wird.

Eine weitere Möglichkeit den Watchdogtimer zu konfigurieren ist es den Jumper auf die Pins 1 und 2 zu setzen. In diesem Modus wird der Timer durch das Signal P1.1 zurückgesetzt, mit anderen Worten, der Timer wird indirekt über die Software zurückgesetzt. In diesem Modus ist der externe Watchdogtimer eine Alternative zu dem internen Watchdog des SAB80C535. Dieser hat den Nachteil, das er alle 65 ms ( bei einem Takt von 12 MHz) zurückgesetzt werden muss.

Eine weitere Funktion, die der MAX690 bietet, ist die Erkennung von Spannungsunterschreitungen z.B. vor der Spannungsstabilisierung. Zu diesem Zweck dient bei dem Baustein der PFI-Eingang. Wenn die Spannung, die an diesen Pin anliegt, unter 1.25 V sinkt wird das Ausgangssignal PFO auf Low-Potential geschaltet. Mit Hilfe eines einfachen Spannungsteilers kann man über diesen Eingang jede Gleichspannung überwachen. Bei diesem Board teilt sich das PFI-Signal mit dem P1.0-Signal einen Anschlusspin an der Steckleiste K1. Wenn keine Spannungsüberwachung über diese PowerFail-Schaltung benötigt wird, kann P1.0 durch das Verbinden der Pins 2 und 3 des Steckers K10 direkt auf die Steckleiste gelegt werden. Es steht also als “normales” I/O-Signal zur Verfügung. Durch das Verbinden der Pins 1 und 2 wird der PFO-Ausgang mit dem P1.0-Pin des Mikrocontrollers verbunden. An dem Anschluss 37 der Steckerleiste ist dann der PFI-Eingang angeschlossen.

Eine wichtige Funktion, die bei diesem Baustein fehlt, ist der manuelle Reset. In den Maxim Datenbuch von 1992 habe ich aber einen kleinen Schaltungstrick gefunden, mit dem diese Funktion nachträglich “eingebaut” wird. Die Versorgungsspannung des MAX690 wird über den Widerstand R5 zugeführt, der den Strom begrenzt. Wenn der Taster gedrückt wird entsteht zusammen mit dem Widerstand R14 ein Spannungsteiler, der die Versorgungsspannung des MAX690 unter 4.65V zieht. Unterhalb dieses Wertes löst der Baustein einen RESET aus.

Die Leuchtdiode, die an das NAND-Gatter 7a angeschlossen ist, dient zur Kontrolle, ob das System läuft oder ob es durch das RESET-Signal gestoppt wurde. Solange die LED leuchtet arbeitet das System.

An den Anschluss K12 wird das Mikrocontrollerboard über die serielle Schnittstelle mit einem herkömmlichen PC verbunden. Da der SAB80C535 bereits einen Interface für die asynchrone serielle Schnittstelle (USART) eingebaut hat, müssen dessen Signale nur noch an den RS232-Standard angepaßt werden. Dies geschieht durch den MAX232, der die TTL-Signale auf einen Signalpegel von +/- 10V umsetzt.

Soviel erst einmal zur Hardware. Die wichtigeren Informationen aus dem Text, wie Adressbelegung, Jumpereinstellungen, sind unten noch mal zusammen gefasst.

Adress und Jumpereinstellungen

Adresstabelle:

Adresse Programmspeicher Datenspeicher
0000h
-
7fffh
EPROM LC-Display
0000h Befehlregister Write
0001h Datenregister Write
0002h Befehlsregister Read
0003h Datenregister Read
8000h
-
ffffh
RAM RAM

Jumper K6:

Beschaltung Funktion
offen Watchdog abgeschaltet
1-2 Watchdog wird durch P1.1 zurückgesetzt
2-3 Watchdog wird automatisch durch ALE-Signal zurückgesetzt

Jumper K10:

Beschaltung Funktion
1-2 PowerFail-Schaltung aktiviert (PFO-Signal an P1.0 angeschlossen)
2-3 PowerFail-Schaltung abgeschaltet. P1.0 wird an die Steckleiste geführt

Bauteilliste

Name Wert Bemerkung
BAT1 Batterie
C1, C2 22pF Keramikkondensator
C11..C18 100nF Kondensator
C4..C6, C9 10µF Elko
D1 LED LED
D3 1N4148 Diode
IC1 SAB80C535 Controller
IC12 MAX232 RS232-Wandler
IC7, IC4 74HCT00 NAND
IC19 MAX690
IC9 74HCT573
K1 2x20 Pins Steckleiste
K10, K12, K6 1x3 Pins Steckleiste
K8 1x2 Pins Steckleiste
LCD1 2x7 Pins Steckleiste
Q2 12MHz Quarz
R3 10k Poti liegend
R5 1k 1/4W
R7 330 1/4W
R9 R Siehe Text
SW1 Taster

Pinbelelgung des SAB80C535 in PGA68-Sockel

Beispielcode Assembler für LCD-Ansteuerung

; Testprogramm for the RS232-Board with LCD  
; Copyright by Thomas Wedemeyer 1996  
  
; Definition Prozessortyp  
cpu 80515 include stddef51.inc  
  
RAMBASE set 8000h ;beginning of RAM area  
LC_IW set 0000h ;LCD Instruction Register Write  
LC_DW set 0001h ;LCD Data Register Write  
LC_IR set 0002h ;LCD Instruction Register Read  
LC_DR set 0003h ;LCD Data Register Read  
ESC set 1bh  
  
ORG RAMBASE  
;*****************************************************************************  
; LCD initialisation  
;*****************************************************************************  
LCD_init:  
mov dptr,#LC\_IW ; load adresspointer with LC\_IW  
mov a,#38h ; function set: 8-bit interface, 2 lines  
movx @dptr,a ; movx accu to pointer-adress (LC_IW)  
mov th0,#27h ; load timer0 with 10ms  
mov tl0,#10h ;  
mov tmod,#02h ; timer0 mode 1  
setb tr0 ; start timer0  
initl0: jnb tf0,initl0 ; wait until timer is 0  
clr tf0 ; clear tf0  
mov a,#38h ; function set: 8-bit interface, 2 lines  
movx @dptr,a ; movx accu to pointer-adress (LC_IW)  
mov th0,#27h ; load timer0 with 10ms  
mov tl0,#10h ;  
setb tr0 ; start timer0  
initl1: jnb tf0,initl1 ; wait until timer is 0  
clr tf0 ; clear tf0  
mov a,#38h ; function set: 8-bit interface, 2 lines  
movx @dptr,a ; movx accu to pointer-adress (LC_IW)  
acall LC_BUSY ; wait until LCD ready  
mov dptr,#LC_IW ;  
mov a,#06h ; Entry Mode = Increment  
movx @dptr,a ; Write instruction  
acall LC_BUSY ; wait until LCD ready  
mov dptr,#LC_IW ;  
mov a,#0fh ; Display control = on, cursor on, flash on  
movx @dptr,a ; Write instruction  
acall LC_BUSY ; wait until LCD ready  
mov dptr,#LC_IW ;  
mov a,#01h ; clear display  
movx @dptr,a ; Write instruction  
acall LC_BUSY ; wait until LCD ready  
;*****************************************************************************  
; Start mainprogramm  
;*****************************************************************************  
main:  
  
acall LC_WRITE ; Write CHR to LCD  
db "RS232-SAB80C535"  
db ESC ;  
test: jmp test  
  
;*****************************************************************************  
; Wait for the Display  
;*****************************************************************************  
LC_BUSY:  
push dpl ; push adress-pointer to stack  
push dph ;  
mov dptr,#LC\_IR ; load adress-pointer with LC\_IR  
LC_BUS0:  
movx a,@dptr ; move LC_IR to accu  
jb acc.7,LC_BUS0 ;  
pop dph ; pop stack to adress-pointer  
pop dpl ;  
ret  
;*****************************************************************************  
; Write Char to LCD  
;*****************************************************************************  
LC_WRITE:  
POP DPH ;LOAD DPTR WITH FIRST CHAR  
POP DPL  
CLR A ;(ZERO OFFSET)  
MOVC A,@A+DPTR ;FETCH FIRST CHAR IN STRING  
LC\_WRI\_1:  
push dpl ; save DPTR  
push dph ;  
mov dptr,#LC\_DW ; Load LC\_Data register adress  
movx @dptr,A ;OUTPUT NEXT CHARACTER  
acall LC_BUSY ;  
pop dph ; load char adress  
pop dpl ;  
INC DPTR ;BUMP POINTER  
CLR A  
MOVC A,@A+DPTR ;GET NEXT CHARACTER  
CJNE A,#ESC,LC\_WRI\_1 ;LOOP UNTIL ESCAPE READ  
MOV A,#1  
JMP @A+DPTR ;RETURN TO CODE AFTER ESCAPE  
;