11 BASIC-52 für den 80535


Für viele Anwendungsbereiche erweist sich BASIC als ein hervorragend geeignetes Entwicklungswerkzeug. Die Vorteile des BASIC-52 von Intel wurden bereits im Kapitel 8 beschrieben. Insbesondere die Verwendung von Realzahlen, die guten mathematischen Leistungen und die einfache Anbindung an ein textorientiertes Terminal sind oft von großem Vorteil. Deshalb besteht auch für den 80535 der Wunsch nach einem BASIC- Interpreter. Gerade die zusätzlichen Hardware-Elemente dieses Controllers lassen sich hervorragend mit den Rechenleistungen eines BASIC-Interpreters nutzen. Deshalb soll das BASIC-52 an den 80535 agepaßt werden. Die hier vorgestellte Anpassung läuft auf dem 80535-Entwicklungsboard nach Kapitel 9, kann aber auch für andere Systeme eingesetzt werden.

Der einzige Grund, warum das BASIC-52 nicht unverändert auf einem 80535 laufen kann, liegt in den unterschiedlichen Ausführungen des Timers 2. Der Timer 2 des 8052 wird direkt mit der Quarzfrequenz (z.B. 12 MHz) getaktet, während der des 80535 den Befehlszyklus-Takt zählt. Die Verwendung des Timers 2 für die Baudratenerzeugung erlaubt beim 8052 eine automatische Erkennung der Baudrate des angeschlossenen Terminals und ermöglicht eine weitgehend freie Wahl des eingesetzten Quarzes. Der Timer 2 des 80535 kann dagegen grundsätzlich nicht als Baudratengenerator eingesetzt werden. Beim 80535 ist man daher auf bestimmte Quarzfrequenzen angewiesen und sollte möglichst mit einer fest vorgegebenen Baudrate arbeiten. Hier ergibt sich bei einem Quarz von 12MHz unter Verwendung des internen Baudratengenerators eine Übertragungsrate von 9600 Baud. Dabei hat man den Vorteil, daß alle drei Timer nutzbar bleiben. Timer 0 wird vom BASIC als Echtzeituhr benötigt. Timer 1 arbeitet mit speziellen Funktionen wie dem PWM-Kommando oder der zusätzlichen seriellen Schnittstelle zusammen. Timer 2 schließlich läßt sich vorteilhaft für die Erzeugung schneller PWM-Signale oder für Zeitmessungen nutzen.

 

11.1 Anpassung des BASIC-52

Hier sollen nun die einzelnen Schritte einer Anpassung erläutert werden. Ein vollständiges Listing der Erweiterung BASIC35.ASM findet sich im Anhang. Um das BASIC an die veränderten Erfordernisse anzupassen, muß eine externe Reset-Routine geschrieben werden. BASIC-52 ist bereits für solche Anpassungen vorbereitet. Beim Start schaut das System bei Adresse 2001h nach, ob eine externe Reset-Routine ausgeführt werden soll. In diesem Fall muß dort ein Byte AAh stehen. Der Benutzer muß dann selbst dafür sorgen, daß alle wichtigen Initialisierungen des Systems ausgeführt werden (vgl. [4]). In ähnlicher Weise wird eine Spracherweiterung angemeldet, indem der Benutzer das Byte 5Ah an die Adresse 2002h des Programmspeichers legt (vgl. Kap. 8.4).

.org 2001H
.byte 0AAH ;externe Reset-Routine
.org 2002H
.byte 5AH ;Befehlerweiterung vorhanden

 

11.1.1 Die externe Reset-Routine

Der Benutzer muß nun selbst für die Initialisierung des Speichers und aller erforderlichen Systemvariablen sorgen. So müssen z.B. das interne und das externe RAM gelöscht werden. Anders als in der originalen Reset-Routine soll hier auf eine Prüfung des verfügbaren Speichers verzichtet werden. Statt dessen geht das Programm von einem Daten-RAM mit 16 Kilobyte aus. Bei Bedarf läßt sich dieser Werte von einem BASIC-Programm selbst verändern. Die eigene Resetroutine muß bei 2090h beginnen.

         .org  2090H
         mov   r0,#0FFH     ;Ende des internen RAM
         clr   a

RESET1   mov   @r0,a        ;Int. RAM leeren
         djnz  R0,RESET1
         mov   SP,#4DH      ;Stack auf 4D setzen
         mov   3EH,#4DH     ;SP-Holding-Reg

         mov   R3,#3FH      ;gesetzt: 16 K
         mov   R1,0FFH      ;0000...3FFF
         mov   DPTR,#0FFFFH
RESET2   inc   DPTR         ;Anfang mit 0000
         clr   a
         movx  @DPTR,a
         mov   a,r3
         cjne  a,DPH,RESET2
         mov   a,R1
         cjne  a,DPL,RESET2 ;Speicher gelöscht

Nach der Initialisierung der Speicherbereiche müssen einige Systemvariablen des Interpreters festgelegt werden. Dazu gehört z.B. die RAM-Obergrenze VARTOP und die verwendete Quarzfrequenz. Ein entscheidender Teil der Initialisierung ist die Einrichtung der seriellen Schnittstelle des Systems. Hier wird der interne Baudratengenerator eingesetzt, um eine Übertragungsrate von 9,6 Kilobaud bei einer Quarzfrequenz von 12MHz zu erreichen. Sofort nach der Initialisierung gibt das System eine Einschaltmeldung aus und geht anschließend in den Kommandomodus.

; RS232 mit Baudratengenerator: 9,6 Kilobaud bei  12 MHz
INIT     setb  BD              ;ADCON.7, Baudratengenerator
         orl   PCON,#80H       ;SMOD=1
         mov   SCON,#50H       ;InitRS232
         setb  TI              ;SCON.1, sendebereit

         mov A,#7           ;CR ausgeben
         lcall 30H
         mov   R3,#22H      ;Startadrese
         mov   R1,#00H      ;Einschaltmeldung
         setb  52
         mov   A,#6         ;Text ausgeben
         lcall 30H

         CLR    A
         LJMP  30H          ;Zum Kommandomodus

         .org 2200H

         .TEXT "MCS-51 BASIC V1.1 / 80535"
         .BYTE '"'

 

11.1.2 Befehlserweiterungen

BASIC-52 erlaubt die Erweiterung durch eigene Statements und Kommandos. Nicht vorgesehen sind allerdings eigene Funktionen, mit denen Werte auf einfache Weise zurückgegeben werden können, wie es z.B. mit A = PORT1 möglich ist. Statt dessen existiert ein Argument Stack, also ein Stapel für Ergebnisse, die ein eigenes Programm liefern kann, und die mit POP abgeholt werden können. Diese Möglichkeit wurde in der vorliegenden Erweiterung für die zusätzlichen Ports des 80535 genutzt. Die zusätzlichen Befehle lauten nun:

Ausgabe :

P3 = X INP3 : POP A
P4 = 255 INP4 : POP A
P5 = 255-X INP5 : POP A

Eingabe

INP6 : POP A

Alle neuen Kommandos müssen in einer Liste definiert und mit eigenen BASIC-Token ab 10h versehen werden. Die Token werden zur Laufzeit des Programms gelesen und führen zum Aufruf von Unterprogrammen, deren Startadressen in einer Vektortabelle eingetragen werden müssen.

 

                   .msfirst

VECTOR_TABLE       .WORD RUN_P4
                   .WORD RUN_INP4
                   .WORD RUN_P5
                   .WORD RUN_INP5
                   .WORD RUN_INP6
                   .WORD RUN_CTRL
                   .WORD RUN_DAPR
                   .WORD RUN_ADCON
                   .WORD RUN_LCDINIT
                   .WORD RUN_CURSOR

USER_TABLE         .BYTE 10H       ;Token
                   .TEXT "P4"      ;Statement
                   .BYTE 00H       ;Trennung
                   .BYTE 11H
                   .TEXT "INP4"
                   .BYTE 00H
                   .BYTE 12H
                   .TEXT "P5"
                   .BYTE 00H
                   .BYTE 13H
                   .TEXT "INP5"
                   .BYTE 00H
                   .BYTE 14H
                   .TEXT "INP6"
                   .BYTE 00H
                   .BYTE 15H
                   .TEXT "CTRL"
                   .BYTE 00H
                   .BYTE 16H
                   .TEXT "DAPR"
                   .BYTE 00H
                   .BYTE 17H
                   .TEXT "ADCON"
                   .BYTE 00H
                   .BYTE 18H
                   .TEXT "LCDINIT"
                   .BYTE 00H
                   .BYTE 19H
                   .TEXT "CURSOR"
                   .BYTE 00H
                   .BYTE 0CEH      ;ehemals RCAP2
                   .TEXT "IO"
                   .BYTE 0FFH      ;Tabellenende

 

Die folgenden Prozeduren zeigen Beispiele für die Bahandlung der neuen Kommanos. Hier wird der Port P4 beschrieben und ausgelesen.

RUN_P4              mov   A,#64    ;Hole Zeichen "="
                    lcall 30H
                    cjne  A,#0EAh,SKIP  ;Token für "=" ?
                    mov   A,#57
                    lcall 30H      ;Ausdruck auswerten
                    mov   A,#01
                    lcall 30H      ;Umwandeln in Integer in R3:R1
                    mov   P4,R1    ;Ausgabe an P4
SKIP                ret

RUN_INP4            mov   R0,P4    ;lowbyte = P4
                    mov   R2,#0    ;highbyte = 0
                    mov   A,#154   ;Umwandlung in Fließkomma
                    lcall 30H      ;und auf den Argumnt Stack
                    ret

11.1.3 Zugriffe auf die erweiterte Hardware

Vor allem das Auslesen von Ports über die Kommandos INP4 bis INP6 erscheint etwas umständlich, weil jeweils der Argument-Stack mit POP ausgelesen werden muß. Zudem werden für jeden Port zwei neue Befehlsworte gebraucht. Es sind aber insgesamt nur 16 neue Befehle möglich. Um alle Möglichkeiten des 80535 nutzen zu können, muß also zusätzlich ein anderer Weg beschritten werden.

Der einzige Operator, der nur bei einem 8052, nicht aber bei einem 80535 einen Sinn hat, ist RCAP2. Im originalen BASIC-52 kann man sowohl auf dieses Register schreiben (RCAP2 = 65535) als auch von ihm lesen (A = RCAP2). Dieser Befehl wird nun in der Anpassung in IO umbenannt und für andere Zwecke eingesetzt. IO schreibt und liest die neuen SFR des 80535, und zwar entweder als 8-Bit-Register oder wie beim ursprünglichen Operator RCAP2 als 16-Bit-Register. Um den neuen Operator IO vielseitig nutzen zu können, wird zusätzlich eine Systemvariable CTRL eingeführt. CTRL legt fest, auf welches SFR der Operator IO zugreift. Für den Port 4 lauten nun die Zugriffe:

