Forum: Mikrocontroller und Digitale Elektronik µC zu schnell bzw. USART zu langsam


von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Ich bin auf der suche nach einer schöneren Lösung als ein stumpfes 
delay()

Ich habe einen Atmega2560 mit 4 USARTs, der µC wird über einen USART 
gesteuert und hat an 2 weiteren USARTs externe Geräte. Die externen 
Geräte erhalten über den Steuer-USART ihre Befehle, dazu wird den 
Befehlen ein @0 oder @3 vorangestellt.

Wenn die externen Geräte selbst etwas senden, stellt die Software im µC 
den Daten ebenfalls ein @0 oder @3 vor.

Die komplette USART-Übertragung läuft mit Interrupts und FIFO-Speichern.
Ich habe nun das Problem, dass die Hauptschleife die eingehenden Daten 
schneller verarbeitet als neue Daten nachkommen.
Wenn das externe Gerät "Test" sendet, wird "@3T@3e@3s@3t" ausgegeben.

Die Kennung brauche ich damit die Software auf dem PC unterscheiden kann 
von welchem Gerät die Daten kommen.
Handshake oder warten auf Abschlusszeichen geht leider auch nicht, da 
die Geräte keine Handshake-Leitungen haben und auch unterschiedliche 
Geräte angeschlossen werden können.

Was bisher funktioniert ist ein Delay nach jedem kopierten Zeichen. Das 
bremmst sowohl die Hauptschleife als auch die serielle Kommunikation aus 
:/

Hier mal der Teil der Hauptschleife um die es geht.
1
        // Eingehende Daten der USARTs über TCP versenden.
2
        // Gegenrichtung in ethertest.c zu finden.
3
        // Ist kein Ethernet verfügbar, erfolgt die Steuerung über den USART fürs Debuggen.
4
        if (HWConfig[1] & HW_ETHERNET) {
5
            for (i = 0; i < 8; i++) {
6
                if (comConnections[i].status != 0 && comConnections[i].wait_ACK == 0) {
7
                    if (readyToRead(&(comConnections[i].com->rx_buffer))) {
8
                        usart2tcp(comConnections[i].com, comConnections[i].tcp_entry);
9
                        comConnections[i].wait_ACK = 1;
10
                    }
11
                    if (comConnections[i].com->setting.flow == FLOW_RTS_CTS) {
12
                        comConnections[i].com->cts();
13
                    }
14
                }
15
            }
16
        } else {
17
            for (i = 0; i < 4; i++) {
18
                if (availCOM & (1 << i)) {
19
                    switch(i) {
20
                    case 0:
21
                        com = &com0;
22
                        break;
23
                    case 1:
24
                        com = &com1;
25
                        break;
26
                    case 2:
27
                        com = &com2;
28
                        break;
29
                    case 3:
30
                        com = &com3;
31
                        break;
32
                    }
33
34
                    // USART Steuerung/Debug nicht überprüfen, da die Daten weiter unten verarbeitet werden.
35
                    if (d_com != com) {
36
                        // Daten im Empfangspuffer ?
37
                        if (readyToRead(&(com->rx_buffer))) {
38
                            // Platz im Sendepuffer?
39
                            if (!readyToWrite(&(d_com->tx_buffer)))
40
                                d_com->flush();
41
42
                            // USART-Kennung für die Prüfsoftware senden
43
                            writeByte('@', &(d_com->tx_buffer));
44
                            writeByte('0' + i, &(d_com->tx_buffer));
45
                        } else {
46
                            break;
47
                        }
48
49
                        // Empfangene Daten in den Ausgangspuffer schreiben
50
                        while (readyToRead(&(com->rx_buffer))) {
51
                            // Platz im Sendepuffer?
52
                            if (!readyToWrite(&(d_com->tx_buffer)))
53
                                d_com->flush();
54
55
                            writeByte(readByte(&(com->rx_buffer)), &(d_com->tx_buffer));
56
                            _delay_ms(5.0);  <<< Um dieses delay geht es!
57
                        }
58
59
                        // Ausgangspuffer leeren.
60
                        d_com->flush();
61
                    }
62
                }
63
            }
64
        }
Das Projekt ist schon etwas größer, deshalb hänge ich es vorerst mal 
nicht mit an.

Was ich eigtl. bräuchte währe ein Flag welches anzeigt, dass gerade 
Daten emfangen werden.

