0x00 über UART übertragen

Gast #206829
Lesenswert?

Hallo zusammen,

ich habe bei der suche im Forum keine entsprechenden beiträge zu meinem
problem gefunden, deshalb meine frage:

ich versuche im moment mit dem MEGA16 daten über die serielle
schnittstelle zu übertragen und via i2c weiterzusenden und umgekehrt.
soweit alles kein problem, die übertragung tut in beide richtungen.
*aber*: da es sich um binärdaten handelt, kommt es auch hin und wieder
vor, dass ein byte mit dem wert 0x00 übertragen werden muss.. das kommt
aber nicht an. es wird einfach ignoriert (bevor es an die i2c-routine
geht). meine idee ist jetzt über eine art escape-sequenz das zeichen zu
codieren. also: wenn 0x00 kommt stattdessen zwei bytes mit z.B. "0x01
0x01" zu übertragen und für den wert 0x01 entsprechend "0x01 0x02".
Oder gibt es da eine andere lösung?
Die zielanwendung ist PC-unabhängig aber im moment simuliere ich den
datentransfer mit minicom unter linux. ist das evtl nur ein pc-problem
oder ist das bei RS232/dem atmel uart nicht vorgesehen?

Gruß, Florian
Gast #206830
Lesenswert?

Hallo.
Eine Frage: Wie hast du festgestellt das ein Nullzeichen nicht ankommt
(ich meine jetzt richtung Mikrocontroller->PC) ?
Ich will ausschliesen das es nur daran liegt das Minicom null-zeichen
ignoriert.

Auf meinem PC werden Null-Zeichen übertragern (allen meinen bisherigen
Beobachtungen nach)
Gast #206831
Lesenswert?

hallo martin,
danke für die schnelle antwort.
das problem tritt im moment in die andere richtung auf:
PC sendet, atmel antwortet mit itoa(UDR, tempstring,10), (integer to
string), des übertragenen bytes. alles andere ist im moment
auskommentiert. und da kommt bei einem 0x00-byte nicht mal der
interrupt.
ob bei der richtung atmel->pc das 0x00-problem auftritt habe ich nocht
nicht ausprobiert (müsste den datenstrom in ein file schicken und mit
dem hex-editor anschauen).
Gast #206837
Lesenswert?

Mikrocontroller habe ich bislang nur im asm programmier, kann also
nichts dazu sagen ob es an itoa liegt.
Naja, ich kann dazu noch sagen, dass es eigentlich möglich ist 0x00 zu
senden und zu empfangen.
Dieser Asm-Code (Anhang) wartet auf 8 Zeichen und sendet sie zurück.
Es funktioniert (jedenfalls bei mir) auch wenn es nur nullen sind.
Angehängte Dateien:
Gast #206838
Lesenswert?

okay, danke für die antworten.
das itoa verwende ich im moment nur als mittel zum zweck um
herauszufinden woran es liegt/lag. ich vermute, dass mein
terminal-programm das 0-byte nicht korrekt verwertet und nichts
aussendet. habe heute nacht nochmal ein oszi drangehängt und man sieht
rein garnichts bei 0-bytes... und der interrupt kommt ja auch nicht.
toller effekt auf jeden fall, vor allem wenn man sich wundert warum von
64kbyte nur 63.9Kbyte ankommen, obwohl der atmel zu 99% rum-idlet.

gruß, florian
#1534369
Lesenswert?

Ich hänge mich mal an den alten Thread weil ich gerade vor dem gleichen 
Problem stehe.

Ich möchte eine Zeichenkette aus hexadezimalen Daten zu Peter Fleury's 
UART Lib übertragen:

char *zeichenkette = "\x10\x02\x68\x00\xff\x10\x03\x8c" ;
uart_puts(zeichenkette);

Hier scheitert es daran, dass die Lib das 0x00 als Stringende erkennt 
und nach dem 0x68 zum senden aufhört.

So sieht seine Lib aus:

void uart1_puts(const char *s )
{
    while (*s)
      uart1_putc(*s++);

}

Wie löse ich das am besten, dass die ganze Zeichenkette übertragen wird? 
Soll ich die Zeichen irgendwie anders deklarieren?
#1534471
Lesenswert?

Das Problem ist, dass die Lib auf Strings aufgebaut ist.
Ein String endet aber definitionsgemäs bei einem 0x00 Zeichen.

Was du da hast sind keine Strings. Daher ist die Funktion uart1_puts und 
alle Stringfunktionen ganz einfach die falschen Werkzeuge für das was du 
vor hast.

Um weiter zu kommen, musst du von Strings Abschied nehmen und auf Bytes 
neu aufbauen.
#1534473
Lesenswert?

Igor Ebner schrieb:
> Kann man die Länge der Zeichenkette

Du hast keine Zeichenkette, die den C Regeln für eine Zeichenkette 
genügt.

> nicht irgendwie in der Funktion
> ermitteln? Endet *s denn nie?

Es gibt kein Kriterium dafür.
Daher musst du allen Funktionen, die mit solchen Daten arbeiten immer 
die Länge deiner Bytefolge mitgeben.

Sieh dir den Unterschied in den Familien der str... und mem... 
Funktionen an. Die str... Funktionen sind für Strings. Die mem... 
Funktionen sind für beliebige Bytefolgen.
#1534589
Lesenswert?

Wie ich schon sagte: Du musst die Anzahl der Bytes mitgeben
1
#define ARRAY_SIZE(x)  ( sizeof(x) / sizeof(*x) )
2

3
unsigned char zeichen[] = { 0x10, 0x02, 0x68, 0x00, 0xff, 0x10, 0x03, 0x8c };
4

5
void uart1_put_data( const unsigned char * data, size_t len )
6
{
7
  size_t i;
8

9
  for( i = 0; i < len; ++i )
10
    uart1_putc( *data++ );
11
}
12

13
int main()
14
{
15
  ...
16

17
  uart1_put_data( zeichen, ARRAY_SIZE( zeichen ) );
18

19
  ...
20
}
#1534677
Lesenswert?

Ja, so klappt es auch. Danke dafür. Aber trotzdem ist es schade, dass 
die Funktion nicht selbst erkennt, wie viel Hex Daten man ihr schickt - 
ist kein bequemes schreiben, wie man es z.B. von Peter Fleury's UART Lib 
her kennt:

uart_puts("Hello World");

wäre doch viel schöner als:

uart_puts("Hello World",11);

oder

uart_puts(zeichen, ARRAY_SIZE( zeichen ));

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren