Hallo Freunde,
ich sitze vor einem Problem, ich möchte eine Structur per Uart Versenden
aber es klappt nicht.
1
volatilestruct
2
{
3
charstart;
4
uint8_tlen;
5
doubleTemp_array[3];
6
charend;
7
}proto,Proto;
8
9
Proto.start=0x02;
10
Proto.end=0x03;
11
Proto.len=sizeof(Proto.Temp_array);
12
13
voidTransmit(void*cData,uint8_tlen)
14
{
15
while(len-->0)
16
{
17
uart_putc(*(char*)cData);// shift out data
18
cData++;
19
}
20
21
}
22
voidmain(int)
23
{
24
while(1)
25
{
26
_delay_ms(500);
27
Transmit(Proto.start,sizeof(Proto));
28
}
29
}
Leider kommt nur Müll aus der Uart raus .
Die Uart Fuktion von Peter Fleury fuktioniert sonst bestens es liegt
also an meiner Trasmit Funktion.
Ich komme aber nicht auf den Fehler Bitte helft mir !
Danke gruß
Fridrich
Der UART versendet einzelne Bytes.
also die struct in Bytes zerlegen, die einzeln übertragen und
dann beim Empfänger wieder passend zusammenbauen.
Senden in etwa so:
damit klar ist, dass der Pointer um ein Byte erhöht werden soll.
fridrich schrieb:> Transmit(Proto.start,sizeof(Proto));
So:
1
Transmit(&Proto.start,sizeof(Proto));
oder besser:
1
Transmit(&Proto,sizeof(Proto));
weil die Adresse der Struktur gemeint ist.
Bedenklich ist:
fridrich schrieb:> volatile struct
was darauf hindeutet, dass die Inhalte der Struktur aus einer ISR heraus
modifiziert werden. Wenn das mitten in der Übertragung passiert, dann
empfängst du evtl. inkonsistente Daten.
fridrich schrieb:> Hallo Freunde,> ich sitze vor einem Problem, ich möchte eine Structur per Uart Versenden> aber es klappt nicht.
Bedenke, dass die Datenstruktur auf Quell- und Zielsystem verschieden
aufgebaut sein kann. Das fängt mit dem Alignment an und geht dann über
den CPU-Endian bis hin zum (möglich verschiedenen) Format eines
double-Wertes.
Eine portable Übertragung geht nur über eine ASCII-Präsentation der
einzelnen Struct-Member.
Konrad S. schrieb:> fridrich schrieb:>> cData++;> Besser: ((char *)cData)++;> damit klar ist, dass der Pointer um ein Byte erhöht werden soll.
Nein. Das ergibt einen Fehler, da man das Ergebnis eines Casts nicht
inkrementieren kann. Wäre auch irgendwie sinnlos.
Noch so am Rande:
fridrich schrieb:> void main(int)
Das gehört umgedreht:
Rolf Magnus schrieb:> Nein. Das ergibt einen Fehler, da man das Ergebnis eines Casts nicht> inkrementieren kann. Wäre auch irgendwie sinnlos.
Ok, das sehe ich ein. Scheint so, als hätte ich so eine Konstruktion
noch nie eingesetzt seit der gcc das überprüft. Erstaunlich.
Konrad S. schrieb:> Ok, das sehe ich ein. Scheint so, als hätte ich so eine Konstruktion> noch nie eingesetzt seit der gcc das überprüft. Erstaunlich.
Das ist bestimmt der Optimierung zum Opfer gefallen ;)
Hallo,
ich muss das nochmal aufwärmen. Ich hänge am gleichen Problem, kann
lesen wie ich möchte, ich weiß nicht wo der Fehler liegt. Der Datentyp
passt nicht. So verstehe ich das jedenfalls. Nur was muss ich anders
machen? Kann mir bitte jemand helfen? Ich nutze ebenfalls die uart Lib
vom Peter Fleury.
1
structNachricht{
2
uint8_tadress=0;
3
uint8_tfunction=0;
4
uint8_twert=0;
5
}message;
Deklaration:
1
voidsendStruct(uint8_t*structPtr,uint8_tlength);
Aufruf:
1
message.adress=78;
2
message.function=135;
3
message.wert=207;
4
sendStruct(&message,sizeof(message));
Funktion:
1
voidsendStruct(uint8_t*structPtr,uint8_tlength)
2
{
3
while(length-->0)
4
{
5
uart_putc(*structPtr);// Bytes rausschieben
6
structPtr++;
7
}
8
}
Fehlermeldungen: die Zeile 534 bezieht sich auf den Aufruf
1
Fehler
2
cannot convert 'Nachricht*' to 'uint8_t* {aka unsigned char*}' for argument '1' to 'void sendStruct(uint8_t*, uint8_t)'
3
C:main.cpp 534
4
Fehler
5
recipe for target 'main.o' failed
6
Makefile 86
7
8
Warnung
9
non-static data member initializers only available with -std=c++11 or -std=gnu++11
10
main.cpp 130
11
Warnung
12
non-static data member initializers only available with -std=c++11 or -std=gnu++11
13
main.cpp 131
14
Warnung
15
non-static data member initializers only available with -std=c++11 or -std=gnu++11
sendStruct erwartet einen Zeiger auf uint8_t, Du übergibst aber einen
Zeiger auf struct Nachricht. Du musst also irgendwo den Zeiger auf
struct Nachricht in einen Zeiger auf uint8_t konvertieren aka "casten".
Du hast zwei Möglichkeiten:
1. Du konvertierst den Zeiger vor dem Aufruf von sendStruct.
2. Du änderst die Funktion sendStruct, so dass sie einen Zeiger auf
struct Nachricht nimmt statt auf uint8_t. Dann musst Du den Zeiger
innerhalb von sendStruct konvertieren. Aber Vorsicht: Sowohl der Zeiger,
den Du an uart_putc übergibst, als auch der Zeiger, der in der Schleife
inkrementiert wird, muss von Typ uint8_t sein.
Die Warnungen gehen weg, wenn Du das "= 0" in der Deklaration von struct
Nachricht weglässt.
PS: Der Mischmasch aus Deutsch und Englisch im Code liest sich
grauenvoll.
Hallo,
wegen den Warnungen. Seit wann darf man die Structur Variablen nicht
initialisieren?
deutsch englisch, ich weiß immer nicht wie ich die sinnvoll benennen
soll.
Typcast habe ich jetzt im Funktionsaufruf gemacht. Danke.
1
structNachricht{
2
uint8_tadresse;
3
uint8_tfunktion;
4
uint8_twert;
5
}daten;
Deklaration:
1
voidsendStruct(uint8_t*structPtr,uint8_tlength);
Aufruf:
1
daten.adresse=78;
2
daten.funktion=135;
3
daten.wert=207;
4
sendStruct((uint8_t*)&daten,sizeof(daten));
Funktion:
1
voidsendStruct(uint8_t*structPtr,uint8_tlength)
2
{
3
while(length-->0)
4
{
5
uart_putc(*structPtr);// Bytes rausschieben
6
structPtr++;
7
}
8
}
es wird alles fehlerfrei kompiliert.
Leider aber!
Statt der ersten 78 wird ein N übertragen. Übertragen wird
N '135' '207'
Ändere ich die Daten, ist immer wieder der erste Wert falsch.
Was ist da los?
Veit D. schrieb:> Hallo,>> wegen den Warnungen. Seit wann darf man die Structur Variablen nicht> initialisieren?
Das darf und durfte man in C in der Form, wie Du es hingeschrieben hast,
noch nie. In C++ darf man es seit C++11.
Es geht aber folgendermaßen:
1
structNachricht{
2
uint8_tadresse;
3
uint8_tfunktion;
4
uint8_twert;
5
}daten={0,0,0};
Oder wenn man Deklaration und Definition trennt:
1
structNachricht{
2
uint8_tadresse;
3
uint8_tfunktion;
4
uint8_twert;
5
};
6
7
structNachrichtdaten={0,0,0};
Oder kürzer, aber gleichbedeutend:
1
structNachrichtdaten={0};
> Leider aber!> Statt der ersten 78 wird ein N übertragen. Übertragen wird> N '135' '207'> Ändere ich die Daten, ist immer wieder der erste Wert falsch.> Was ist da los?
Na dann passt es doch. 'N' ist gleichbedeutend mit 78, siehe
ASCII-Tabelle. Wenn Du den Zahlenwert sehen willst, musst Du die
Formatierung der Ausgabe auf Empfängerseite umstellen.