Vielleicht hat jemand von euch noch eine Idee was ich machen könnte.

von Uwe (Gast)


Lesenswert?

Und was soll passiert wenn beide Geräte gleichzeitig senden ?
Also :
@3Test
@0Hallo
dann
@3Te@0Halstlo
besser wäre wohl
@3Test@0Hallo
Dann mußt du aber den einen puffern wenn der andere gerade sendet, und 
woher weißt du das ernicht mehr sendet ohne Steuerzeichen für das Ende ?
Da würde doch die jetzige Version vorziehen :
@3T@3e@0H@0a@0l@3s@3t@0l@0o
da kann nichts durcheinander kommen. Mußt du halt auf dem PC wieder 
zusammenbasteln.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Weis ja nich was an Geräten drannehängt, aber die haben doch sicher ne 
Kennung wann die Nachricht abgeschlossen ist.
Daher erst wiedern @ vorhängen wenn dieser Abschluss vorkam.

Vllt auch noch komplett Zwischenspeichern um Kollisionen zu vermeiden.

von Uwe (Gast)


Lesenswert?

Oder du machst jedem UART einen eigenen Puffer für RX und  TX und mußt 
halt mit Timeout erkennen wenn jemand nicht mehr sendet. Das m it dem 
Timeout ist aber doof.

von Falk B. (falk)


Lesenswert?

@  M. K. (avr-frickler) Benutzerseite

>Die komplette USART-Übertragung läuft mit Interrupts und FIFO-Speichern.

Klingt gut.

>Ich habe nun das Problem, dass die Hauptschleife die eingehenden Daten
>schneller verarbeitet als neue Daten nachkommen.

Kaum, dann dann wäre es kein FIFO.

>Wenn das externe Gerät "Test" sendet, wird "@3T@3e@3s@3t" ausgegeben.

Dann hast du einen Programmierfehler.

>Die Kennung brauche ich damit die Software auf dem PC unterscheiden kann
>von welchem Gerät die Daten kommen.
>Handshake oder warten auf Abschlusszeichen geht leider auch nicht, da
>die Geräte keine Handshake-Leitungen haben und auch unterschiedliche
>Geräte angeschlossen werden können.

Müssen sie auch nicht. Du musst meldungsbasiert denken und arbeiten, 
nicht zeichenbasiert.

>Was bisher funktioniert ist ein Delay nach jedem kopierten Zeichen.

Delay ist meistens eine Zeichen für Murks.

> Das
>bremmst sowohl die Hauptschleife als auch die serielle Kommunikation aus
>:/

Macht man so nicht, sondern Multitasking. Ist gar nicht so schwer.

>Was ich eigtl. bräuchte währe ein Flag welches anzeigt, dass gerade
>Daten emfangen werden.

Nö, keineswegs. Du musst interruptgesteuert komplette Meldungen 
empfangen und dann per Flag den anderen Programmteilen (= 
statemachine) das mitteilen, dort kann dann die Meldung komplett 
verarbeitet werden.

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Uwe schrieb:
> Und was soll passiert wenn beide Geräte gleichzeitig senden ?
> Also :
> @3Test
> @0Hallo
> dann
> @3Te@0Halstlo
Nein das kann nicht passieren, in diesem Fall sähe das so aus: 
@3Te@0Hal@3st@0lo

> besser wäre wohl
> @3Test@0Hallo
Das währe mein Wunschergebniss!

Uwe schrieb:
> Dann mußt du aber den einen puffern wenn der andere gerade sendet, und

Die UARTs haben alle 2(RX/TX) eigene Puffer(FIFO). Der RXC-Interrupt 
stellt die Daten immer in den RX-Puffer und der UDRE-Interrupt sendet 
die Daten aus dem TX-Puffer.

> woher weißt du das ernicht mehr sendet ohne Steuerzeichen für das Ende ?
Wissen tue ich das nicht, ich schreibe einfach nur alle Daten aus den 
Empfangspuffer raus bis der Puffer leer ist. Durch das Delay verzögere 
ich das senden nur soweit das nach dem Delay das nächste Zeichen im 
Puffer steht. Ist der Puffer nach dem Delay immer noch leer, springe ich 
zum nächsten USART.

Uwe schrieb:
> Da würde doch die jetzige Version vorziehen :
> @3T@3e@0H@0a@0l@3s@3t@0l@0o
> da kann nichts durcheinander kommen. Mußt du halt auf dem PC wieder
> zusammenbasteln.

