Hallo zusammen,
ich möchte Daten die ich über den UART gesendet bekomme in Variablen
speichern.
Die Daten die gesendet werden sind unterschiedlich lang (max. 10Zeichen)
und ich weiß nicht direkt was gesendet wird, bis auf das es insgesamt 6
Datenpakete sind. Zusammengefasst 10 Zeichen sind und 6 Pakete, jedoch
nicht was in den Paketen steht.
Einmal hatte ich die Idee mit einem Mehrdimensionalen Array[11][7].
Oder mit einem Scruct.
Mein Problem ist, dass ich nicht auf den Trichter kommen, wie ich die
Daten abspeichern soll, also wie ich die Daten in ein Scruct speicher...
typedef struct Data
{
char ch_data_name_one;
char ch_data_page_one;
char ch_data_name_secound;
char ch_data_page_secound;
char ch_data_name_third;
char ch_data_page_third;
}S_Data;
S_Data g_SData;
Grüße
Eberhard schrieb:> Die Daten die gesendet werden sind unterschiedlich lang (max. 10Zeichen)> und ich weiß nicht direkt was gesendet wird, bis auf das es insgesamt 6> Datenpakete sind.
Das ist dein erster Problemkreis.
'Ich weiß nicht' geht schon mal gar nicht. Ein µC ist kein Hellseher, du
genausowenig.
D.h. der Sender muss Steuerinformation mitschicken, mit der er zb
ausdrückt: Jetzt kommt der "Name" und das sind zb 4 Zeichen (oder: jetzt
kommt der "Name" und ich schicke dir dann die Zeichen, wobei ich den
Text mit einem vereinbarten Ende-Kennzeichen abschliesse)
> Einmal hatte ich die Idee mit einem Mehrdimensionalen Array[11][7].> Oder mit einem Scruct.
Kann man beides machen.
In deinem Fall ist ein struct wahrscheinlich schöner.
> Mein Problem ist, dass ich nicht auf den Trichter kommen, wie ich die> Daten abspeichern soll, also wie ich die Daten in ein Scruct speicher...
Wenn du die Steuerinformation empfängst, weißt du was als nächstes
kommt. Die Steuerinformation wird selbst wieder in Variablen gespeichert
und beim Empfang des nächsten Zeichens kann man dann mit dieser
Steuerinformation entscheiden, wo das gerade empfangene Zeichen
hingehört.
Eberhard schrieb:> Verdammt sorry, diese Information hatte ich außer acht gelassen!>> Der Abschluss ist 0x17 = ASCII --> END OF TRANSMISSION
Schön.
Trotzdem brauchst du noch eine 'Einleitung' mit der du dem Empfänger
mitteilst, was als nächstes kommt.
Du musst aus dem Status
> 6 Pakete, jedoch nicht was in den Paketen steht.
raus.
Ich weiß nicht was in einem Paket drinnen ist, geht nicht. Da muss der
Sender eben am Anfang eines Paketes mitteilen: Jetzt kommt der Name, das
nächste Paket enthält die Kontonummer, etc. etc.
> char ch_data[12][6];
Das sind 12 Zeilen mit je 6 Spalten.
D.h. du hast 12 Strings, wobei jeder String aus 6 Bytes bestehen kann.
(Merkregel: der letzte Index läuft am schnellsten)
Zum Rest: Du bist sicher, dass dein s_CmdBuffer bereits alle Zeichen
aller 6 Pakete beinhaltet, wenn diese Funktion aufgerufen wird?
Ich wuerd einen Ringbuffer verwenden und mir in einem Array pointer,
resp indices, in den Ringbuffer hinein halten, die auf den jeweiligen
Anfang einer Meldung zeigen.
> Mein Problem ist, dass ich nicht auf den Trichter kommen, wie ich> die Daten abspeichern soll, also wie ich die Daten in ein Scruct> speicher...
Das geht dann zb mit einer Hilfsfunktion, die den nächsten String aus
dem 'Input' rausholt und in die Stringvariable deiner Wahl umkopiert
Komplizierter geht es wirklich nicht mehr....
Warum machst Du die Prüfung auf Start- und Endzeichen nicht in der
Interrupt-Routine und setzt Dir ein Flag wenn alles im Empfangspuffer
ist.
D.h., das Start- und Endzeichen brauchst Du nicht im Datenpuffer
eintragen.
Beispielsweise so:
1
uart_interrupt_rx()
2
{
3
4
unsignedcharc;
5
6
c=uart_rx_register;
7
8
switch(c){
9
10
caseSTARTSIGN:bufferpointer=cmdbuffer;
11
buffer_set_flag=0;
12
break;
13
caseSTOPSIGN:buffer_set_flag=1;
14
break;
15
16
default:
17
bufferpointer++=c;
18
}
19
}
Da fehlt noch einiges, aber grundsätzlich mache ich das immer SO.
Erstmal vielen Dank für die Beispiele Hilfe Anreize!
Karl Heinz Buchegger schrieb:> while (source[index] != '\0' &&> source[index] != 0x16)
Momentan ist es so, dass ich weiß, nach einem 0x16 ist der ersten
Datensatz fertig und der nächste kommt dran, hier wird geprüft ob ein
0x16 und ein \0 angekommen ist. \0 ist ja nur dann wenn ich ein String
abschließen will oder der Datensatz komplett übertragen wurde.
Eberhard schrieb:> Erstmal vielen Dank für die Beispiele Hilfe Anreize!>> Karl Heinz Buchegger schrieb:>> while (source[index] != '\0' &&>> source[index] != 0x16)>> Momentan ist es so, dass ich weiß, nach einem 0x16 ist der ersten> Datensatz fertig und der nächste kommt dran, hier wird geprüft ob ein> 0x16 und ein \0 angekommen ist.
Nein.
Du hast die ! nicht bedacht.
Die Schleife läuft so lange, so lange das nächste Zeichen weder ein \0
noch ein 0x16 ist. Mit anderen Worten, solange das alles ganz normale
Zeichen sind, läuft die Schleife. Erst beim nächsten \0 bzw. 0x16 bricht
die Schleife ab, je nachdem was dann eben gerade vorliegt.
Karl Heinz Buchegger schrieb:> Nein.> Du hast die ! nicht bedacht.> Die Schleife läuft so lange, so lange das nächste Zeichen weder ein \0> noch ein 0x16 ist. Mit anderen Worten, solange das alles ganz normale> Zeichen sind, läuft die Schleife. Erst beim nächsten \0 bzw. 0x16 bricht> die Schleife ab, je nachdem was dann eben gerade vorliegt.
Ja habe es selbst gemerkt!
Das ist wirklich genial! Prinzipiell versucht ich immer selbst auf sowas
zu kommen, aber wenn man C nur mit Probieren und GCC Tutorial lernt,
stößt man oft an seine Grenzen!
Eberhard schrieb:> Karl Heinz Buchegger schrieb:>> Nein.>> Du hast die ! nicht bedacht.>> Die Schleife läuft so lange, so lange das nächste Zeichen weder ein \0>> noch ein 0x16 ist. Mit anderen Worten, solange das alles ganz normale>> Zeichen sind, läuft die Schleife. Erst beim nächsten \0 bzw. 0x16 bricht>> die Schleife ab, je nachdem was dann eben gerade vorliegt.>> Ja habe es selbst gemerkt!> Das ist wirklich genial! Prinzipiell versucht ich immer selbst auf sowas> zu kommen, aber wenn man C nur mit Probieren und GCC Tutorial lernt,> stößt man oft an seine Grenzen!
De Morgan Regel
1
nicht( A oder B ) <==> ( nicht A ) und ( nicht B )
1
A ist das Zeichen ein \0
2
B ist das Zeichen in 0x16
1
NICHT( ist das Zeichen ein \0 ODER ist das Zeichen ein 0x16 )
in 'Deutsch' übersetzt: "wenn nicht gilt, dass das Zeichen ein \0 oder
ein 0x16 ist" ... dann kann es keines von beiden sein.
mit De Morgan wird daraus
1
NICHT( ist das Zeichen ein \0 ODER ist das Zeichen ein 0x16 )
2
3
<==>
4
5
(ist das Zeichen NICHT \0) UND (ist das Zeichen NICHT 0x16)
Amateur schrieb:> Pass' aber auf, wenn "asynchron" der Stecker gezogen wird.> Sonst wartet irgendjemand schon mal auf das Ende des begonnenen> Datenpaketes.
Das wäre äußerst ungünstig das stimmt!
Guten Abend zusammen,
ich habe in dem Code noch ein paar Sachen angepasst.
Vielen Dank noch mal für die Hilfe!
Hier erstmal der Struct:
typedef struct Data
{
char ch_data_name_one[12];
char ch_data_page_one[12];
char ch_data_name_secound[12];
char ch_data_page_secound[12];
char ch_data_name_third[12];
char ch_data_page_third[12];
}S_Data;
S_Data g_SData;
uint8_t NextString( char *target, char *source, uint8_t index )
{
while (source[index] != '\0' && source[index] != 0x17)
{
*target = source[index];
target++;
index++;
}
*target = '\0';
index++;
return index;
}
void get_data(void)
{
uint8_t index = 0;
index = NextString(&g_SData.ch_data_name_one, &s_CmdBuffer, index);
index = NextString(&g_SData.ch_data_page_one, &s_CmdBuffer, index);
index = NextString(&g_SData.ch_data_name_secound, &s_CmdBuffer, index);
index = NextString(&g_SData.ch_data_page_secound, &s_CmdBuffer, index);
index = NextString(&g_SData.ch_data_name_third, &s_CmdBuffer, index);
index = NextString(&g_SData.ch_data_page_third, &s_CmdBuffer, index);
}
Wenn ich jetzt eine Zeichekette senden möchte, angenommen "bla"
muss ich ja am Ende des Zeichenkette ein 0x17 mit schichen, damit ich
weiß, dass es hier zu Ende ist.
In C kann ich das ja nicht einfach hinten anhängen zudem ist es ja ein
Char 0x17 also 8 Bit.
hw_rs232_send_string("bla (\)ETB" );
So habe ich es schon versucht, leider ohne Erfolg.
Stefan Ernst schrieb:> ...("bla\x17");oder#define ETB "\x17">> ...("bla"ETB);
Danke für die Antwort, aber genau soweit war ich schon.
Es wird ausgegeben...
---> (4x16 LCD)
bla bla bla bla bla
bla bla bla bla
bla
usw. also irgendwie stimmt da was noch nicht so ganz.
Eberhard schrieb:> Stefan Ernst schrieb:>> ...("bla\x17");oder#define ETB "\x17">>>> ...("bla"ETB);>> Danke für die Antwort, aber genau soweit war ich schon.> Es wird ausgegeben...>> ---> (4x16 LCD)>> bla bla bla bla bla> bla bla bla bla> bla>> usw. also irgendwie stimmt da was noch nicht so ganz.
Ja das ist meistens so, dass Programme nicht so ganz auf Anhieb
funktionieren. Dann betritt man die Phase die man 'Debuggen' nennt.
-> Erst mal feststellen, ob beim Empfänger hbei der Auswertung hier in
der Funktion der String überhaupt so aussieht, wie er aussehen sollte.
PS: zum Debuggen kannst du ja auch das 0x17 erst mal durch ein anderes
Zeichen ersetzen, zb ein '*'. Denn im Prinzip ist es ja wurscht, welches
Zeichen (welchen ASCII Code) du nimmst, solange der in den Nutzdaten
nicht vorkommt. Und zb ein '*' hat den Vorteil, dass du im Debugger
keine Probleme mit Strings hast, die irgendwelche nicht darstellbare
'Sonderzeichen' beinhalten.
Läuft alles, dann kann man den '*' ja wieder durch 0x17 austauschen.
das if nicht gesehen oder hast du das absichtlich rausgeworfen.
Dieses if hat seinen Grund: Es soll verhindern, dass index hinter den
Eingangsstring laufen kann, wenn im Eingangsstring irgendwas schief
läuft und zb gar keine 6 Pakete enthalten sind.