Schreiben: CTRL = 4 : IO = A
Lesen: CTRL = 4 : A = IO

Wenn mehrmals auf die gleiche Hardwarefunktion zugegriffen werden muß, braucht CTRL nur einmal angegeben zu werden. Es ergibt sich also insbesondere bei fortgesetzten Lesezugriffen eine deutliche Vereinfachung.

Der ursprüngliche Operator RCAP2 hat das Token CEh. Das BASIC-52 sieht vor, daß ein Benutzer Befehle umbenennen kann. Neben der Definition neuer Token im Bereich 10h bis 1Fh kann also das ursprüngliche Schlüsselwort RCAP2 in IO umbenannt werden. Auf diese Weise läßt sich die gesamte Syntaxprüfung und alle Interpreterfunktionen des altes Operators für den universellen Operator IO nutzen. Zum Umbenennen des Schlüsselworts erfolgt durch den folgenden Eintrag in der User-Tabelle.

.BYTE 0CEH ;ehemals RCAP2
.TEXT "IO"

Der ursprüngliche Operator RCAP2 wird im BASIC-52 in zwei unterschiedlichen Teilen des Programms bearbeitet, und zwar in Abhängigkeit von der Art des Zugriffs, also je nachdem, ob es sich um einen Schreib- oder Lesezugriff handelt. Bei einem Schreibzugriff verzweigt das BASIC-52 an die folgende Stelle:

im originalen BASIC-52:

088B 8B CB mov RCAP2H,R3
088D 89 CA mov RCAP2L,R1

Lowbyte und Highbyte der Operation befinden sich also nun in den Registern R1 und R3. Deshalb kann hier eine Verzweigung eingesetzt werden, um die bereits ausgewerteten Argumente in anderer Weise zu verarbeiten. Das Programm wird modifiziert, indem diese vier Bytes ersetzt werden und einen Unterprogrammaufruf zu einer eigenen Verarbeitungsroutine bei Adresse 2300h bewirken.

im abgeänderten Programm:

088B 12 23 00 lcall 2300h
088E 00 nop

Das Unterprogramm bei 2300h ist Teil der BASIC-Erweiterung und verarbeitet die Daten in den Registern R1 und R3 in Abhängigkeit von der Variablen CTRL in der Registeradresse 18h. Bei jedem Aufruf wird dieses Register gelesen und ausgewertet. Das folgende Teilprogramm zeigt die Bearbeitung des Operators IO für CTRL=1, also die Ausgabe an Port P1. In diesem Fall wird nur das Lowbyte in Register R1 verwendet.

      .org 2300H       ;umgelenkte Ausgabe
            ;lcall 2300H, umgelenkt von 088B

      mov   1BH,A      ;Akku sichern in R3/bank3
      mov   A,18H      ;R0/Bank3, CTRL lesen
      cjne  A,#01,O2   ;Ctrl = 1?
      mov   P1,R1      ;Ausgabe P1
      mov   A,1BH      ;Akku wiederherstellen
      ret
 O2                    ;Ausgabefunktion mit CTR=2

In ähnlicher Weise wird die Bearbeitung von Lesezugriffen auf den ursprünglichen Operator RCAP2 durch eine neue Unterroutine in der Spracherweiterung übernommen. Der ursprüngliche Programmcode lautet:

im originalen BASIC-52:

14CA AA CB mov R2,RCAP2H
088D A8 CA mov R0,RCAP2L

Lowbyte und Highbyte werden hier also in die Register R0 und R2 geschrieben. Die neue Routine bei Adresse 2400h muß also ebenfalls diese Register verwenden.

im abgeänderten Programm:

14CA 12 24 00 lcall 2400h
14CD 00 nop

Der folgende Auszug aus der Erweiterung BASIC35.ASM zeigt die Behandlung des AD-Wandlers. Der Operator IO führt bei einem Lesezugriff mit CTRL=30 zur Ausführung einer Messung mit den Parametern ADCON und DAPR. Das Ergebnis erscheint als Lowbyte in R0, während das Highbyte R2 mit dem Wert Null geladen wird.

      I5            cjne  A,#30,I6    ;Ctrl = 30? AD-Wandler:
                    mov   A,1AH       ;"ADCON" lesen, R2/Bank3
                    anl   A,#07H      ;0...7 maskieren
                    orl   A,#80H      ;BD = 1 (nur 9600Bd/12MHz)
                    mov   ADCON,A     ;AD Kanal setzen
                    mov   DAPR,19H    ;AD-Meßbereich setzen
      ADBUSY2       jb    BSY,ADBUSY2
                    mov   R0,ADDAT    ;Ergebnis lesen
                    mov   R2,#0
                    mov   A,1BH
                    ret
      I6            cjne  A,#10,I7    ;CTRL = 10?
 

Die durch den neuen Operator IO definierte Spracherweiterung trägt entscheidend dazu bei, das BASIC-52 nutzbringend in einem 80535-System einsetzen zu können. Für viele Aufgaben ist es daneben wichtig, auch einen einfachen Zugriff auf das anschließbare LCD-Display zu haben. Deshalb wurde auch ein LCD-Treiber in die Erweiterung mit aufgenommen.

