Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Funktion liefert nicht immer das was es soll
TheD - Mo 31.03.03 21:05
Titel: Funktion liefert nicht immer das was es soll
Hallöchen,
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function TSW.IstGeraetAn: Boolean; begin // Result := False; GetAdressValue(12039, Value); if ((Value and 32) <> 0) then Result := True else Result := False; end; |
folgendes Problem, nach Programmstart, klicke ich auf einen Button, wodurch ich diese Funktion aufrufe. Das ganze geht im prinzip.
Ich überprfüe dabei ob ein Gerät an der seriellen Schnittstelle angeschlossen ist. Dabei schicke ich ein Byte und empfange eins. Dann schau ich ob in dem empfangenem Byte, ein Bit 1 ist, wenn ja, dann soll halt eben True, wenn nicht dann False geliefert werden.
Das Problem, wenn ich beim ersten Anklicken des Buttons klicke und das Gerät ist nicht dran, dann wird mir False geliefert. Und zwar auch wenn ich dann das Gerät anshcliesse und dann wieder den Button drücke! Daher kann ich auch nicht mit dem restlichen Code weiter machen.
Wenn aber beim ersten klick das Gerät da ist, dann funktionierts.
Hoffe dass das verständlcih war, ist ein bisschen blöd zum erklären. ;)
Achja, das else habe ich reingemacht, nachdem ich die eine Zeile auskommentiert habe. War nur ein Versuch.
AndyB - Mo 31.03.03 23:01
| Zitat: |
| if ((Value and 32) <> 0) then |
Damit überprüfst du, ob Bit 5 (2^5=32) gesetzt ist. Wenn du prüfen willst ob überhaupt irgendein Bit gesetzt ist, dann geht das ganz einfach mit
TheD - Mo 31.03.03 23:08
Das ist schon so beabsichtigt! ;)
Es muss das 5te Bit an sein. Wenn das Gerät ein ist und bereit ist, dann setzt es das 5te Bit auf 1, das möchte ich eben überprüfen.
Brueggendiek - Di 01.04.03 00:42
Titel: Re: Funktion liefert nicht immer das was es soll
Hallo!
Zunächst einmal: Wo und wie ist Value definiert, wer verändert das sonst noch?
Ansonsten kann ich keinen Fehler sehen. Allerdings vermisse ich die Ausgabe auf der Schnittstelle, mit der das Gerät zur Antwort aufgefordert wird. Fehlt das etwa beim 2. Aufruf?
Oder sollte GetAdressValue den Wert nur liefern, aber nicht im Schnittstellenregister löschen?
Übrigens kann man das noch besser so schreiben:
Quelltext
1: 2: 3: 4: 5:
| function TSW.IstGeraetAn: Boolean; begin GetAdressValue(12039, Value); Result := (Value and $20) <> 0; end; |
Bei bitweiser Auswertung von Werten und bei Adressen bevorzuge ich die Sedezimalform, weil $20 leichter in Bits umzusetzen ist als 32! Bevor jetzt Beschwerden kommen, dem Compiler sei das egal: ich meine besser lesbar für den Programmierer oder den, der den Code später warten soll! Besonders bei mehreren Bits ist das wichtig: $26 ist klarer als 38!
Eine Deklaration von
Quelltext
1:
| const GeraeteAdresse = $2F07; |
und die Verwendung von GeraeteAdresse bei den Aufrufen erhöht außerdem die Lesbarkeit und erleichtert Änderungen (suche mal im ganzen Projekt die Adresse und ändere sie, ohne einen zufällig gleichen Wert in anderem Zusammenhang zu verändern!)
Gruß
Dietmar Brüggendiek
TheD - Di 01.04.03 07:44
Hallo,
Value ist eine globale Byte-Variable. Die benutze ich in allen möglichen Funktionen und Prozduren.
Hier mal der Code mit dem auslesen von der Schnittstelle.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| function TSW.GetAdressValue(bAdresse: Byte; var Value: Byte): Boolean; var sByte: String; begin Result := False; case Format of 0: begin // end; 1: begin // end; 2: begin // if bAdresse > 111 then begin Result := False; end else begin ComPort1.WriteStr(Chr(bAdresse)); ComPort1.ReadStr(sByte, 2); if Length(sByte) < 2 then //Falls weniger als zwei Bytes ankommen begin Result := False; end else if Byte(sByte[1]) <> bAdresse then //Falls das erste Byte <> AdressByte begin Result := False; end else begin Value := Byte(sByte[2]); //Wert des zweiten Bytes weiter geben Result := True; end; end; //if end; //begin end; //case end; |
Format ist wieder ne globale Variable vom Typ Integer.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function TSW.IstZentraleAn: Boolean; begin // Result := False; GetAdressValue(109, Value); if ((Value and 32) <> 0) then Result := True else Result := False; end; |
Das sind funktionen die in einer allgemeinen Unit sind.
Im Hauptprogramm sieht es dann so aus:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| procedure TForm1.BitBtnLesenClick(Sender: TObject); //Daten Lesen var // bUnter, bOber: Word; s: String; begin ButtonsOff; LabelGeraetVersion.Caption := ''; LabelHersteller.Caption := ''; LabelModul.Caption := ''; LabelVersion.Caption := ''; if SW.IstZentraleAn then //Prüfen ob Gerät eingeschaltet ist begin if SW.IstModulAn then //Prüfen ob Modul im Programmiermodus begin if SW.GetHerstellercode = 1 then //Prüfen ob Herstellercode richtig ist begin if SW.GetModulCode = 3 then //Prüfen ob richtiges Modul im Programmiermodus ist begin ; end else begin ShowMessage('Es ist kein ' + IntToStr(SW.GetModulCode)); end; end else begin ShowMessage('Hersteller'); end; end else begin ShowMessage('Es ist kein Modul im Programmiermodus!'); end; end else begin ShowMessage('Gerät ist nicht eingeschaltet,' + #13#10 + 'oder nicht mit dem Computer verbunden!'); end; ButtonsOn; end; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!