hi,
kann mir einer vielleicht anhand eines Beispieles zeigen
wie ich anhand STX und ETX und Checksumme mein Programm erweitern könnte
habe den AT90S8515
Muss von LabView Daten seriell schicken
Soweit funktioniert es, dass ich über mein UART Daten an meinem STK500
empfangen kann und senden, aber da ist das Protokoll nicht dabei
das check ich irgendwie noch nicht, da ich keinerlei Beispiele gesehen
habe
vielen vielen Dank
.include "8515def.inc"
.def temp1 = R16
.def SchlZaY = R17
.def out1 = R18
.EQU fqu = 3686000
.EQU fbd = 9600
.EQU bddv = (fqu/(16*fbd))-1
ldi temp1, LOW(RAMEND)
out SPL, temp1
ldi temp1, HIGH(RAMEND)
out SPH, temp1
ldi temp1, 0xFF
out DDRB, temp1
ldi temp1,bddv ;Baudrate des UART einstellen
out UBRR,temp1
sbi UCR,TXEN
sbi UCR,RXEN
Empfangen: sbis USR,RXC
rjmp Empfangen
in tenmp1, UDR
out PortB, temp1
Senden: sbis USR,UDRE
rjmp Senden
out UDR, temp1
[SYN+] STX Len SRC DST Cmd [Data] CRC
das ist ja noch komplexer als ich dachte, wie sieht das in Assembler
erst aus??
brauche doch nur vor meinen Nutzdaten dieses STX, mit einer
XOR-Verknüpfung müsste ich irgendwie die Checksumme überprüfen und dann
noch das ETX
STX|Nutzdaten|Nutzdaten|Nutzdaten|Checksumme|ETX
irgendwie muss man nur 0x02 für STX und 0x03 für ETX und die Nutzdaten
werden automatisch gefiltert???
Das kann man machen, automatisch ist allerdings gar nichts. Im
Empfaenger hat man immer eine Statusmaschine, die arbeitet das Protokol
ab. Auch in ASM sieh t das wie eine lange statusmaschine aus. Ja, als
Checksumme, kannst Du alle Daten XOR nehmen, oder alle Daten in ein Byte
aufsummieren. Vieles ist moeglich. Es gibt auch Leute, die Wollen dass
STX und ETX nicht in den Daten vorkommen und codieren die dann um, aus
einem 0x02 wird dann ein 0x02 0x02, oder ein % davor usw.
okay, dankeschön
also mein Empfänger ist ja das UART, UART Daten Regeister
mir Statusmaschine meint man was genau??
oja ich dachte auch das STX und ETX net in den Daten vorkommen
ok nop,
und diese statusmaschine muss ich dann auch implementieren, das ist
dann zwingend zu meinem Protokoll, richtig?? oder das ist dann mein
vollständiges Protiokoll??
Die statusmaschine arbeitet das Protokol ab. Wie du beim code von Rene
siehst, sagt dir die statusmaschine wann die Meldung komplett ist. Zum
Senden musst du die Meldung entsprechend zusammenkleben.
macht es kein unterschied, da in diesem Code-Beispiel
"Kommunikation ist Halbduplex-, wenn auch das Medium gleichzeitige
Übertragung und Empfang erlauben würde"
ist doch ein Unterschied, zum voll-duplex das ich benutze beim AT90S8515
(ersetzt ATMega8515)
Vollduplex heisst das Medium erlaubt gleichzeitiges Senden und
Empfangen. Mach das auch Sinn fuer die Anwendung ? Ein Master Slave
betrieb zwischen PC und Device ist naturgemaess nur Halbduplex. Der PC
will was, das Device antwortet.
Nicht mal das. Der PC will was, das Device antwortet, ist definitiv
sequenziell. In der Fachsprache halb duplex. Demgegenueber kann man sich
in einer anderen anwendung vorstellen, dass der PC kontinuierlich DAC
werte sendet und das Device asynchron dazu hin und wieder etwas
quittiert. Das waere dann Vollduplex. Die physikalische Leitung kann
Vollduplex sein, das Protokol kann trotzdem halbduplex sein. Umgekehrt
geht nicht mehr.
okay ungefähr versteh ich dich nop,
mein Device muss zum PC auch ein Protokoll zurücksenden zur Bestätigung,
bevor ich die RELAIS auf meiner Platine dann schalten lasse
sprich ich brauche ein Vollduplex Protokoll??
manuete wrote:
> sprich ich brauche ein Vollduplex Protokoll??
Nein. Du hast es immer noch nicht.
Stell es dir so vor:
Bei Vollduplex kann gleichzeitig in der Hin-Richtung und in
der Rück-Richtung übertragen werden.
Bei Halbduplex kann etweder in der Hin-Richtung oder in
der Rück-Richtung übertragen werden. Aber nur hintereinander
und nicht gleichzeitig.
Ein Telefon zb. wird praktischerweise im Halbduplex eingesetzt.
Der Eine spricht, der andere hört zu. Und andersrum: der Andere
spricht, der Eine hört zu. Aber wenn beide gleichzeitig
sprechen, versteht keiner was.
Noch deutlicher ist das beim Funk.
Wenn die Sprechtaste am Funnkgerät gedrückt wird, wird der
Lautsprecher abgeschaltet und du kannst ins Mikrofon sprechen.
Lässt du die Sprechtaste los, wird der Lautsprecher wieder aktiv
aber dafür kannst du nicht senden.
Voll-Duplex / Halb-Duplex hat nichts damit zu tun ob ich Daten
nur von A nach B oder auch von B nach A übertragen kann.
Voll- / Halb-Duplex trifft nur eine Aussage darüber, ob der
Informationsfluss gleichzeitig in beide Richtungen laufen kann
oder nicht.
hmmm ok, dann halbduplex Protokoll
gibt es ausser dem oberen Link noch weitere Beispiele in asm die ein
halbduplex Protokoll mit STX/ETX verwenden
ich weiss net wie ich anfangen soll, und mit was und wie
manuete wrote:
> hmmm ok, dann halbduplex Protokoll> gibt es ausser dem oberen Link noch weitere Beispiele in asm die ein> halbduplex Protokoll mit STX/ETX verwenden> ich weiss net wie ich anfangen soll, und mit was und wie
Fang damit an, dir ein Protokoll auszudenken.
Was willst du überhaupt machen?
Dann stell dir deine kleine Schwester vor. Die ist zwar brav
aber unheimlich dämlich (soll jetzt keine Beleidigung sein).
Der musst du alles sagen, von alleine macht sie gar nichts.
Aber: Wenn du ihr was sagst, dann macht sie das auch und liefert
ein 'OK' oder irgendeine sonstige Rückmeldung.
Wenn du jetzt der Befehlssender bist und deine Schwester der
Befehlsempfänger, welche Kommandos brauchst du, damit deine
Schwester die gestellte Aufgabenstellung erfüllen kann.
Auch wichtig: Angenommen ihr seid beide (mit ein paar Freunden)
im Raum: Woran kann deine Schwester erkennen, dass jetzt ein
Kommando für sie dabei ist und du nicht einfach so mit deinen
Freunden sprichst.
Im Grunde läuft es meistens auf das gleiche hinaus:
Es gibt ein Zeichen, mit dem wird signalisiert: Hier beginnt
ein Kommando
Es gibt ein Zeichen, mit dem wird signalisiert: Hier endet
ein Kommando
Die beiden Dinge sind wichtig, denn wenn der Befehlsabarbeiter
mitten in eine Übertragung hineinplatzt (Stecker eingesteckt
oder dergleichen), dann muss es für ihn eine Eindeutige
Kennung geben, bis wohin er noch Zeichen aus einer vorhergehenden
Übertragung mitkriegt, und wo denn nun das nächste Kommando
anfängt. Erst wenn er dieses Zeichen empfängt, weiss er, dass
es hier tatsächlich los geht.
Daraus folgt aber auch: Diese Start und Ende Kennzeichnungen
dürfen in der restlichen Übertragung nicht vorkommen. Diese
Zeichen sind ausschliesslich für diesen einen Zweck reserviert:
Den Start und das Ende eines Kommandos zu kennzeichnen.
Und das dazwischen: Denk dir was aus.
Wenn du zb. Relais schalten willst:
Du könntest zb einen String
R10
schicken. Und das heist dann
R Ich möchte ein Relais schalten ...
1 ... und zwar das Relais Nr 1
0 ... das möchte ich ausschalten
Damit da keine Missverständnisse aufkommen.
<STX>/<ETX> kann man zur Start/Stop Synchronisierung benutzen,
muss aber nicht. Du kannst dir auch selbst etwas ausdenken.
Zb. wird auch gerne sowas benutzt
Es gibt kein <STX>/<ETX>. Wann immer der Sender ein Kommando
senden will, dann tut er das (der Empfänger darf nur nach
Aufforderung senden), allerdings beendet der Sender jedes
Kommando mit einem speziellen Zeichen. Das kann zb. ein ';'
sein oder der allseits beliebte 'Return'.
Das wichtige daran ist: Du machst das so wie du es haben
willst und wie du dir am leichtesten tust. Es gibt kein
richtig/falsch. Was du dir ausdenkst ist per Definition
richtig solange es den gestellten Zweck erfüllt.
dankeschön karl heinz;) für deine so schöne Erklärung,
Meine Aufgabe ist es. eine
bestehende parallele Schnittstelle die über SPI realisiert ist durch die
RS232 ersetzen.
Sprich nicht mehr üer SPI sonder über das UART,
und das ganze wird durch LabView angesteuert, sprich ich steuere meine
RelaisMatrix in LabView und schalte so die gewünschten Relais, dies soll
dann mein UART richtig empfangen, bevor er schalten darf, soll er wieder
zurück an LabView senden dass er richtig empfangen hat und wenn nicht
die Checksumme übereinstimmt dann muss er nochmals warten bis ich über
LabView die Daten senden
Also: ich muss im Programm lediglich noch dieses Start of Text,
Nutzdaten, Checksum und End of Text einfügen, dann müsste es ja klappen
An meinem STK500 hat das senden und empfangen der gesendeten Bytes über
LabView funktioniert halt ohne Protokoll
manuete wrote:
> dankeschön karl heinz;) für deine so schöne Erklärung,>> Meine Aufgabe ist es. eine> bestehende parallele Schnittstelle die über SPI realisiert ist durch die> RS232 ersetzen.> Sprich nicht mehr üer SPI sonder über das UART,>> und das ganze wird durch LabView angesteuert, sprich ich steuere meine> RelaisMatrix in LabView und schalte so die gewünschten Relais, dies soll> dann mein UART richtig empfangen, bevor er schalten darf, soll er wieder> zurück an LabView senden dass er richtig empfangen hat und wenn nicht> die Checksumme übereinstimmt dann muss er nochmals warten bis ich über> LabView die Daten senden>
AH. OK.
Das heist dann aber auch: Das Protokoll steht bereits
und du musst es nur noch ... was den nu? Schreibst du
den Sender oder den Empfänger?
> Also: ich muss im Programm lediglich noch dieses Start of Text,> Nutzdaten, Checksum und End of Text einfügen, dann müsste es ja klappen>
Das klingt jetzt mehr nach:
Du programmierst am Sender. Musst also die richtigen Bytes in
der richtigen Reihenfolge auf den Weg bringen.
Jetzt hab ich den Faden verloren :-)
> An meinem STK500 hat das senden und empfangen der gesendeten Bytes über> LabView funktioniert halt ohne Protokoll
Na ja. ist doch schon was!
"AH. OK.
Das heist dann aber auch: Das Protokoll steht bereits
und du musst es nur noch ... was den nu? Schreibst du
den Sender oder den Empfänger?"
Nein das Protokoll steht nicht;)
Da es vorher so ablief:
Die Dateneingabe gigen über ne Data-Schnittstelle PortA des
Mikrocontrollers und über PortB wurde die SPI sprich MOSI, MISO über
/ss (Pin4) des Port aktiviert, also die Datenübertragung
Und jetzt muss ich es halt mit der RS232 und einen MAX232 ersetzen,
Vorher kamen die Daten parallel und jetzt sollen sie seriell übertragen
eben über dieses UART, und dazu verwendet man eben statt PortB -->Port D
Pin PD0(RXD) und Pin PD1(TXD)
und ich muss es in meinem Assemblerprogramm diese SPI-Schnittstelle
ersetzen, und dieses neue RS232-Protokoll einfügen, die Datenübertragung
soll aber weiterhin sicher sein...
die LabView - Ansteuerung sendet an das UDR des UART insgesamt 11 BYTES,
STX,8mal Nutzdaten, Checksumme und ETX (=11Bytes)
Der Mikrocontroller empfängt die 11 DAtenbytes und errechnet ebenfalls
die CS der empfangenen Nutzdaten, und sendet 3Bytes zurück an die
LabView Anwendung. STX,Nutzdaten FF= Ja, ETX -->3BYTES
Zumindestesn habe ich es mir so gedacht, nur habe ich keinen Plan wie
ich das in dem Code oben einfügen kann
OK. Ich denke ich verstehe jetzt ein bischen besser.
Ja. Eine Statusmaschine für den Empfang, wie oben
angedacht, wäre eine Möglichkeit.
Welche Zustände gibt es denn?
* Zustand: Ausgangsposition.
Es liegt kein Kommando vor
Bezeichnung: INIT
* Zustand: Zeichen werden gesammelt
Bezeichnung: COMMAND
* Zustand: Fehler
Bezeichnung: FEHLER
Dann musst du dir noch überlegen, wie denn der Übergang
der Maschine von einem Zustand zum nächsten erfolgt.
Klarerweise wird ein Zustandsübergang durch den Empfang
eines Zeichens ausgelöst. Aber welche Zeichen führen
zu welchem neuen Zustand
Zustand empfangenes Zeichen neuer Zustand
INIT <STX> COMMAND
alles andere INIT
COMMAND <ETX> INIT
alles andere COMMAND
FEHLER <ETX> INIT
Fehlen nur noch die Aktionen, die bei jedem Zustandswechsel
durchgeführt werden sollen:
INIT alles andere keine Aktion INIT
<STX> Commandobuffer vorbereiten COMMAND
Anmerkung: INIT ist der Grundzustand. Der Sinn dieses
Zustands ist es, auf das <STX> Zeichen zu warten,
welches den Beginn eines Kommandos einleitet. Wird
es angetroffen, so wird alles zur Zwischenspeicherung
des Kommandos vorbereitet und in den Zustand COMMAND
übergewechselt.
COMMAND <ETX> Auswertung INIT
alles andere empf. Zeichen speichern COMMAND
Anmerkung: beim Speichern des Zeichens kann es natürlich
passieren, dass mehr als 9 Bytes empfangen werden.
In so einem Fall wird dann das empfangene verworfen
und in den Zustand FEHLER gewechselt
Nach dem Empfang von ETX kann die Auswertung erfolgen.
ETX kann nur erreicht werden, wenn weniger oder exakt
9 Bytes empfangen wurden. D.h. man wird hier mal
überprüfen, ob das auch genau 9 Bytes waren. Weiters
wird man prüfen, ob die Checksumme stimmt.
Ist eine der beiden Prüfungen negativ, so wird der
Sender benachrichtigt und sofort in den Zustand INIT
gewechselt (und damit auf den Beginn des nächsten
Kommandos gewartet).
Sind beide Bedingungen erfüllt, wird der Sender
über den korrekten Empfang benachrichtigt und
das Kommando zur Weiterverarbeitung freigegeben.
Danach geht es wieder in den Zustand INIT
FEHLER <ETX> INIT
alles andere empf. Zeichen verwerfen FEHLER
Anmerkung: Der Sinn des Zustands FEHLER ist es, alle
Zeichen zu überlesen, bis der ETX empfangen wird.
Der Sender wird über den Fehlerfall informiert
und es geht wieder ab in den Zustand INIT
Tja. So oder so ähnlich könnte deine State-maschine aussehen.
Der Zustand (Status) ist einfach nur eine Variable. Je nachdem
in welchem Zustand die Maschine ist, hält sie unterschiedliche
Werte ( zb. 0 = INIT, 1 = FEHLER, 2 = COMMAND, etc.. )
Wenn ein Zeichen über die Serielle Schnittstelle hereinkommt,
dann sieht die Empfangsfunktion nach, welcher Zustand gerade
anliegt und verzweigt dann in Programmteile, die die beschriebene
Funktionalität realisieren. Steht ein Zustandswechsel an, dann
schreibt die ausführende Funktion einfach nur einen neuen Wert
in diese Status Variable hinein.
im Befehlsatz vom AT90S8515 habe ich keine XOR-Verknüfung gefunden, nur
eine OR-Verknüpfung, könnte ich das auch für die Checksummen Überprüfung
anwenden, oder net
Denk nach.
Wenn du nur genügend unterschiedliche Bytes miteinander OR
verknüpfst, dann wird da meistens 0xFF (also alle Bits gesetzt)
herauskommen.
Nicht besonders sinnvoll für eine Prüfsumme.
manuete wrote:
> im Befehlsatz vom AT90S8515 habe ich keine XOR-Verknüfung gefunden, nur> eine OR-Verknüpfung, könnte ich das auch für die Checksummen Überprüfung> anwenden, oder net
EOR? Einfach aufmerksam lesen... ;)
Hi an alle,
habe hier mal mein Protokoll versucht...
Wenn ich es mit meinem STK500 teste, dann funkts net so ganz auf Anhieb,
sprich es könnte sein das ich meine Checksumme die ich vom LabView
bekomme und im AT90S8515 vergleiche nicht richtig berechne, was ich
nicht denke;)
Oder liege ich mit dieser Vorgehensweise total falsch???
> dann funkts net so ganz auf Anhieb,
Das ist eigentlich ziemlich normal, dass Dinge nicht auf Anhieb
funktionieren. Kein Grund zu verzweifeln.
Hast du schon mal probiert, die Bytes die du vom LabView
kriegst mitzuprotokollieren und mal händisch (auf Papier)
die Checksumme auszurechnen? Wenn du das hinkriegst und
auch alle Zwischenergebnisse auf dem Papier kennst, kannst
du hergehen und im Simulator mal diese Bytes einspeisen
und den Programmfluss verfolgen und nachsehen, ab welchem
Zwischenergebnis das Programm zu falschen Werten kommt und,
noch viel wichtiger, wo dein Denkfehler liegt.
hi karl;)
ist ja süss das du mir so schnell antwortest...
mit Anhieb meinte ich, wenn ich es teste, muss ich an meinem STKBoard
öfters was von LabView schicken damit ich was zurücksende
Yep hab ich gemacht, also die CS berechnet bei FFFF FFFF FFFF FFFFF ist
sie 0...
haa sprich ich könnte mein Programm so ändern, dass ich nix einlese
sondern einfach diese 8Bytes Schritt für Schritt auswerte, versuch ich
jetzt mal;) dankeschön
manuete wrote:
> hi karl;)> ist ja süss das du mir so schnell antwortest...>> mit Anhieb meinte ich, wenn ich es teste, muss ich an meinem STKBoard> öfters was von LabView schicken damit ich was zurücksende>> Yep hab ich gemacht, also die CS berechnet bei FFFF FFFF FFFF FFFFF ist> sie 0...
Nimm besser 8 reale Bytes die du vom LabView bekommst.
Im Web findest du Programme die 'serial Port Monitor' heissen.
Die klinken sich auf deinem PC zwischen Programm und serieller
Schnittstelle ein und protokollieren jeglichen Datenverkehr
mit. Dort kannst du zb. vergleichen ob das, was dein µC empfängt
identisch ist mit dem was am PC gesendet wird (ist nicht so
selbstverständlich wie es jetzt klingt). Auch kann man damit
ganz schnell einen Testdatensatz zu Debug-Zwecken abgreifen.
> haa sprich ich könnte mein Programm so ändern, dass ich nix einlese> sondern einfach diese 8Bytes Schritt für Schritt auswerte, versuch ich> jetzt mal;)
Yep.
Endlich mal wer, der nicht davor zurückschreckt sein in stundenlanger,
mühsamer Arbeit erstelltes Programm zu debugzwecken auch mal zu
verändern.
hmmm:) das sind eigentlich 8 Reale Bytes die ich vom LabView schicke
02FF FFFF FFFF FFFF FF00 03
das gebe ich in LabView "Basic Serial Write an Read.Vi Panel" write
string ein
dann kommt im LabView read string zurück:
02FF 03
Bei meinem Code, kommt leider noch manchmal bei der selben Eingabe, mal
das und 02FF 0302 FF03 --> egal ob die Checksumme richtig ist oder
net...
sprich ich über LabView:
02FF FFFF FFFF FFFF FF11 03 schicke, und eigentlich 0200 03 erwarte, für
Checksumme nicht Ok, laut meinem Code:
Natürlich ist
Baudrate, data bits und COM usw richtig eingestellt in LabView, damit
die Kommunikation richtig funkt.
"Yep.
Endlich mal wer, der nicht davor zurückschreckt sein in stundenlanger,
mühsamer Arbeit erstelltes Programm zu debugzwecken auch mal zu
verändern."
und das hat gewirkt, habe alle Fehler beseitigt, waren ein paar
Kleinigkeiten bezüglich des Pointers und des Pointers laden;)
zumindestens ganze Feste 11Bytes werden in diesem Protokoll
berücksichtigt...
supi, dankeschön für den Tipp, hat ein wenig gedauert aber hab es ja
noch hingekriegt nach ein paar Stunden;)