BASIC-52 springt bei der Verarbeitung des User-Output die Adresse 4030h bzw. 403Ch an. Die Sprungvektoren zu den Adressen 4030h und 403Ch befinden sich in der zweiten Hälfte des EPROMs, die in der Betriebsrat 3 des Systems durch Invertierung der Adreßleitung A14 vom unteren Adreßbereich (0000h bis 3FFFh) in den oberen Bereich (4000h bis 7FFFh) verschoben wird. Die erforderlichen Vektoren sind bereits im Betriebsprogramm des Entwicklungssystems berücksichtigt worden. Dort stehen Sprungbefehle nach 2030h und 203Ch, also in den Bereich der BASIC-Erweiterung. Von hier erfolgt dann ein Sprung zu den eigentlichen Unterprogrammen für die Ansteuerung des LCD-Display. Das hat den Vorteil, daß Änderungen am Programm der Spracherweiterung keine Änderung am Betriebssystem des Entwicklungsboards erforderlich machen. Leider ist die LCD-Erweiterung nur mit dem EPROM im Betriebsmodus 3 nutzbar, weil im RAM-Betrieb (Modus 1) kein freier Programmspeicher ab 4000h vorhanden ist.

 

11.1.4 Anwendung der neuen Sprachelemente

Das mit BASIC35.ASM erweiterte BASIC kann in den Adreßbereich ab 4000h in das EPROM des 80535-Entwicklungssystems gebrannt werden. Dabei liegt der ursprüngliche, aber durch acht Bytes veränderte BASIC-Interpreter im Bereich 4000h bis 5FFFh, während die Erweiterung bei Adresse 6000h beginnt. Die bereits im Betriebssystem vorgesehene Umschaltung des Systems in den Betriebsmodus 3 setzt diesen Adreßbereich an die untere Adreßlage und startet den BASIC-Interpreter. Nun kann ein beliebiges Terminalprogramm mit 9600 Baud eingesetzt werden, um BASIC-Programme zu schreiben und zu starten. Das erweiterte BASIC hat folgende Eigenschaften:

- Baudrate fest eingestellt auf 9600 Baud bei 12 MHz
- RAM-Größe 16 K
- Alle drei Timer verfügbar
- Voller Befehlssatz des Intel-8052AH-BASIC
- Unterstützung des AD-Wandlers
- Unterstützung der zusätzlichen Ports
- Unterstützung der zusätzlichen SFR
- Treiber für eine LCD-Anzeige

In Kapitel 8 wurde das originale BASIC von Intel bereits kurz vorgestellt. Gegenüber dem Original haben sich folgende Änderungen ergeben: Die Programmierbefehle für EPROMs können nicht verwendet werden, weil dies ein BASIC im internen ROM des Prozessors erfordert. Außerdem fehlt der Operator RCAP2, weil das gleichnamige Register nur beim 8052 vorhanden war.

Während im BASIC-52 der Timer 2 als Baudratengenerator für die serielle Schnittstelle verwendet wurde, steht er nun ganz dem Benutzer zur Verfügung. Daneben gibt es beim 80535 zwei weitere 8-Bit-Ports und acht analoge Eingänge, die auch als ein 8-Bit-Eingabeport genutzt werden können.

Im BASIC-52 wurde die dritte Speicherbank des internen RAMs für den Benutzer reserviert. Die vier ersten Bytes dieser Bank werden nun von der Spracherweiterung genutzt:

Adresse, Nutzung

24 CTRL speichern
25 DAPR-Wert speichern
26 ADCON-Wert speichern
27 allgemeiner Zwischenspeicher

 

Da die Größe des RAMs mit 16K vorgegeben ist, läßt sich das erweiterte BASIC auch in der Betriebsart 1 des Entwicklungssystems starten. Dabei wird der BASIC-Interpreter z.B. mit LOAD35 in das RAM geladen und gestartet. Es steht dann nur ein Datenbereich von 16K zur Verfügung. Der LCD-Treiber ist hier leider nicht einsetzbar, weil die erforderlichen Sprungvektoren im Bereich ab 4030h liegen, der hier nicht als freier Programmspeicher zur Verfügung steht.

In der Betriebsart 3 wird der BASIC-Interpreter im EPROM betrieben, so daß auch der LCD-Treiber benutzt werden kann. Nun steht das gesamte RAM mit 32K als Datenspeicher bereit, wobei das System zunächst nur 16K verwendet. Die freibleibenden 16K können z.B. durch direkte Speicherzugriffe als zusätzlicher Datenspeicher im Byte-Format genutzt werden. Falls größere Programme mit umfangreichen Variablen es erforderlich machen, kann der verfügbare Speicherbereich mit MTOP = 32767 verdoppelt werden.

Für die zusätzlichen Ports stehen die bereits oben erwähnten Schreibbefehle P3, P4 und P5 sowie die Lesebefehle INP3, INP4, INP5 und INP6 zur Verfügung. Während Schreibzugriffe auf die Ports in der gewohnten Weise z.B. mit P4=100 möglich sind, muß das Lesen der Ports über den Argument-Stack ausgeführt werden:

INP4: POP A: PRINT A

Die Ports sind auch über den neuen Operator IO erreichbar, ebenso wie alle neuen SFR des 80535. Schreib- und Lesezugriffe erfolgen über IO. Die jeweilige Funktion von IO wird über die Zuweisung einer Funktionsnummer an die Steuervariable CTRL bestimmt.

Beispiel:

10 CTRL=4: IO=255: REM Ausgabe über Port 4
20 CTRL=5: PRINT IO: REM Eingabe von Port 5

Insgesamt sind folgende Funktionen erreichbar:

Ports:

CTRL=1 Port 1 schreiben und lesen
CTRL=3 Port 3 schreiben und lesen
CTRL=4 Port 4 schreiben und lesen
CTRL=5 Port 5 schreiben und lesen
CTRL=6 Port 6 nur lesen

Interruptsteuerung:

CTRL=10 IEN0 schreiben und lesen
CTRL=11 IP0 schreiben und lesen
CTRL=12 IEN1 schreiben und lesen
CTRL=13 IP2 schreiben und lesen
CTRL=14 IRCON schreiben und lesen

Timer 2:

CTRL=20 CCEN schreiben und lesen
CTRL=21 CCL1/CCH1 schreiben und lesen, 16 Bit
CTRL=22 CCL2/CCH2 schreiben und lesen, 16 Bit
CTRL=23 CCL3/CCH3 schreiben und lesen, 16 Bit
CTRL=24 CRCL/CRCH schreiben und lesen, 16 Bit

A/D-Wandler:

CTRL=30 A/D-Wandler nur lesen

Der BASIC-Interpreter kann mit einem beliebigen Terminal genutzt werden. Ein übliches Terminalprogramm sendet jedes Zeichen von der Tastatur direkt an den Mikrocontroller. Alle Zeichen werden dort zunächst in einem Eingabepuffer mit einer Länge von 79 Zeichen gesammelt und erst nach <RETURN> ausgewertet. Jeder Fehler macht es leider erforderlich, daß die gesamte Zeile neu eingegeben wird. Um die Arbeit mit BASIC etwas zu erleichtern, wurde das kleine Editor- und Terminalprogramm BASEDIT entwickelt (vgl. Kap. 8). Das Programm läßt sich in der angepaßten Form als BASED535.EXE für den 80535 nutzten. Dabei wird automatisch in den Betriebsmodus 3 umgeschaltet, um das BASIC aus dem EPROM zu starten. Durch einen Übergabeparameter kann die serielle Schnittstelle gewählt werden, die ohne einen Startparameter auf COM2 voreingestellt ist, also z.B. BASED535 1 für COM1.

Nach dem Start des Editorprogramms bei eingeschaltetem 80535-System meldet sich dieses mit seiner Einschaltmeldung:

MCS-51 BASIC V1.1 / 80535

Nun können in gewohnter Weise BASIC-Programme eingegeben und gestartet werden.

 

11.2 Nutzung des AD-Wandlers

Jede Messung im erweiterten BASIC verwendet den Operator IO mit CTRL=30. Vor einer Messung muß der gewünschte Meßbereich über den Operator DAPR festgelegt werden, und der gewünschte Eingangskanal ist in ADCON zu schreiben. Beide Operatoren können nur beschrieben werden und wirken nicht sofort auf die Funktionsregister gleicher Bezeichnung, sondern werden als Parameter in die dafür festgelegten Systemvariablen geschrieben und von der Maschinenroutine erst bei der eigentlichen Messung in die SFR DAPR und ADCON übertragen. Dabei können in ADCON nur die unteren drei Bits zur Auswahl des Eingangskanals weitergeben werden, während die oberen fünf Bits festliegen. Deshalb ist es ausgeschlossen, daß z.B. versehentlich das Bit BD (ADCON.7) zur Erzeugung der Baudrate verändert wird. Das Programmbeispiel AD.BAS zeigt die Durchführung von zehn Einzelmessungen an Kanal AN2. Nach der Festlegung der erforderlichen Parameter genügt es, wiederholt den Operator IO auszulesen, um Meßwerte zu erhalten.

 

1 REM Ansteuerung des AD-Wandlers (AD.BAS)
10 CTRL=30: REM AD-Wandler
20 DAPR=0: REM Messbereich 0-5V
30 ADCON=2: REM Kanal 2
40 FOR N = 1 TO 10
50 PRINT IO
60 NEXT N
 

Alle Adressen des internen RAMs werden bei der Initialisierung des BASIC gelöscht. Ohne explizite Zuweisung arbeitet der AD-Wandler deshalb mit ADCON=0 und DAPR=0, also am Kanal AN0 im Bereich 0...5V. Es können aber bis zu acht Eingangskanäle bei einer freien Wahl der Meßbereiche zwischen 1,25V und 5V festgelegt werden. Abb. 11.1 zeigt den möglichen Anschluß von vier Eingangskanälen unter Verwendung von Schutzwiderständen gegen eventuelle Überspannungen.

Abb. 11.1 Messungen an vier Eingangskanälen

Das Programmbeispiel AD4.BAS zeigt die Realisierung eines Vierkanal-Voltmeters mit einem Meßbereich von 0...2,5V. In einer Schleife werden über ADCON jeweils die Eingangskanäle gewählt. Die Spannung wird hier in Volt umgerechnet und am Terminal angezeigt.

 

10 REM Vierkanalmessung (AD4.BAS)
100 CTRL =30 : REM AD-Wandler 
110 DAPR =128 : REM Vref=2,5V
120 FOR N=0 TO 3
130 ADCON =N : REM Kanal 
140 U=IO/100 : REM AD-Wandler auslesen
150 PRINT U,
160 NEXT N
170 PRINT " V "
180 FOR T=1 TO 2000 : NEXT T
190 GOTO 120

 