Hmm das währe auch noch eine Variante.

Martin Wende schrieb:
> Weis ja nich was an Geräten drannehängt, aber die haben doch sicher ne
> Kennung wann die Nachricht abgeschlossen ist.
> Daher erst wiedern @ vorhängen wenn dieser Abschluss vorkam.

Im Moment sind es 2 verschiedene Netzteile das eine hat als Endung <cr> 
das andere <cr><lf>.

von Falk B. (falk)


Lesenswert?

@  M. K. (avr-frickler) Benutzerseite

>Die UARTs haben alle 2(RX/TX) eigene Puffer(FIFO). Der RXC-Interrupt
>stellt die Daten immer in den RX-Puffer und der UDRE-Interrupt sendet
>die Daten aus dem TX-Puffer.

Dieser Minipuffer reicht hier nicht.

>Wissen tue ich das nicht, ich schreibe einfach nur alle Daten aus den
>Empfangspuffer raus bis der Puffer leer ist. Durch das Delay verzögere
>ich das senden nur soweit das nach dem Delay das nächste Zeichen im
>Puffer steht. Ist der Puffer nach dem Delay immer noch leer, springe ich
>zum nächsten USART.

Total unbrauchbar.

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
>>Ich habe nun das Problem, dass die Hauptschleife die eingehenden Daten
>>schneller verarbeitet als neue Daten nachkommen.
>
> Kaum, dann dann wäre es kein FIFO.

Doch es ist einer, nur er wird halt nicht voll weil die Hauptschleife 
ihn zu schnell wieder leert.

Falk Brunner schrieb:
>>Wenn das externe Gerät "Test" sendet, wird "@3T@3e@3s@3t" ausgegeben.
>
> Dann hast du einen Programmierfehler.

Nö denn es macht genau das was es soll.

Falk Brunner schrieb:
> Müssen sie auch nicht. Du musst meldungsbasiert denken und arbeiten,
> nicht zeichenbasiert.

Würde ich ja gerne, nur woher soll ich wissen wann eine Meldung zuende 
ist. Es gibt unzählige Variaten wie ein Gerät eine Meldung abschliessen 
kann, <cr>, <cr><lf>, <lf><cr>, <null>, feste Länge, usw.

Falk Brunner schrieb:
> Delay ist meistens eine Zeichen für Murks.

Ein Grund warum ich es gerne weg hätte.

Falk Brunner schrieb:
> Macht man so nicht, sondern Multitasking. Ist gar nicht so schwer.

Die Software macht Multitasking. Was in diesem Fall mit zu dem Problem 
beiträgt.

Falk Brunner schrieb:
> Nö, keineswegs. Du musst interruptgesteuert komplette Meldungen
> empfangen und dann per Flag den anderen Programmteilen (=
> statemachine) das mitteilen, dort kann dann die Meldung komplett
> verarbeitet werden.

Der µC soll die Meldungen nicht verarbeiten, er soll Sie lediglich an 
den PC weiterleiten.

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
>>Die UARTs haben alle 2(RX/TX) eigene Puffer(FIFO). Der RXC-Interrupt
>>stellt die Daten immer in den RX-Puffer und der UDRE-Interrupt sendet
>>die Daten aus dem TX-Puffer.
>
> Dieser Minipuffer reicht hier nicht.

Wie groß soll er denn sein? Ich kann ihn theoretisch 64kByte groß 
machen, praktisch 256Byte im Moment sind es 50Bytes RX und 50Bytes TX, 
was dicke reicht, wie schon geschrieben der Puffer läuft nicht voll, 
sondern er wird zu schnelle geleert.

von Karl H. (kbuchegg)


Lesenswert?

M. K. schrieb:

>> Müssen sie auch nicht. Du musst meldungsbasiert denken und arbeiten,
>> nicht zeichenbasiert.
>
> Würde ich ja gerne, nur woher soll ich wissen wann eine Meldung zuende
> ist. Es gibt unzählige Variaten wie ein Gerät eine Meldung abschliessen
> kann, <cr>, <cr><lf>, <lf><cr>, <null>, feste Länge, usw.


Dann muss man das eben in deiner Software konfigurieren können, wenns 
denn universell sein soll. Wenns an spezielle Geräte angepasst wird, 
dann programmiert man dann eben deren Verhalten rein. So viele 
verschiedene Varianten gibt es dann auch wieder nicht.

