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
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)
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).
ich hab das jetzt mal über esc-sequencen gelöst, das tut auch soweit ganz gut. es lebe die modularisierung ;-)
Was soll denn bei itoa mit 0x00 passieren? Das ist doch kein druckbares Zeichen...
>Was soll denn bei itoa mit 0x00 passieren? Das ist doch kein >druckbares Zeichen... Aber "0" ist ein druckbares Zeichen. itoa konvertiert doch integer in einen String.
ja, itoa bildet die textrepräsentation eines integers, also nicht das zeichen 0x00 sondern den String "0"
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.
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
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?
Schreib am anfang des strings die länge des Strings. Dann sendest du soviele Zeichen wie am anfang des Strings angegeben ist.
1 | char *zeichenkette = "\x09\x10\x02\x68\x00\xff\x10\x03\x8c" ; |
2 | |
3 | |
4 | void uart1_puts(const char *s ) |
5 | {
|
6 | int tmp = *s; |
7 | int count = 0; |
8 | while (count != tmp) |
9 | uart1_putc(*s+count++); |
10 | |
11 | }
|
sowas in der Art vielleicht?
Kann man die Länge der Zeichenkette nicht irgendwie in der Funktion ermitteln? Endet *s denn nie?
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.
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.
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 | }
|
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 ));
Schreib halt eine eigene "putx" Funktion, die bis zu einem anderen Terminierungszeichen als 0x00 geht. Wenn du kein Zeichen ausschließen kannst, dann gehts nur über die Nachrichtenlänge.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.