Der AD-Wandler kann auch mit einer Auflösung von 10 Bit betrieben werden, wenn die Umsetzung in zwei Stufen erfolgt. In der ersten Stufe reicht eine Messung über den gesamten Bereich von 0V bis 5V. Daraus wird dann der feinere Meßbereich für die zweite Wandlung abgeleitet. Die zweite Messung arbeitet mit einem Meßumfang von 1,25V, wobei der erforderliche Offset aus der ersten Messung abgeleitet wird. Die Umrechnung muß in jeweils vier Bits die untere und obere Grenze des Meßbereichs festlegen und beide gemeinsam in DAPR schreiben. Das Programm AD10BIT.BAS demonstriert das Verfahren für vier Eingangskanäle.

 

100 REM ADC 10 bit (AD10BIT.BAS)
110 CTRL = 30 : REM AD-Wandler 
120 FOR N=0 TO 3
122 DAPR =0 : REM Vref=5V
130 ADCON =N : REM Kanal
140 LOW=INT(IO/16)-2 : IF LOW<0 THEN LOW=0
150 HIGH=LOW+4 : IF HIGH>16 THEN HIGH=16 : LOW=HIGH-4
160 DAPR =LOW+HIGH*16
170 U=(64*LOW+IO)/200
180 PRINT U,
190 NEXT N
200 PRINT " V "
210 FOR T=1 TO 2000 : NEXT T
220 GOTO 120

 

11.3 Ein PWM-Drehstromgenerator

In der Leistungselektronik wird zur Steuerung größerer Lasten gern auf pulsweitenmodulierte (PWM-) Signale zurückgegriffen, weil die Leistungsverstärker im Schalterbetrieb arbeiten und damit nur geringe Verlustleistungen umsetzen. Die Ausgangsspannung ist auf diese Weise regelbar und ergibt sich durch Integration der Impulse. Benötigt man ein analoges Signal, so kann dieses durch eine Tiefpaßfilterung gewonnen werden (vgl. Kap 9.5). Drehspul-Meßinstrumente integrieren die Signale von sich aus. Deshalb lassen sich langsam veränderte Ausgangssignale direkt beobachten. Abb. 11.2 zeigt den Aufbau für drei Kanäle. Hier soll ein langsames Drehstromsignal erzeugt werden, wozu drei Sinussignale mit Phasenverschiebungen von 120° erzeugt werden müssen.

Abb. 11.2 Erzeugen eines dreiphasigen PWM-Signals

Der Timer 2 des 80535 arbeitet mit der vielseitigen Capture/Compare-Unit (CCU) zusammen, die es ermöglicht, auch in BASIC zeitkritische Steuerungen vorzunehmen. Das Beispiel zeigt, daß sich gleichzeitig drei kontinuierliche PWM-Signale generieren lassen. Die gesamte Periode wird durch das Reload-Register CRC festgelegt und liegt zwischen 1µs und 65535µs. Jeder beliebige Teilbereich dieses Zeitraums kann durch die drei Compare-Register CC1 bis CC3 als AN-Zeit des PWM-Signals festgelegt werden. Die drei PWM-Signale werden hier mit einer Periode von 1ms erzeugt. Bei einer Schaltfrequenz von 1kHz ergibt sich so eine mögliche Auflösung der Ausgangsspannung in 1000 Schritte.

Das relativ schnelle PWM-Signal kann durch das wesentlich langsamer laufende BASIC-Programm unterbrechungsfrei verändert werden, weil die PWM-Signale ohne Aktivitäten des Prozessors allein von der Hardware erzeugt werden. Lediglich zur Änderung der Ausgangsspannung eines Kanals muß das entsprechende CC-Register neu beschrieben werden. Das Programm PWM.BAS zeigt die Ausgabe von langsamen Sinusschwingungen mit einer Phasenverschiebung von 120 Grad.

10 REM Drehstrom über PWM-Signale (PWM.BAS)
100 T2CON=0 : REM stop timer2
110 TIMER2=65535
120 CTRL =20 : IO=8+32+128 : REM CCEN : compare CC1, CC2,CC3
130 CTRL =24 : IO=65535-1000 : REM reload CRC, 1ms
140 T2CON=1+16 : REM start timer2 with reload
150 CTRL =21 : REM CC1
160 IO =65535-500 + INT (400* SIN(I))
170 CTRL =22 : REM CC2
180 IO =65535-500 + INT (400* SIN(I+PI*2/3))
190 CTRL =23 : REM CC3
200 IO =65535-500 + INT (400* SIN(I+PI*4/3))
210 I=I+0.1
220 GOTO 150

 

 

11.4 Ein Rechteck-Signalgenerator

Mit Hilfe von Timer 2 läßt sich auch ein quarzgenauer, digital einstellbarer Signalgenerator programmieren. Der Timer wird dazu als Frequenzteiler des Systemstakts von 1MHz eingesetzt. Bei jedem Überlauf wird der vorgegebene 16-Bit-Wert von CCR nachgeladen, der damit die Ausgangsfrequenz des Teilers festlegt. Sie entsteht immer durch Teilen aus der Timer-Taktfrequenz von einem Zwölftel der Quarzfrequenz. Der gesamte Frequenzumfang reicht von ca. 16Hz bis 500kHz. Für kleine Frequenzen lassen sich besonders feiner Abstufungen erreichen. Abb. 11.3 zeigt das Prinzip.

Abb. 11.3 Durch Timer 2 erzeugte Rechtecksignale