von Falk B. (falk)


Lesenswert?

@  M. K. (avr-frickler) Benutzerseite


>> Dann hast du einen Programmierfehler.

>Nö denn es macht genau das was es soll.

Warum dann dein Posting?

>> Müssen sie auch nicht. Du musst meldungsbasiert denken und arbeiten,
>> nicht zeichenbasiert.

>Würde ich ja gerne, nur woher soll ich wissen wann eine Meldung zuende
>ist.

Tja, wie soll es der Mikrocontroller wissen? Der tut nur das, was du ihm 
sagst.

> Es gibt unzählige Variaten wie ein Gerät eine Meldung abschliessen
>kann, <cr>, <cr><lf>, <lf><cr>, <null>, feste Länge, usw.

Dann musst du das berücksichtigen, in welcher Forma auch immer.


>> Macht man so nicht, sondern Multitasking. Ist gar nicht so schwer.

>Die Software macht Multitasking. Was in diesem Fall mit zu dem Problem
>beiträgt.

Nicht wenn man es richtig (tm) macht. Siehe oben, meldungsbasiert, nicht 
zeichenbasiert.

>Der µC soll die Meldungen nicht verarbeiten, er soll Sie lediglich an
>den PC weiterleiten.

Er muss aber verschiedene Meldungen verschiedener Geräte ohne 
Verwurstung in EINEN Datenstrom zusammenfügen, aka Multiplexer. Dazu 
muss er wisssen, was ein vollständiger Datenblock ist, aka Kommando bzw. 
String. Einfach planlos Zeichen zusammwürfeln kann jeder Depp.

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> @  M. K. (avr-frickler) Benutzerseite
>
>
>>> Dann hast du einen Programmierfehler.
>
>>Nö denn es macht genau das was es soll.
>
> Warum dann dein Posting?
Weil es nicht das ist was ich will, sind halt 2 verschiedene Paar Schuhe 
:P

Karl Heinz Buchegger schrieb:
> Dann muss man das eben in deiner Software konfigurieren können, wenns
> denn universell sein soll. Wenns an spezielle Geräte angepasst wird,
> dann programmiert man dann eben deren Verhalten rein. So viele
> verschiedene Varianten gibt es dann auch wieder nicht.

Was dann zu Falks Meldungsbasiertem Interrupt führt. Scheint wohl der 
einzigst sinvolle Weg zu sein. Werde es dann wohl so machen:

Kommando erzeugen fürs setzen Meldungsende-Makierung. 2 Bytes sollten 
reichen denke ich.

Im RXC-Interrupt die Meldungsende-Makierung erkennen und Flag setzen, in 
der Hauptschleife das Flag auswerten und darauf reagieren.

Für den Fall das kein Makierungsende gesetzt wurde oder der FIFO voll 
läuft den Puffer leeren, dann müssen die Daten am PC halt richtig 
zusammengesetzt werden.

Wenn mir am Wochenende nichts besseres einfällt werde ich das am Montag 
mal so umsetzen.

von Peter D. (peda)


Lesenswert?

M. K. schrieb:
> Würde ich ja gerne, nur woher soll ich wissen wann eine Meldung zuende
> ist. Es gibt unzählige Variaten wie ein Gerät eine Meldung abschliessen
> kann, <cr>, <cr><lf>, <lf><cr>, <null>, feste Länge, usw.

Wieviel verschiedene Geräte mit verschiedenen Protokollen sind es denn 
wirklich?
Ich mach das immer so, daß CR oder LF als Ende angesehen werden und ein 
folgendes CR oder LF wird ignoriert.

Ein anderer Trick wäre, Du setzt ein Timeout auf. Z.B. wenn 3 Bytezeiten 
kein neues Zeichen eintrudelt, wird das Paket als beendet angenommen und 
bis dahin gesendet.
Blöd wäre dann aber, wenn die Geräte ihr Senden manchmal durch einen 
langen Interrupt unterbrechen oder ohne Pause senden.

Man kann auch, wenn das Ende erkennen nicht klappt, dann spätestens bei 
50% Füllgrad des FIFO senden.


Peter

von Purzel H. (hacky)


Lesenswert?

