Hallo,
ich finde seit mehreren Stunden keine Lösung für folgendes Problem:
Beim initialisieren meiner USART beim ATMEGA2560 wird nach dem setzen
von RXEN und TXEN des UCSR0B Registers ein Zeichen auf der Schnittstelle
ausgegeben (meist 0xFC).
Dadurch kommen daran hängende Geräte mit dem ersten Kommando nach dem
Einschalten nicht klar, da es ja ein führendes falsches Zeichen enthält.
So sieht die Initialisirung aus:
1
voiduart0_init()
2
{
3
4
//set baud rate
5
UBRR0H=0x00;
6
UBRR0H=(uint8_t)(UBRR_BAUD0>>8);
7
UBRR0L=(uint8_t)UBRR_BAUD0;
8
9
//enable receiver and transmitter
10
UCSR0B=0x00;
11
12
//return; return an dieser Stelle: kein Zeichen wird ausgegeben
13
14
UCSR0B=(1<<RXEN0)|(1<<TXEN0);
15
16
//return; return an dieser Stelle: 0xFC wird ausgegeben
17
18
//enable interrupts
19
UCSR0B|=(1<<RXCIE0);
20
21
//set frame format to 'async USART' and 8n1
22
UCSR0C=0x00;//clear
23
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
24
25
}
Hat jemand von Euch einen Tip, wie man das unterbinden kann? Das
Verhalten ist auf alle 4 USARTS reproduzierbar.
Gruß
Christian
schon mal getauscht
Christian Rothe schrieb:> //return; return an dieser Stelle: kein Zeichen wird ausgegeben>> UCSR0B = (1<<RXEN0) | (1<<TXEN0);>> //return; return an dieser Stelle: 0xFC wird ausgegeben>> //enable interrupts> UCSR0B |= (1<<RXCIE0);>> //set frame format to 'async USART' and 8n1> UCSR0C = 0x00; //clear> UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
setze doch doch erst die Formatlänge dann RXEN/TXEN enablen und danach
RXCIE freigeben falls nicht schon mal ausprobiert
> Dadurch kommen daran hängende Geräte mit dem ersten Kommando nach dem> Einschalten nicht klar, da es ja ein führendes falsches Zeichen enthält.
Müssen die aber, es kann immer mal wieder vorkommen, daß ein falsches
Zeichen dazwischenfunkt. Trotzdem sollte man das mit dem Zeichen bei
Reset verhindern. Aber auch ein falsches Zeichen darf dein System nicht
stören, ansonsten Mülltonne.
Hallo Uwe,
im Prinzip sehe ich das ebenso. Allerdings kann natürlich das nächste
Gerät nicht unterscheiden, ob dieses Zeichen gewollt oder eben zufällig
kam.
Für den nächsten Empfänger ist es halt das erste Zeichen vom neuen
Kommando. Der Parser erkennt das Kommando dann halt nicht.
Beherzige die Vorschläge bzgl. dem Abfangen von falschen Informationen.
"Da kann wird nichts anderes geschickt," ist keine Ausrede. Es ist immer
mal möglich durch falsch gesetzte Parameter, dass an der UART
Schnittstelle nur murks rauskommt.
zur Not 0x00 ins UDREx schreiben bevor die TX/RX pins gesetzt werden und
mal testen find das eigentlich ungewönhlich das beim Reset Zeichen
gesendet werden passiert vielleicht im Programm irgendwas was wir gerade
nicht sehen da es ja nicht der vollständige Code ist?aber warte mal wann
tritt denn der Reset auf?? denn es kann ja sein das im UDRE noch ein
Zeichenn ist und du genau dann den Reset machst obwohl der Vorgang noch
nicht abgeschlossen ist
Hallo Stefan,
hast Du dazu noch einen Tip? Mir fehlt dazu gerade der richtige Ansatz
denn:
Mein Gerät startet und sendet ein Kommando über den USART. Dieses ist
(wegen des ersten Zeichens) falsch. Das Zielgerät ignoriert das Kommando
und alles weitere hakt...
Einzige Lösung die mir Einfällt wäre nun zuerst ein unnötiges Kommando
(ohne gewünschte Funktion) zu senden um die FIFOs und Kommandoparser zu
bereinigen.
Gibt es da elegantere Lösungen?
Ich nehme mal an, dass während des Resets alle Pins in den hochohmigen
Zustand gehen. Damit ist dann der Pegel von TX undefiniert. Das kann
sich beim Empfänger durchaus als vermeintliches "Zeichen" bemerkbar
machen.
Diese These wird dadurch unterstützt, dass dann ein 0xFC ankommt. Das
sieht bei der Übertragung folgendermaßen aus:
___-----------
S012345678
(S=Startbit)
Das heisst, der kurze Dip auf der Leitung ergibt durchaus ein "Zeichen".
Wahrscheinlich hilft ein Pullup-Widerstand auf der TX-Leitung.
Das ist wahrscheinlich kein Zeichen, das gesendet wird, sondern ein
Pinwackeln, das durch das Umschalten des Pins von I/O auf
TXD-Pinfunktion entsteht.
Wie ist denn Dein Pin vor dem Einschalten des UARTs konfiguriert?
Floatet der oder ist der terminiert?
Am Besten hängst Du mal ein Oszi an den TXD-Pin und schaust Dir das
Signal beim Reset und beim Konfigurieren an.
Gruß, Stefan
> Gerät nicht unterscheiden, ob dieses Zeichen gewollt oder eben zufällig> kam.
Muss es aber, sonst Mülltonne.
Ist das "nächste Gerät" von dir? Wenn ja anderes Protokoll
implementieren, wenn nein dann "nächste Gerät">Mülltonne, neuses Gerät
mit anständigem Protokoll.
Ich könnte mir vorstellen, dass das eigentliche Problem ein ganz anderes
ist.
Der Ruhepegel auf der Tx Leitung vom Mega ist bei UART Betrieb +5V.
Nur: Diesen Pegel hat die Leitung nach dem einschalten (bzw. nach einem
Reset) nicht.
Erst nachdem die UART aktiviert wird, geht die Leitung auf +5V. Wodurch
sich eine Flanke am Ausgang ergibt.
Und auf diese Flanke reagieren deine Geräte.
Fazit: wie schon gesagt. Ein Empfänger ohne entsprechende
Fehlerbehandlung ist Murx. D.h. eigentlich ist dann das Protokoll Murx,
wenn es nicht erlaubt, dieses Problem zu erkennen und derartig
fehlerhafte Datensätze auszusortieren. So etwas muss ein Protokoll bzw.
ein Empfänger abkönnen. Was macht denn der Empfänger, wenn mal das Kabel
abfällt und von der Putzfrau im laufenden Betrieb neu angesteckt wird?
Deswegen darf der Feueralarm nicht ausgelöst werden.
@Chris
vollständiger Code ist viele Dateien groß, aber der wird hier noch gar
nicht ausgeführt. Ich habe eine leere Endlosschleife direkt nach der
Initialisirung eingefügt.
Ich habe bereits versucht UDR0 vor der Initialisierung oder an beliebig
anderen Stellen während der Initialisierung zu leeren (auszulesen bis
das RXC Register kein Zeichen mehr meldet) - kein Erfolg
Der Reset kommt entweder beim Einschalten oder durch Betätigen des
Reset-Tasters, also willkürlich.
Karl Heinz schrieb:> Erst nachdem die UART aktiviert wird, geht die Leitung auf +5V. Wodurch> sich eine Flanke am Ausgang ergibt.> Und auf diese Flanke reagieren deine Geräte.
Das sehe ich genauso. Das "empfangene" Zeichen 0xFC spricht dafür, denn
es besteht nur aus einem kurzen Drop mit der Bitlänge 3 (zusammen mit
dem Start-Bit), also 3 Bits Low, Rest wieder High.
Hi
>Mein Gerät startet und sendet ein Kommando über den USART. Dieses ist>(wegen des ersten Zeichens) falsch. Das Zielgerät ignoriert das Kommando>und alles weitere hakt...
Nur mal so: Die USART sendet nichts, wenn der Transmit-Puffer leer ist.
Und das ist er nach einem Reset. Mir ist es in über 16 Jahren mit AVRs
noch nicht vorgekommen, das die USART ein solches Eigenleben entwickelt.
Was machst du mit dem Port vorher?
MfG Spess
Karl Heinz schrieb:> Ich könnte mir vorstellen, dass das eigentliche Problem ein ganz anderes> ist.>> Der Ruhepegel auf der Tx Leitung vom Mega ist bei UART Betrieb +5V.> Nur: Diesen Pegel hat die Leitung nach dem einschalten (bzw. nach einem> Reset) nicht.> Erst nachdem die UART aktiviert wird, geht die Leitung auf +5V. Wodurch> sich eine Flanke am Ausgang ergibt.> Und auf diese Flanke reagieren deine Geräte.>> Fazit: wie schon gesagt. Ein Empfänger ohne entsprechende> Fehlerbehandlung ist Murx. D.h. eigentlich ist dann das Protokoll Murx,> wenn es nicht erlaubt, dieses Problem zu erkennen und derartig> fehlerhafte Datensätze auszusortieren. So etwas muss ein Protokoll bzw.> ein Empfänger abkönnen. Was macht denn der Empfänger, wenn mal das Kabel> abfällt und von der Putzfrau im laufenden Betrieb neu angesteckt wird?> Deswegen darf der Feueralarm nicht ausgelöst werden.
Ja, da hast Du recht.
Das folgende Gerät ignoriert das Kommando zwar ganz brav, ist dadurch
auch nicht aus dem Tritt geraten, aber hat meine Moduseinstellung
(erstes Kommando) halt nicht akzeptiert.
Da liegt das Übel nun also im reinen ASCII Protokoll, welches hier keine
Überprüfung auf richtig verarbeitete gesendete Kommandos vornimmt.
Da ist natürlich eine Umfangreiche Modifikation in der Struktur nötig.
Hoffte es wäre einfach lösbar durch Vermeidung dieses Zeichens.
Dann danke Dir für die Denkanstöße, Karl Heinz
Gruß
Christian
Es ist wohl wirklich nur
Christian Rothe schrieb:> Ja, da hast Du recht.> Das folgende Gerät ignoriert das Kommando zwar ganz brav, ist dadurch> auch nicht aus dem Tritt geraten, aber hat meine Moduseinstellung> (erstes Kommando) halt nicht akzeptiert.
Ist das Protokoll so aufgebaut, dass es ein Endezeichen vorsieht? Bei
ASCII ist das meistens ein \n.
Dann sende ihm als allererstes Zeichen ein \n, damit der Kommandobuffer
im Empfänger geleert wird und quasi die Empfansmaschinerie im Empfänger
auf Ausgangsstellung zurückgeht, egal was vorher passiert ist.
spess53 schrieb:> Hi>>>Mein Gerät startet und sendet ein Kommando über den USART. Dieses ist>>(wegen des ersten Zeichens) falsch. Das Zielgerät ignoriert das Kommando>>und alles weitere hakt...>> Nur mal so: Die USART sendet nichts, wenn der Transmit-Puffer leer ist.> Und das ist er nach einem Reset. Mir ist es in über 16 Jahren mit AVRs> noch nicht vorgekommen, das die USART ein solches Eigenleben entwickelt.> Was machst du mit dem Port vorher?>> MfG Spess
Hallo Spess
vorher wird lediglich der µC initialisiert. Sollte ich das vielleicht
auf das notwendigste reduzieren?
Karl Heinz schrieb:> Christian Rothe schrieb:>>> Ja, da hast Du recht.>> Das folgende Gerät ignoriert das Kommando zwar ganz brav, ist dadurch>> auch nicht aus dem Tritt geraten, aber hat meine Moduseinstellung>> (erstes Kommando) halt nicht akzeptiert.>> Ist das Protokoll so aufgebaut, dass es ein Endezeichen vorsieht? Bei> ASCII ist das meistens ein \n.>> Dann sende ihm als allererstes Zeichen ein \n, damit der Kommandobuffer> im Empfänger geleert wird und quasi die Empfansmaschinerie im Empfänger> auf Ausgangsstellung zurückgeht, egal was vorher passiert ist.
Ja, \r\n beendet den Parser. So werde ich es machen.
Danke für die Ideen.
Gruß
Christian
Hi
>vorher wird lediglich der µC initialisiert. Sollte ich das vielleicht>auf das notwendigste reduzieren?
Ja. Da liegt der Fehler. Du setzt die PINs Ausgang und dann auf L. Lass
einfach die USART PINs auf Ausgang. Mit TXE und RXE übernimmt die USART
eh die Kontrolle über die Pins.
MfG Spess
spess53 schrieb:> Ja. Da liegt der Fehler. Du setzt die PINs Ausgang und dann auf L. Lass> einfach die USART PINs auf Ausgang.
-> Eingang
Wenn es möglich ist würde ich allerdings trotzdem dem Empfänger erst mal
einen Dummy-Kommando Abschluss schicken. Dann kann ich als Sender von
gesicherten Verhältnissen ausgehen. Sicher ist sicher.
Karl Heinz schrieb:> spess53 schrieb:>>> Ja. Da liegt der Fehler. Du setzt die PINs Ausgang und dann auf L. Lass>> einfach die USART PINs auf Ausgang.>> -> Eingang>> Wenn es möglich ist würde ich allerdings trotzdem dem Empfänger erst mal> einen Dummy-Kommando Abschluss schicken. Dann kann ich als Sender von> gesicherten Verhältnissen ausgehen. Sicher ist sicher.
Perfekt !!!
Danke für die Hilfe, so geht es und ich fühle mich wohler :-)
... und die 3 Bits low-Time sind genau die Zeit zwischen
InitController() und InitUart(). Auch eine Idee, die Laufzeit der
Initialisierung zu messen ;-)
Gruß, Stefan