Das Ausgangssignal erscheint als Ausgangssignal der Compare-Einheit CC1. Neben der Frequenz kann daher auch das Puls/Pausen-Verhältnis eingestellt werden. Das Programm RECHTECK.BAS verwendet immer ein möglichst symmetrisches Signal mit einem Puls-Pausenverhältnis von 50%, was jedoch nur bei geraden Teilerfaktoren genau gelingen kann. Der Benutzer des Programms muß eine gewünschte Frequenz eingeben. Daraus wird der erforderliche Teilerfaktor berechnet, wobei es naturgemäß mit steigender Frequenz und kleineren Teilerfaktoren zu immer größeren Abstufungen kommt. Um die entstehenden Rundungsfehler der Frequenzteilung zu erkennen, wird daher immer die genaue Frequenz an das Terminal zurückgemeldet.

 

10 REM Rechteckgenerator (RECHTECK.BAS)
100 PRINT "Frequenz in kHz?"
110 INPUT F
120 T=INT(1000/F) : REM clock=1000kHz
130 GOSUB 500
140 PRINT "Teiler = ",T,"Frequenz = ",1000/T
150 GOTO 100
500 REM TIMER2 
510 CTRL =20 : IO=8 : REM CCEN Compare-Modus, CC1
520 CTRL =24 : IO=65536-T : REM Reload-Wert fr CRC
530 CTRL =21 : IO=65536-INT(T/2) : REM Compare-Wert, CC1
540 T2CON=1+16 : REM starte Timer2 im Reload-Modus
550 RETURN 

 

 

11.5 Frequenzmessungen

Auch Frequenzmessungen bis ca. 50kHz können mit Timer 2 durchgeführt werden. Als Zählereingang wird T2 (P1.7) verwendet. Abb. 11.4 zeigt den Anschluß. Wenn es ganz ohne externe Hardware gehen soll, kann man die Echtzeituhr des BASIC zur Bildung der Torzeit von einer Sekunde heranziehen. Die Zeitsteuerung des Programms FREQUENZ.BAS setzt die Interruptsteuerung des Kommandos ONTIME ein. Der Timer wird zunächst zurückgesetzt und mit dem externen Taktsignal gestartet.

Abb. 11.4 Frequenzmessung über Timer 2

Die Frequenzmessung beruht darauf, daß zwei Zählerstände im Abstand von einer Sekunde gelesen werden. Da das Auslesen des Timers zu zeitkritisch ist, werden Zwischenstände nach der Capture-Methode in CC1 und CC2 eingefangen. Die Übertragung des aktuellen Zählerstandes in ein CC-Register wird hier durch einen Schreibzugriff auf das entsprechende Register ausgelöst.

Bei laufendem Zähler wird nach einer Sekunde zunächst ein Capture-Wert in CC1 zwischengespeichert, um genau eine Sekunde später den Zählerstand in CC2 einzufrieren. Die Differenz beider Zählerstände ergibt die Frequenz. Die Torzeitmessung über die Echtzeituhr bringt Meßfehler im Bereich 0,5% mit sich, die in Zeile 1080 bis auf ca. 0,1% korrigiert werden können. Noch genauere Messungen sind denkbar, wenn man Timer 1 als Frequenzzähler einsetzt und die Torzeit durch Timer 2 rein hardwaremäßig erzeugt.

 

10 REM Frequenzmessung (FREQUENZ.BAS)
100 PRINT "Frequenz an P1.7, T2"
110 GOSUB 1000 : PRINT F
120 GOTO 110
999 REM Unterprogramm Frequenzmessung
1000 T2CON=0 : REM stop Timer2
1010 TIMER2=65535
1020 CTRL =20 : IO=12+48 : REM CCEN : Software-Capture CC1, CC2
1030 T2CON=2 : REM start timer2 with input T2EX
1040 TIME=0 : CLOCK 1 : ONTIME 1,1100
1050 IF TIME<2.1 THEN GOTO 1050
1060 CTRL =21 : COUNTER1=IO
1070 CTRL =22 : COUNTER2=IO : CLOCK 0
1075 IF COUNTER2<COUNTER1 THEN COUNTER2=COUNTER2+65536
1080 F=INT((COUNTER2-COUNTER1)*1.0020)
1090 RETURN 
1100 CTRL =21 : IO=0 : REM Software-Capture, CC1
1110 ONTIME 2,1200
1120 RETI 
1200 CTRL =22 : IO=0 : REM Software-Capture, CC2
1210 RETI 
 

 

 

11.6 Akku-Ladungsmessung

Intelligente Akku-Ladegeräte zeichnen sich u.a. durch eine automatische Entladung und ein zuverlässiges Erkennen des Ladeendes aus. Das angepaßte BASIC eignet sich sehr gut für die Steuerung automatischer Ladegeräte, weil es neben dem AD-Wandler über eine Echtzeituhr und komfortable mathematische Grundfunktionen verfügt. Mit dem LCD-Anschluß bietet sich darüber hinaus auch noch die Möglichkeit einer automatischen Ladungsmessung und -anzeige.

Intelligente Laderegler stellen sowohl für den Entlade-, wie für den Ladevorgang einen Regelkreis bereit, der die Stellgröße Akkustrom entsprechend dem aktuellen Ladezustand steuert. Die dabei relevante Ist- Größe ist in erster Linie die Akkuspannung. Oft wird zusätzlich auch die Temperatur des Akkus gemessen und ausgewertet.