Man hat ja 4 UARTs. Daher kann der Controller ja wissen woher welche 
Meldung kommt. Also der Controller wartet parallel auf allen UARTs ab, 
bis eine komplette Meldung da ist und sendet sie dann als komplette 
Meldung weiter. Alles andere ist Murks. Denk dir eine Zustandsmaschine 
aus, die das leistet.

Wie ich's verstanden habe sind die Gerate verschieden und haben bereits 
feste Protokolle. Also der controller muss diese Geraete natuerlich 
verstehen, um die einzelnen Meldungen zu entschluesseln und zu wissen , 
wann eine Meldung fertig ist.
Das Protokoll zum PC ist noch unbestimmt. Dabei sollte man etwas 
waehlen, das eine Absenderkennung, und eine Laenge hat. Allenfalls noch 
einen CRC, um sicherzustellen, das nur gueltige Daten verwendet werden. 
Die einzelnen Meldungen der Geraete werden dann einfach als einzelne 
Meldungen aneinander gefuegt.

von Falk B. (falk)


Lesenswert?

@  M. K. (avr-frickler) Benutzerseite

>Kommando erzeugen fürs setzen Meldungsende-Makierung. 2 Bytes sollten
>reichen denke ich.

Warum zwei Bytes? Es sind ASCII-Strings in C, da kann man das alles 
standardkonform machen, 0x00 = Stringende.
Ein Byte reicht als Flag. Deine einzelnen RX-Interrupts müssen nur das 
Datenendezeichen erkennen, eine 0x00 in den FIFO schreiben und das Flag 
setzen. Die Hauptschleife mit ihrer Statemachine prüft diese Flags. Wenn 
eins gesetzt ist, wird nur aus diesem FIFO der komplette String 
gesendet, danach das Flag gelöscht, dann geht es weiter zum nächsten 
Flag eines anderen Kanals. GGf. nutz man das Flag als Zähler für mehrere 
Strings im Puffer, falls die Datenraten der UARTs arg verschieden sind. 
Aber Vorsicht mit atomarem Zugriff!

>Im RXC-Interrupt die Meldungsende-Makierung erkennen und Flag setzen, in
>der Hauptschleife das Flag auswerten und darauf reagieren.

Ja, siehe Interrupt.

>Für den Fall das kein Makierungsende gesetzt wurde oder der FIFO voll
>läuft den Puffer leeren, dann müssen die Daten am PC halt richtig
>zusammengesetzt werden.

Wie denn, wenn dort Fragmente ankommen? Ein voller FIFO darf eigentlich 
nie vorkommen, es sein denn, die Datenrate aller Eingänge in Summe ist 
größer als die Datenrate zum PC. Das kann man leicht verhindern.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Ich verstehe ehrlich gesagt nicht so ganz wo das Problem liegt? Wenn eh 
von den Geräten alles "zu langsam" kommt ist es ja egal das du immer 
doppelt soviele Zeichen überträgst. Falls die Geräte mal schneller sind 
wird es ja automatisch mehr Daten pro "Paket" übertragen...

von Uwe (Gast)


Lesenswert?

> Warum zwei Bytes? Es sind ASCII-Strings in C, da kann man das alles
> standardkonform machen, 0x00 = Stringende.
Ich denke er will alle möglichen Geräte dranmachen. Da geht gar kein 
Endzeichen, weil die geräte könnten ja auch binäre Daten senden.
Also für eigenes Protokoll :
Startbyte - Nummer der des ports - Länge der Daten - Checksumme

Aber ich glaube er wird sowieso viele Probleme bekommen, denn was 
passiert wenn ein Gerät was sendet und ne antwort in 100ms erwartet, 
aber erst mal ein anderes gerät bedient wird bzw. die Statemachine 
weiter die puffer füllt usw.

Das einzige was geht ist :
@0T@1H@2J@3µ@0e...
Dann die Baudrate zum PC vier mal so hoch wählen bzw. den Overhead ala 
"@0" muß man auch noch dazurechen, also pro Zeichen 2 extra Zeichen also 
3x4=12.
Mindestens 12 fache Baudrate einstellen. dann brauch man auch keine 
großen Puffer.

von Falk B. (falk)


Lesenswert?

@  Uwe (Gast)

>> Warum zwei Bytes? Es sind ASCII-Strings in C, da kann man das alles
>> standardkonform machen, 0x00 = Stringende.
>Ich denke er will alle möglichen Geräte dranmachen. Da geht gar kein
>Endzeichen, weil die geräte könnten ja auch binäre Daten senden.

