1.
Stolpersteine (Stand 23.12.2008)
Aus den Fehlern Anderer lernen.
Pause_wait_Wartezeit Schleife (Loop)
Bit_OFF_und_ON Relais mit OFF einschalten? (gedreht EIN AUS)
(0 und –1), Schalter, Relais, Schaltzustände &B10110101
Rechnen_mit_Bruchzahlen, Rechnen_mit_Klammern
NEU Vorzeichen_der_positiven_Zahl , Teilen_durch_Null
Rechnen_mit_großen_Zahlen, bis 65535
Softwarefehler_bei_Schiebefunktion ,
Trennung_Hauptprogramm_und_Unterprogramm
Überschneidung_Name von Variable und gosub
Bit-Nr. und Überschneidung der Variablen
Sprachliche_Stolpersteine MIN und MAX
Anzahl_der_Variablen (Erweiterung) mehr Variable NEU
RAM-Variable und EEPROM-Variable siehe
Kapitel Softwarebausteine
Programmlänge (Fehlerbeseitigung) , PC_Bild_scrollt bei LCD-Ausgabe
Weitere_Stolpersteine Uhr, Dow, -32768 Division, Modulo
Hast Du 5000 € Schulden ohne Gegenwert, dann hast Du ein
Problem.
Hast Du 5 Millionen Schulden, hat Deine Bank ein Problem.
Hat die Bank 50 Milliarden Schulden, hat der Staat ein
Problem.
Hat der Staat dieses Banken-Problem, hast wiederum Du das
Problem.
Frag nicht, was der Staat für Dich tut,
sondern frag, was Du für den Staat tun kannst.
Frag nicht, wo sind die Milliarden geblieben,
sondern tilge die Schulden durch höhere Steuern
und Geldentwertung Deiner Ersparnisse und Deiner privaten
Altersvorsorge.
Warum soll ich die Schulden tragen? Wer denn sonst?
Du bist
Deutschland !!! Durch Deutschland muss
ein Ruck gehen.
Nun ist durch Deutschlands Banken ein Ruck gegangen.
Die Schuldigen wurden belohnt, die Unschuldigen werden
entlassen.
(Ähnlichkeiten
mit Reden von Politikern sind nicht zufällig sondern beabsichtigt)
halten den Steuerungsablauf an und sind deshalb in Anlagen-
und Maschinensteuerungen unzulässig, weil nur noch eine Funktion
bearbeitet wird und andere Funktionen (Einschalten, Ausschalten, Anzeigen,
Befehlseingabe, usw.) nicht mehr bearbeitet werden.
Eine Ampelsteuerung mit dem Befehl pause
ist zwar verlockend einfach, doch die Tastschalter für die Fußgänger
werden nicht bearbeitet. Der Befehl ist unwirksam.
Rot
Pause
Gelb
Pause
Grün
Stattdessen gibt es in Steuerungen die Wartezeit, die mit einem Zeitwert gesetzt wird und rückwärts gegen Null läuft.
Mit if- und goto-Anweisung wird die Funktion (1), die warten soll, übersprungen und die nächste Funktion (2) bearbeitet.
if (Wartezeit = 0) then goto BearbeiteFunktion1 ' Wartezeit abgelaufen? ja ---> Bearbeite Funktion 1 (Ampel)
if (sekpuls = OFF) then goto Funktion2 ' Bearbeite Funktion 2 (Taster)
Wartezeit = Wartezeit - 1 ' Wartezeit minus 1 (läuft rückwärts nach Null)
Goto Funktion2 ' Bearbeite Funktion 2 während der Wartezeit ---->>>
Die Aufteilung in Schritte (Rot,
Gelb, Grün, usw.) siehe Kapitel Steuerungstechnik Teil Schrittsteuerung.
Des Weiteren darf in der Steuerungstechnik auch nicht der Ablauf durch eine Schleife im Programm unterbrochen werden.
#WarteEingabe
if F1 then goto WarteEingabe '
Warte bis Taste gedrückt für Einschalten des Relais K1,
K1 = ON
(Vorsicht, die folgenden Funktionen werden nicht mehr bearbeitet, weil dies die programmierte Schleife verhindert.)
Stattdessen wird programmiert:
if F1 then goto weiter ' Wenn Taste nicht gedrückt, dann weiter
K1 = ON
#weiter ' (die folgenden Funktionen werden weiter bearbeitet)
(Anmerkung: „Des Weiteren“ ist ein Stolperstein der neuen Rechtschreibung).
1.1) Bit OFF und ON (0 und -1) (Schalter, Relais, Schaltzustände)
Die c-control kennt nur ihren Eingang bzw. Ausgang (Port) und der hat Plus- oder Masse-Potenzial (1-Signal oder 0-Signal).
Die Masse (Ground, Minus der Stromversorgung) ist das Bezugspotenzial.
Die Abfrage if Schalter bedeutet if 1-Signal am Port „Schalter“.
Die Abfrage if not Schalter bedeutet if nicht 1-Signal am Port gleichbedeutend if 0-Signal .
1.1.1)
Schaltzustand Eingang und Abfrage Bits
1-Signal bedeutet am Eingang liegt +5 Volt bezogen auf Masse.
Das bedeutet bei der Abfrage auf einzelne Bits ON oder auch –1 (Minus),
jedoch bei Darstellung der Bits eines Bytes binär &B00000010 (ein Bit ist gesetzt).
0-Signal bedeutet 0 Volt liegt am Eingang.
Das bedeutet bei der Abfrage auf einzelne Bits OFF oder auch 0 (Null).
1.1.2) Schaltzustand
Ausgang und Setzen Bits
1-Signal bedeutet am Ausgang liegt +5 Volt bezogen auf Masse.
Setzen von einzelnen Bits mit ON oder mit jeder Zahl außer 0 (Null), also auch 1 oder –1 bedeutet Setzen,
Ein Bit oder mehrere Bits setzen eines Bytes binär mit &B00000010 (ein Bit ist gesetzt).
0-Signal bedeutet 0 Volt liegt am Ausgang.
Rücksetzen von einzelnen Bits mit OFF oder auch 0 (Null).
1.1.3) Schalter
Eingang
Durch viele Schaltmöglichkeiten entsteht leicht Verwirrung.
Häufig werden die Schalter zwischen Eingang und Minus (Masse) geschaltet.
Bei der Station wird der Eingang durch den internen Pullup-Widerstand bei offenem Schalter auf Plus (+5 V) gezogen.
Industriemäßig wird von Plus auf den Eingang geschaltet. Sofern ein Pullup-Widerstand vorhanden ist, bleibt dies natürlich wirkungslos.
Außerdem können die Schalter Schließer oder Öffner sein.
Das Programm in der c-control kennt nur den Eingang bzw.
Ausgang und der hat Plus- oder Masse-Potenzial
Für die c-control muss es bei Plus-Potenzial if Eingang = ON heißen. Aber das wäre beim Lesen des Programms unverständlich.
Für den Anwender muss
es heißen if SchalterBetätigt , um heraus zu
finden, wie das Programm dann abläuft.
Dieser Konflikt soll im Folgenden aufgehellt werden.
Für Schließer gilt:
Die Abfrage if Schalter = ON unterstellt, dass bei betätigtem Schalter (geschlossener Schließer) Plus-Potenzial am Eingang liegt (if SchalterBetätigt).
Wird nach Masse geschaltet, muss jedoch für „Schalter betätigt“ if Schalter = OFF then ... programmiert werden, um zu wirken.
Für Öffner gilt:
Die Abfrage if Schalter = ON unterstellt, dass bei nicht-betätigtem Schalter (geschlossener Öffner) Plus-Potenzial am Eingang liegt.
Wird nach Masse-Potenzial geschaltet, muss für „Schalter betätigt“ if Schalter = ON then ... programmiert werden (if SchalterBetätigt).
(siehe auch Kapitel Hardware Öffner und Schließer und Schaltplan bei Linkliste).
1.1.4) Funktion benennen, Funktion drehen
Define EIN OFF
Define AUS ON
„Eingänge (Schalter) abfragen“ oder „Ausgänge (Relais) setzen“ kann man auch mit Hilfe von Konstanten textlich drehen.
Beispiel: Aufgrund der Relaisschaltung (Hardware) muss man das Relais mit OFF einschalten.
Mit obigem Define kann man stattdessen Relais = EIN programmieren. Das Relais schaltet ja tatsächlich hardwareseitig ein, obwohl es intern ausgeschaltet wird.
Aber auch Abfragen können sinnvoll erfolgen, wenn Schalter hardwareseitig öffnen müssen.
If Übertemperatur = EIN then ...
Weitere sinnvolle Texte zum Schalten und Abfragen:
Define AUF ON
Define ZU OFF
Beispielsweise kann man für Fenster oder Ventile sinnvolle
Texte zuordnen.
If Fenster = AUF then
Ventil = ZU Diese Befehle sind sprechend und benötigen
keinen Kommentar.
Diese weiteren Texte define ...
erhöhen nicht den Speicherbedarf in der c-control aber die Verständlichkeit des
Programms.
1.1.5) Beispiele
(1)
Abfragen auf
Ein (Plus-Potenzial = Schalter betätigt)
(Schließer an Plus oder Öffner an Masse)
If Schalter = ON
then goto
Die gleiche Wirkung haben die folgenden Abfragen:
If Schalter then goto ...
If Schalter
= -1 then goto
Achtung Minus1 (alle anderen Zahlen bedeuten
OFF)
If Schalter = AUS then goto (gedreht)
(2)
Abfragen auf
Aus (M-Potenzial = Schalter betätigt)
(Schließer an Masse oder Öffner an Plus)
If Schalter = OFF
then goto
Die gleiche Wirkung haben die folgenden Abfragen:
If not
Schalter then goto ...
If Schalter
= 0 then goto Achtung alle Zahlen möglich außer –1
If Schalter = EIN then goto (gedreht)
(3)
EIN schalten
Relais = ON
Die gleiche Wirkung haben folgende Befehle:
Relais
= -1 Achtung, alle Zahlen außer Null
Relais = AUS (gedreht,
falls durch ON ausgeschaltet wird)
(4)
AUS schalten
Relais = OFF
Die gleiche Wirkung haben folgende Befehle:
Relais =
0 Achtung
alle anderen Zahlen bedeuten ON
Relais = EIN
(gedreht, falls durch OFF eingeschaltet wird)
Die „–1“ (Minus 1) entsteht dadurch, dass das
Betriebssystem intern für ein Bit = ON
alle Bits seines Rechenwords setzt und das ist der Wert –1.
Die c-control zeigt bei einzelnen Bits das ganze word also
–1, insofern unlogisch, denn man hat nach dem Bit gefragt.
Dagegen sieht man bei Anzeige des Bitmusters eines Byte die
Bits als 1 und 0 z.B. 10110101 und programmiert auch &B10110101 als
Bitzahl.
Dem Problem geht man aus dem Weg, wenn man für
Einzelbits immer ON und OFF benutzt bzw. die Zuordnungen EIN, AUS, AUF, ZU.
(5) EIN-AUS schalten (Zuweisung)
Man kann auch mit einem Bit ein- und ausschalten.
Relais = Bit
Eine Zahl ungleich Null als Signal gleichbedeutend ON wird auch erzeugt, wenn ein Vergleich durchgeführt wird.
Ist die Innentemperatur größer als die Außentemperatur wird eingeschaltet andernfalls ausgeschaltet.
Luefter = TempInnen > TempAussen Achtung, kann nicht mit OR usw. verknüpft werden.
1. Lösung mit Pseudovariable (nur bei Version 1.1) verknüpfen:
Luefter = TempIA OR
HandEin
2. Lösung mit Zwischenspeicher verknüpfen:
wert1 = TempIA
bzw. (wert1 = TempInnen > TempAussen
)
Luefter = wert1 OR HandEin
‘--------------------------------------
Pseudovariable
(Unterprogramm)
#TempIA Return TempInnen > TempAussen
(6)
Abfrage von Bits
Beispiel: Abfrage
Bit 3 (weitere Abfragen siehe
„Tipps und Tricks“)
Man teilt durch 8 (oder verständlicher durch &B 0000 1000 <- Bit 3 gesetzt)
Anschließend wird mit Modulo-Division festgestellt, ob ein Rest (=1, also ON) bleibt.
AnzeigeBit = Wert / &B 0000
1000 MOD 2
oder alternativ schiebt man im Byte oder word nach rechts um drei Bit für Abfrage Bit 3
AnzeigeBit
= Wert SHR 3 MOD 2
Danach kann abgefragt werde:
If
AnzeigeBit = ON then ... ' Achtung Bit-Abfrage (OFF/ON bzw. 0/–1)
Bei direkter Abfrage ist das Ergebnis eine Zahl 0 bzw. 1.
If
Wert SHR 3 MOD 2 = 1 then ..' Achtung Wert-Abfrage (0/1)
Ports z.B.
Relais können mit jeder Zahl außer Null eingeschaltet werden. Das Problem
besteht immer nur bei Abfragen.
1.2) Rechnen mit Bruchzahlen und Klammern
(1) Bei Bruchzahlen kommt es auf die Reihenfolge des Rechnens an.
x = (17/3*10+5)/10
y = (10*17/3+5)/10
Mathematisch beträgt x und y = 6,166... Die Rechnung von C-Control ergibt jedoch x = 5 und y = 6.
C-Control rechnet nur mit ganzen Zahlen (= Integer), die Kommastellen fallen weg. Wird zuerst dividiert, fällt wertmäßig mehr weg.
Beim Rechnen mit
Klammern ist Folgendes zu beachten.
In den Beispielen werden Zahlen an Stelle von Variablen genommen, um es deutlicher zu machen.
(2) Wie viel ist 1 + 2 * 3 ? Und wie viel ist 2 * 3 + 1 ? In beiden Fällen = 7
Lassen Sie sich nicht durch einen billigen Taschenrechner irritieren, der im ersten Fall als Ergebnis = 9 zeigt.
Der billige Taschenrechner rechnet falsch, weil er nicht die sogenannte Punkt-vor-Strich-Regel berücksichtigt.
Er macht einen aktiven Fehler, weil er Klammern ohne Befehl des Benutzers hinzufügt: (1 + 2) * 3 = 9
Bei Rechnern ohne
Punkt-vor-Strich-Regel muss mit der Reihenfolge 2*3 +1 = 7 das richtige
Ergebnis erzielt werden.
Die c-control rechnet mit Punkt-vor-Strich-Regel. Trotzdem sind Stolpersteine vorhanden.
(3) Die Klammer ist auch im Nenner wichtig. Zuerst wird der
Wert in der Klammer berechnet.
x = 300 / (5 * 3). Die 3 gehört zum Nenner. x = 300 / 5 * 3. Die 3 gehört zum Zähler.
(4) Wie viel ist 10 * 3/2 ? Und wie viel ist 10 * (3/2) ?
Mathematisch ist die Klammer überflüssig, aber nicht beim Rechnen mit ganzen Zahlen (Integer).
C-Control rechnet im ersten Fall 10 * 3 und teilt danach durch 2. Ergebnis = 15
Im zweiten Fall wird erst die Klammer berechnet, 3 geteilt durch 2 (= 1, da die Kommastelle wegfällt) danach *10 Ergebnis = 10
1.3) Vorzeichen der positiven Zahl
Das positive Vorzeichen muss weggelassen werden.
Variable = +1 führt zu einem falschen Ergebnis z.B. bei Print ;Variable; oder Variable = +1 +37
Richtig ist Variable = 1 bzw. Variable = 1 +37. + ist nur als Rechenanweisung zulässig.
Beim negativen Vorzeichen ist der Stolperstein nicht vorhanden: Variable = -1 +37 ist zulässig.
Bekanntlich darf man nicht durch Null teilen. Dies kann unbeabsichtigt geschehen z.B.
Brennerstarts je Stunde = Anzahl / Betriebszeit, nach einem Neustart ist Betriebszeit Null.
Eine Abfrage des Nenners auf Null ist bei C-Control jedoch
nicht notwendig, da das System nicht „abstürzt“, sondern als Ergebnis Null
ausgibt.
1.5) Rechnen mit
großen Zahlen bis 65535
Die größte Zahl ist 32767 . Im Verlauf der Rechnung darf sie nicht überschritten werden.
x = 32000 + 3000 – 3000 liefert zwar das richtige Ergebnis wie auch
x = 32000 – 3000 + 3000, anders sieht es bei Multiplikation aus:
y = 3000*15/10 überschreitet bei der Multiplikation den Zahlenbereich und zeigt ein unsinniges Ergebnis.
Lösung: y = 3000/10*15 oder die Zahl 3000 wird in Faktoren 30 *100 zerlegt und jede Zahl wird multipliziert.
Hundertfachwert 30 * 15 und Einfachwert 100 * 15. Beim weiteren Rechnen muss immer der Hundertfachwert beachtet werden.
Allgemeine Lösung: Beispiel 1002 * 53 = 53106 ist größer 32767
Faktor 53 wird zerlegt in 53/10 = 5 und 53 MOD 10 = 3
Nun wird getrennt multipliziert 1002*5 und 1002*3 (= 5010 und 3006)
Ausgabe für Anzeige:
4 Stellen sind 5010 + 3006/10 = 5310
Einer ist 3006 MOD 10 = 6
Lösung mit
Speichern in ein word bis 65535 siehe Kapitel Tipps.
1.6) Eine
Softwarefalle bei Schiebefunktion
–2 SHR 1 ergibt das gleiche Ergebnis wie –2 / 2 = –1 ( minus Zwei geteilt durch 2)
Das Vorzeichen (hier Minus) ist Bit 15 und wird geschoben wie auch Bit 0 bis 14
Das sind die Binär-Zahlen zur Erläuterung des Übergangs von –2 auf –1
1111 1111 1111
1110 ist die Zahl –2
+ 1
1111 1111 1111 1111 ergibt die Zahl
–1
Bei Linksschieben SHL kann die Zahl 32767 (Bit 0 bis 14) überschritten werden. Ein Bit des Zahlenbereichs kann zum Minus-Vorzeichen auf Bit 15 werden.
Problem und Lösung wird bei folgender Maskierung gezeigt mit Variable Wert1 im Byteformat, wenn Nachtzeit = &H28 (Hex 28) beträgt (für Nacht-Ende 8 UHR):
Wert1 = Nachtzeit SHL 12 SHR 12
0000 0000 0010 1000 Nachtzeit wird geladen (Hex 28)
1000 0000 0000
0000 SHL 12 (Schiebe links 12
Bit), positiver Zahlenbereich ist überschritten
1111 1111 1111 1000 SHR 12 (Schiebe rechts 12 Bit)
Beim Schieben nach links um 12 Bit wird die 8 zum Vorzeichen.
Beim Schieben nach rechts um 12 Bit entsteht die Zahl – 8 (Minus) bzw. im Byte die Zahl 248 (=255 –7).
Bei der folgenden Lösung wird zusätzlich mit Wert1 (Byte) maskiert.
Nachtzeit = &H 28 ' . . . Binär . (0010 1000)
. . .Wert1 = Nachtzeit SHL 4 ' .(1000 0000)
. . .Wert1 = Wert1 SHR 4 ' . . . (0000 1000)
Einfacher ist jedoch die Modulo-Division (Ergebnis ist der Rest einer Division).
Wert1 = Nachtzeit MOD 16 (HEX 28 = DEZ 2*16 +8 = 40), 40 / 16 = 2 REST 8
1.7)
Trennung Hauptprogramm und Unterprogramm
Die Struktur „nur eine Schleife des Hauptprogramms“ muss eingehalten werden.
Define x byte
Define y byte
#AnfangHauptprogramm ' Schleife des Hauptprogramms
x = x + 1
gosub Rechnen
y = y + 1
goto AnfangHauptprogramm ' Rücksprung
Der Rücksprung stellt sicher, dass das Hauptprogramm nicht
in das Unterprogramm „Rechnen“ hinein läuft.
#Rechnen
y = 2 * x
return
1.8) Überschneidung Variable und gosub-Label
Variable und gosub-Label dürfen den gleichen Namen haben.
Vorsicht! Wird z.B. der Name des byte geändert und im Programm eine Variable vergessen,
dann bemerkt der Compiler diesen Fehler nicht.
define Zaehlerwert byte ' geändert von Zaehler in Zaehlerwert
if Zaehler = 5 then goto ... ' statt Byte Zaehlerwert
zu holen, erfolgt Sprung zu Zaehler
goto ...
#Zaehler
Zaehlerwert = Zaehlerwert +1
Return
Diesen Stolperstein vermeidet man, indem immer Variable und gosub-Label unterschiedliche Namen bekommen.
Der Compiler kann den Fehler nicht bemerken, weil über RETURN auch Zahlenwerte zurückgegeben werden können.
Siehe Pseudo-Variable im Kapitel Tipps und Tricks
1.9) Bit-Nr. und Überschneidung
der Variablen
byte1 [1] = word1 [1] = bit-Nr. 1 bis 8
byte2 [2] = bit-Nr. 9 bis 16
byte3 [3] = word2 [2] = bit-Nr. 17 bis 24
byte4 [4] = bit-Nr. 25 bis 32
usw.
Man muss die Überschneidung beachten und kann z.B. byte1 und 2 nicht unabhängig von word1 nutzen.
Andererseits kann man die Überschneidung gezielt einsetzen:
word1 in byte1 und byte2 zerlegen
word1 aus byte1 und byte2 bilden
Einzelne Bits abfragen oder setzen.
Ermittelung der
Bit-Nr. für define
Byte-Nr. x 8 ist die zum Byte gehörige höchste Bit-Nr.
Beispiel: Byte 2 x 8 ist es Bit-Nr. 16. Byte 2 umfasst also Bit-Nr. [9] bis [16].
Word-Nr. x 16 ist die zum Word gehörige höchste Bit-Nr.
Beispiel: Word 1 x 16 ist es Bit-Nr. 16. Word 1 umfasst also
Bit-Nr. [1] bis [16].
Stolperstein
Bit-Nr.
Bit-Nr. 1 wird mit define Schaltzustand Bit [1] benannt.
Hier gibt es kein Problem, weil kein wertmäßiger Zusammenhang zum Byte besteht.
Probleme kann es geben, wenn ein Wert gesetzt oder abgefragt werden soll.
define Wert Byte [1]
define WertBit3 Bit [4], wertmäßig ist es Bit 3.
Sein Wert beträgt 2 hoch 3 also Wert = 8. (= 2*2*2) Siehe hierzu Tipps und Tricks unter Zahlendarstellung.
Ermittlung von Bit-Wert-Nr aus der Bit-Nr (define Bit [ ])
Bit-Nr. [ ] minus 1 ist das Bit als
Wert-Nr.
Beispiel: Byte [2] = Bit [9] bis [16]
Das sind die Bit-Wert-Nr. 8 bis 15
Übrigens sind das die Bit-Wert-Nr. auch im word [1]
Beispiel: word [1] = Bit [1] bis [16]
beinhaltet die Bit-Wert-Nr. 0 bis 15.
1.10) Sprachliche Stolpersteine
Die Vorgabe lautet: Der Sollwert soll mindestens die Rücklauftemperatur haben.
Sollwert = Max (Sollwert , RücklaufTemperatur) ' Wähle den Maximal-Wert von (....)
Ist die Rücklauftemperatur größer als der Sollwert, wird sie als Sollwert genommen.
Weniger „elegant“ ist die Befehlszeile mit gleichem Ergebnis:
If RücklaufTemperatur > Sollwert then Sollwert = RücklaufTemperatur
Gleicher Stolperstein ist: Der Sollwert soll maximal 60 Grad haben.
Sollwert = Min (Sollwert , 60)
' Wähle den Minimal-Wert von ( ....)
1.11) Anzahl der Variablen (Erweiterung)
Man kann Variable sparen wie im Kapitel „Tipps und Tricks“ beschrieben, denn die Anzahl der Variablen ist zunächst auf 24 Byte begrenzt.
Mehr Variable erhält man durch Austausch des CCBas.dll (siehe 1.13).
Damit wird auch der Fehler im Betriebssystem bei der Programmlänge korrigiert.
Byte 25 bis 28 (= word 13 und 14) und Byte 59 und 60 (=word 30) kann ich verwenden, weil ich Interrupt und Befehl SQR nicht benutze.
Byte 40 bis 45, (41/42 = word 21) (43/44 = word 22)
dürfen als Variable eingesetzt werden, wenn Datei-Befehle open for write, print#,
usw. (Datei EEPROM) nicht benutzt werden.
Byte 53 und 54 (= word 27) dürfen als Variable belegt werden, wenn der Befehl print nicht benutzt wird.
Byte 66 kann als Zwischenspeicher genutzt werden. Bei
Minutenbeginn wird es jedoch vom Betriebssystem überschrieben. Außerdem muss
man das Byte in größeren Zeitabständen freihalten, wenn die interne Uhr durch
eine Funk-Uhr nachgestellt werden soll.
Byte 67 enthält Anzahl der Tage des aktuellen Monats. Nur
bei jedem Tagwechsel wird es vom System gesetzt. In der übrigen Zeit kann man
es nutzen.
Byte 68 (mit Byte 67 = word 34) enthält das Jahr für
Berechnung des Schaltjahres und wird nur einmal im Jahr vom System benutzt.
Byte 69 bis 76 (= word 35 bis 38) darf man Byte nutzen, wenn kein Assemblerprogramm (SYS) verwendet wird.
Andernfalls muss man mit einem Test feststellen, welche Bytes von fremden Programmteilen benutzt werden.
Byte 69 bis 72 (= word 35 und 36) können von mir laut Test
als Variable für ein eigenes Programm
benutzt werden.
Alle anderen Bytes dürfen nicht benutzt werden, weil sie vom Betriebssystem belegt sind.
Byte 59 und 60 sowie 69 bis 72 behalten ihren Wert auch nach
Reset und Start,
nicht jedoch nach Ausfall der Versorgungsspannung (ohne
Netzspannung, ohne Batterie).
Test für freie Variable
Beispiel: Byte 69 wird in vorhandenes Programm eingefügt.
Die Variable wird mit 0 und 255 vorbesetzt.
Bleibt der Wert bestehen, kann die Variable für das eigene Programm benutzt werden.
Define Byte69 [69]
Byte69 = 255 ' Vorbesetzung der Variablen mit 255 bzw. 0
#AnfangHauptprogramm ' Schleife des Hauptprogramms
print ;Byte69; ' Anzeige Kontrolle auf Abweichung
goto AnfangHauptprogramm
' Rücksprung
1.12) Speicherwerte (Variable) vom EEPROM bzw. RAM-Variable siehe Kapitel Softwarebausteine
EEPROM-Variable (Datei EEPROM) sind voll remanent, d.h.
der gespeicherte Wert bleibt nach Reset, Spannungsausfall und sogar bei Neuladen eines geänderten Programms erhalten.
1.13) Programmlänge (Fehlerbeseitigung) und mehr Variable
Der Speicher ist zwar 8 kByte groß, aber schon bei 5,5 kByte kommt die Fehlermeldung „Programm zu lang“.
Dieser Fehler kann durch Austausch des Moduls CCBas32.dll beseitigt werden.
Das folgende Modul kann bei Windows eingesetzt werden und hebt gleichzeitig die Begrenzung der Variablen auf.
Nur vorgenannte Variable im Abschnitt 1.11 dürfen benutzt werden.
Die Begrenzung der Programmlänge ist aufgehoben.
Programme größer 8 kByte dürfen nicht übertragen werden,
wenn die Hardware 8 kByte-Speicher hat.
Die Länge kann man leicht mit compilieren vor dem Übertragen feststellen.
Das Modul wurde von den vielen auf Idels homepage ausgewählt und steht hier zum download:
Vorgehensweise
beim Austausch CCBas32.dll
In ihrem installierten Programm befindet sich CCBas32.dll im Ordner Ccew32d (meistens Laufwerk C).
Mit dem Windows-Explorer ändert man den Namen z.B. AltCCBas32.dll, um ihn notfalls wieder zu aktivieren.
Nun clickt man hier auf den neuen CCBas32.zip (gepackt 52 kB) oder CCBas32.dll (97 kB).
Durch Entpacken (Extrahieren) bzw. Speichern legt man das neue Modul in den Ordner Ccew32d. Das ist alles.
Weitere Hinweise finden Sie
http://www.idel-online.de (von dort stammt der neue CCBas32.dll) und
http://ccintern.dharlos.de/forum/ Download Area (mehr Variable)
Ich benutze selten die Simulation, sondern simuliere direkt mit der Hardware.
Ich konnte keine
Einschränkung unter Windows bei Programmen größer 6,8 kB feststellen.
1.14) PC_Bild scrollt durch LCD-Ausgabe
Text kann mit entsprechendem Treiber bei LCD mit print “Text ABC“ ausgegeben werden.
Dabei scrollt das PC-Bild, weil in die serielle Schnittstelle ein Zeilenvorschub übertragen wird (Fehler der Systemsoftware).
Dies kann verhindert werden, indem ein Semicolon angehängt
wird: ... print “Text ABC“ ;
(1) Beim Wechsel
der Stunde wird manchmal die Minute schon auf 00 geschaltet und dabei
noch die alte Stunde gezeigt, z.B.:
16:59
à 16:00 à 17:00
Lösung: Vor
der Abfrage wird eine Befehleszeile eingefügt
If
second = 0 or second = 59 then goto EndeZeitabfrage
Hier kann natürlich nicht mehr second = 0 bzw. second = 59 abgefragt werden.
#EndeZeitabfrage
(2) Wird DOW im Programm benutzt, muss der Wochentag korrigiert werden.
IF DOW > 6 THEN DOW = 0
Kürzer ist DOW = DOW MOD 7
Dadurch wird DOW 0 = Sonntag, 1 = Montag,.....6 = Samstag
Wird in der ersten Minute nach Mitternacht DOW nicht benutzt, reicht eine Korrektur am Anfang des Programms innerhalb der Schleife.
Andernfalls muss vor jeder Abfrage des Wochentags die Fehlerkorrektur erfolgen.
Die Kalenderwoche reicht von Montag bis Sonntag entsprechend Tag 1 bis 7.
In der Arbeitswelt wird die Lohnwoche von Sonntag bis Samstag benutzt, damit der Schichtbeginn Sonntag 22:00 Uhr in der neuen Woche liegt.
Dadurch wird der Sonntag zum Tag 0.
(3) Fehler bei der Zahl –32768 und negativem Divisor
Vorsicht ist geboten, wenn durch Addition oder Subtraktion eine negative Zahl entsteht und damit weiter gerechnet wird.
(3.1) Ausgabe –32768 über die serielle Schnittstelle ergibt –P513
Lösung: if wert12 = -32768 then print “-32768“ else print wert12
(3.2) Ausgabe in Anzeige LCD wird fehlerhaft, weil ABS (-32768) auch –P513 bildet.
Lösung: if Variable = -32768 then Variable =
-32767 (Begrenzung)
(3.3.1) Divisionsergebnis = Dividend / Divisor
Der Dividend
darf -32767 bis +32767 betragen. –32768 führt zu Fehlern!
Die gleiche Einschränkung haben Modulo-Funktion z.B. –32768 MOD 100 und der Befehl ABS (-32768).
Lösung: if Variable = -32768 then Variable = -32767 (Begrenzung)
(3.3.2) Der Divisor darf nur positiv sein. Negativer Divisor führt zum Ergebnis Null.
(4) Lösungen:
(4.1) Begrenzung auf positive Zahl (siehe Kapitel Steuerungstechnik), wenn man gar nicht mit negativen Zahlen rechnen möchte.
(4.2) Überschreitung von 32767 beim Rechenvorgang siehe auch Kapitel Tipps und Tricks.
(4.3) Man rechnet nur mit den positiven Zahlen mit dem Befehl ABS (Variable) und bildet das Vorzeichen nach den Rechenregeln.
Eine negative Zahl ergibt ein negatives Ergebnis. Sind beide Zahlen negativ, dann ist das Ergebnis positiv.
if Variable1 = -32768 then Variable1
= -32767 (Begrenzung
Dividend)
if Variable2 = -32768 then Variable2
= -32767 (Begrenzung
Divisor)
Ergebnis = ABS (Variable1) / ABS
(Variable2)
If
SGN (Variable1) = -1 XOR If SGN (Variable2) = -1 then Ergebnis = – Ergebnis
Erläuterung:
If SGN (Variable) = -1 then ... lautet die Abfrage auf negative Zahl.
Hier wird auch die Funktion des Befehls XOR (entweder oder) gezeigt.
Ist entweder Variable1 oder Variable2 negativ (also nur eine Variable), dann wird das Ergebnis negativ gemacht.
Sind jedoch beide
negativ, bleibt das Ergebnis erhalten. Ebenso natürlich, wenn beide Zahlen
positiv waren.
Vorstehende Stolpersteine stammen u.a. von der folgenden Adresse. Weitere Hinweise siehe
http://ccintern.dharlos.de/bugs.txt
----------- Ende Stolpersteine ------------------------------ nach oben
------------------------- zurück zur Startseite