Als Schaltstufe für den Akkulader wird hier der Leistungstreiber L293 verwendet. Dieser Baustein enthält vier Brückentreiber, die sowohl den Ladestrom als auch den Entladestrom liefern können. Über zusätzliche Enable-Anschlüsse lassen sich die Ausgänge nach dem Ende der Ladung in den hochohmigen Zustand versetzen. Mit einer Belastbarkeit von 1A pro Kanal können auch größere Akkus geladen werden. Die entstehende Verlustwärme wird über die Masseanschlüsse des DIL-Gehäuses auf eine genügend große Kupferfläche der Platine abgeleitet. Bei Bedarf können mehrere Treiber parallelgeschaltet werden. Abb. 11.5 zeigt die Schaltung des Ladegerätes. Es ist hier für Akkus mit 4,8V und 1,2Ah ausgelegt. Da die Ladespannung bis über 6V reichen kann, werden die Analogeingänge des Prozessors über Spannungsteiler angeschlossen.

Abb. 11.5 Aufbau des Ladereglers

Der Leistungstreiber L293 wird hier vollständig durch Port P4 gesteuert. Die unteren vier Bits sind den vier Ausgangskanälen zugeordnet. Mit P4.4 und P4.5 lassen sich jeweils zwei der Verstärker gemeinsam einschalten oder in den hochohmigen Zustand versetzen. Hier wird nur einer der Leistungsausgänge eingesetzt. Es besteht jedoch die Möglichkeit, mehrere Akkus gleichzeitig zu laden.

Das Programm soll zunächst eine definierte Entladung bis zu einer festgelegten Grenzspannung vornehmen. Dabei wird die Kapazität gemessen und am LCD-Display angezeigt. Gleichzeitig erfolgt laufend eine Ausgabe der aktuellen Akkuspannung. Dieses Verfahren erlaubt eine einfache

Beurteilung des Zustandes eine frisch geladenen Akkus. Ebenso läßt sich die Selbstentladung nach einer längeren Lagerung untersuchen.

Nach der vollständigen Entladung erfolgt die neue Ladung. Der Ladestrom bleibt solange eingeschaltet, bis die kontinuierliche Erhöhung der Akkuspannung zum ersten Mal durch einen deutlichen Spannungsrückgang abgelöst wird. Dieser Vorgang ist ein eindeutiges Indiz für eine Temperaturerhöhung des vollständig geladenen Akkus. Aus Sicherheitsgründen wird zusätzlich eine maximale Ladedauer festgelegt. Während des Ladens wird ebenfalls eine Ladungsmessung und eine Spannungsmessung durchgeführt. Es lassen sich daher Aussagen über das Verhältnis zugeführter und entnehmbarer Ladung machen.

 

100 REM Akku-Messprogramm (AKKU.BAS)
110 RL=22 : REM Lade- und Entladewiderstand = 22 Ohm
120 UMIN=4.0 : REM Entladegrenze 4 Volt
130 TMAX=4 : REM maximal 4 Stunden laden
140 DAPR =0 : REM 0-5V
150 CTRL =30 : REM AD-Wandler
160 LCDINIT : UO 1
170 CURSOR 0
200 REM *************** Entladen *****************
210 TIME=0 : CLOCK 1
220 P5 =48
230 T1=0
240 T1=T1+1
250 DO : WHILE TIME<T1
260 GOSUB 500 : CAP=CAP+IL/3600
270 PRINT USING(#.###),CAP,"Ah",
275 PRINT USING(#.##),UBAT,"V"
280 IF UBAT<UMIN THEN GOTO 300
290 GOTO 240
300 REM *************** Aufladen *****************
310 TIME=0 : CLOCK 1
320 P5 =255 : CAP=0
330 T1=0 : CURSOR 64
340 T1=T1+1
350 DO : WHILE TIME<T1
360 GOSUB 500 : CAP=CAP+IL/3600
365 IF BAT>UMAX THEN UMAX = UBAT
370 PRINT USING(#.###),CAP,"Ah",
375 PRINT USING(#.##),UBAT,"V"
380 IF UBAT<(UMAX-0.2) THEN P5 =0 : UO 0 : END
385 IF (T1/3600) > TMAX THEN P5 =0 : UO 0 : END
390 GOTO 340
500 REM **************** Messung *****************
510 ADCON =0 : REM Kanal 0
520 UBAT=IO/255*10
530 ADCON =1 : REM Kanal 1
540 UL=IO/255*10
550 IL=ABS((UBAT-UL)/RL)
560 RETURN 

 

Für einen Akku mit 4,8V und 1,2Ah wurden folgende Werte gemessen:

Entladekapazität und Entladeschlußpannung: 1057mAh 3.99V

Ladekapazität und Ladeschlußspannung: 1438mAh 6.04V

Das Meßbeispiel zeigt, daß der Akku nicht mehr seine volle Kapazität hat. Außerdem sieht man hier, daß grundsätzlich mehr Ladung beim Aufladen benötigt wird, als bei der Entladung zur Verfügung steht.

Die eingesetzte Hardware eignet sich grundsätzlich für unterschiedliche Ladeverfahren. Den möglichen Erweiterungen und Experimenten sind keine Grenzen gesetzt. Über die vier Leistungsausgänge lassen sich z.B. unterschiedliche Ladestromstärken steuern. Zudem stehen genügend Analogeingänge zur Erfassung weiterer Meßgrößen wie z.B. der Akkutemperatur zur Verfügung. Die Programmierung in BASIC erleichtert dabei die experimentelle Arbeit.