Eas dürfte mit dem Konzept schwiegig bis unmöglich werden, denn er 
sendet ja ASCII zum PC, mit der Kennung @1 für Gerät 1 etc.

Und eine eierlegende Wollmilchsau ist selten gut.

>Aber ich glaube er wird sowieso viele Probleme bekommen, denn was
>passiert wenn ein Gerät was sendet und ne antwort in 100ms erwartet,
>aber erst mal ein anderes gerät bedient wird bzw. die Statemachine
>weiter die puffer füllt usw.

Das ist eine andere Frage.

>Das einzige was geht ist :
>@0T@1H@2J@3µ@0e...
>Dann die Baudrate zum PC vier mal so hoch wählen bzw. den Overhead ala
>"@0" muß man auch noch dazurechen, also pro Zeichen 2 extra Zeichen also
>3x4=12.
>Mindestens 12 fache Baudrate einstellen. dann brauch man auch keine
>großen Puffer.

Dann kann man sich den Käse gleich schenken und vier RS232 Ports direkt 
an den PC klemmen, sei es per USB oder wasauchimmer. Spart haufenweise 
Zurückfriemeln der Daten.

von Uwe (Gast)


Lesenswert?

> Eas dürfte mit dem Konzept schwiegig bis unmöglich werden
Genaumeine Meinung, falsches Konzept !

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Also binäre Daten werden nicht übertragen, es sind schon einfache 
ASCII-Strinngs.

Falk Brunner schrieb:
>>Aber ich glaube er wird sowieso viele Probleme bekommen, denn was
>>passiert wenn ein Gerät was sendet und ne antwort in 100ms erwartet,
>>aber erst mal ein anderes gerät bedient wird bzw. die Statemachine
>>weiter die puffer füllt usw.
>
> Das ist eine andere Frage.
So etwas ist bisher noch nicht vorgekommen.

Falk Brunner schrieb:
> Warum zwei Bytes? Es sind ASCII-Strings in C, da kann man das alles
> standardkonform machen, 0x00 = Stringende.

Ja so meinte ich es auch nur halt auf 2 Zeichen begrenzt .. obwohl wenn 
ich recht überlege ist es eigtlich egal, wenn ich im Interrupt nen 
Zähler habe wieviele Zeichen des Meldungsende-Strings bereits 
übereinstimmen brauche ich nur noch gegen die Stringlänge testen und das 
Flag setzen.
1
ISR( USART0_RX_vect ) {
2
>>  static uint8_t count_endl;
3
    uint8_t i = com0.rx_buffer.in;
4
    char c = UDR0;
5
6
    WRAPBUFFER( i, com0.rx_buffer.length );
7
8
    // Puffer Überlauf
9
    if ( i == com0.rx_buffer.out )
10
        return;
11
12
    com0.rx_buffer.data[com0.rx_buffer.in] = c;
13
    com0.rx_buffer.in = i;
14
15
>>  if (c == com0.endl[count_endl])
16
>>      count_endl++;
17
>>  else
18
>>      count_endl = 0;
19
20
>>  if (count_endl == strlen(com0.endl))
21
>>      com0.msgComplete = 1;
22
23
    if (com0.setting.flow == FLOW_RTS_CTS) {
24
        c = 0;
25
        do {
26
            WRAPBUFFER( i, com0.rx_buffer.length );
27
        } while (i != com0.rx_buffer.out && c++ <= 5);
28
29
        if ( c < 5 ) {
30
            PORT_HANDSHAKE0 |= (1 << RTS0);
31
        }
32
    }
33
}
* Die mit >> makierten Zeilen sind neu.
static-Variablen werden vom Compiler mit 0 initialisert? Arbeite kaum 
mit static-Variablen daher die Frage.
strlen kann noch gegen eine Variable ersetzt werden die beim 
initialiseren des USARTs gesetzt wird, msgComplete könnte auch ein 
Zähler anstatt eines Flags sein.

von Jens B. (nixiefreak)


Lesenswert?

Splitte doch dein Byte in ein 4-Bit-Teil mit Adresse und einen 
4-Bit-Teil mit Daten. Musst du dein Protokoll nur ein bisschen umbauen 
(also zwei Mal senden für 1 Byte), aber dann ist es eindeutig, wenn 
keine Übertragungsfehler dazukommen.

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
Noch kein Account? Hier anmelden.