Ich übertrage von einem ATmega über den FT232 binäre Daten in Paketen zu 14 Bytes. Ich beobachte jetzt, daß das erste Byte jeweils verschluckt wird, es kommen also nur 13 Bytes (2-14) an. Das ganze egal bei welcher Baudrate. Die ankommenden byts sind übrigens fehlerfrei. Besonders ulkig: Wenn ich 20 Pakete am Stück senden lasse, kommen 279 Bytes an (20*14-1!). Flicke ich ziwschen die Pakete delays von 100ms, dann kamen nur 260 Bytes an - jeweils das erste Byte fehlte. Ich vermute Probleme des Treibers - irgendwo habe ich gelesen, das USB oder der FT232 Probleme mit dem Übertragen kleiner Datenmengen hat, was isch wohl mit Treiebr-Tuning lösen liesse. Kann jemand helfen ?
N. N. schrieb: > Ich übertrage von einem ATmega über den FT232 binäre Daten in Paketen zu > 14 Bytes. > Ich beobachte jetzt, daß das erste Byte jeweils verschluckt wird, es > kommen also nur 13 Bytes (2-14) an. Das ganze egal bei welcher Baudrate. > Die ankommenden byts sind übrigens fehlerfrei. > > > Besonders ulkig: Wenn ich 20 Pakete am Stück senden lasse, kommen 279 > Bytes an (20*14-1!). > Flicke ich ziwschen die Pakete delays von 100ms, dann kamen nur 260 > Bytes an - jeweils das erste Byte fehlte. > > Ich vermute Probleme des Treibers Klar, es liegt natürlich immer an den Anderen! FTDI schmeist nur so einen Schrott auf den Markt - oder was? > - irgendwo habe ich gelesen, das USB > oder der FT232 Probleme mit dem Übertragen kleiner Datenmengen hat, was > isch wohl mit Treiebr-Tuning lösen liesse. Quelle/Link? Und warum hast du es nicht probiert? > Kann jemand helfen ? Leider nicht. Du hältst dich ja für fehlerfrei, darum ist es auch nicht nötig, dass du deinen Quellcode postest!
Hallo drnicolas, um das systematisch einzugrenzen würde ich mit Testcode nur 1 Byte senden, unbedingt ein Druckbares (ASCII 'A' z.B.) alle 100ms oder noch seltener (1/sec). Als Empfangssw KEINE eigene sondern ein Terminalprogramm (notfalls Hyperterminal). Baudrateneinstellung prüfen ob korrekt und dann los. Vielleicht werden ja nur bestimmte Zeichen verschluckt (Schnittstelle im Binarymode öffnen!), mit anderen Zeichen probieren ( einfach 0x00 bis 0xFF durchgehen lassen). Sollte bei öffnen im Binarymode NICHT passieren. Mit dem Oszi/Logicanalysator (sofern vorhanden) Das Byte prüfen ob es korrekt aufgebaut ist (Startbit,Daten,Stoppbit), damit klar ist dass nicht deine HW/SW die Ursache ist. Erst kürzlich hat einer meiner jüngeren Kollegen aus NichtWissen und nichtFragen eine RS232 falsch rum gepolt betrieben und sich gewundert das nicht alles ankam. Generell gilt nämlich für alle mir bekannten Controller: Das Signal am Controller-Pin ist negiert gg. dem Signalpegel auf der RS232-Leitung (weil die alten 75188/75189 RS232-Treiber negierend waren, MAX232&co haben das beibehalten). Für das alles braucht man deinen Code erstmal nicht :-) Ich kann mich noch gut erinnern, in den 90ern musste ich einen DOS Gerätetreiber bauen. Gab Probleme, letztlich war die Ursache wirklich das MS-DOS 5.0 selbst. Es hatte vom Programm übergebene Bytes !manchmal! nicht an den Gerätetreiber weitergegeben. Letztlich haben wir damals einen Workaround gemacht, weil die eigentliche Ursache nicht korrigiert werden konnte. Zurück zu deinem Problem: Erst wenn das übertragen einzelner Bytes ohne Fehler klappt, dann erst auf die gewünschte Blocklänge gehen, und schauen was ankommt. Hier erst kommen dann Interrupt und ggf. Timingprobleme dazu wenn es dann nicht klappt. Wenn du auf dem PC eigene SW hast, bau dir einen Debugmode ein der die empfangenen Bytes direkt anzeigt oder in eine Logdatei schreibt, bevor irgendeine Weiterverarbeitung passiert. RS232 kann man übrigens problemlos anzapfen (also die Datenleitung an einen zweiten EIngang legen wo eine Terminal-SW mithorcht), Treiberleistung, Eingangsimpedanz sind hier noch unkritisch. Viel Erfolg mit dem Projekt!
Hannes schrieb im Beitrag #2975409: > @Michael L. > > Nun komm mal wieder runter...wenn Du nicht helfen willst, spar Dir solch > blöde Kommentare. OK, das hat dem TO jetzt aber ganz bestimmt geholfen. ;-) > Warum bist Du so aggressiv? Muss man jetzt schon Sarkasmus erklären? BTW: Wenn man fragt, bekommt man nicht immer die Antworten, welche man erwartet. Das wiederum liegt so gut wie immer an der Fragestellung. http://www.tty1.net/smart-questions_de.html Wer etwas zusammenfrickelt, sollte nicht vorschnell die Fehler auf Andere schieben. Schon gar nicht auf Basis von Vermutungen, oder weil man glaubt, mal irgendwo irgendwas gelesen zu haben. Und mehr als eine vage verbale Beschreibung hat der TO nicht geliefert. > Hat Dich Frauchen nicht gut behandelt? Ich werde von ihr immer gut behandelt. Nur den Ausdruck "Frauchen" kann sie nicht ausstehen, schließlich ist sie erwachsen. Da hättest du dir im RL wohl mindestens einen blöden Spruch eingefangen. :-D @drnicolas Bitte mehr Informationen und systematisches Vorgehen, wenn du Hilfe suchst.
...wenn man ohne Interrupt arbeitet passiert so etwas oefters
Michael L. schrieb: > > Ich werde von ihr immer gut behandelt. Nur den Ausdruck "Frauchen" kann > sie nicht ausstehen, schließlich ist sie erwachsen. Da hättest du dir im > RL wohl mindestens einen blöden Spruch eingefangen. :-D Also die paar RL, die ich hier im hohen Norden kenne, sind alle unsympathisch, da hilft wohl auch kein Umzug.
Das Rätsel ist gelöst. Es lag daran, daß ich zuerst UDRIE enabled habe und DANACH in UDR die Daten schreibe. Jetz funktioniert es. trotzdem lohnt es sich mit den Timeouts des Treiebrs zu experimentieren. Wenn man von 0 auf z.B 200ms umstellt, dann kommen die Daten zwar vollständig aber etwas abgehackt.
@ N. N. (drnicolas) >Es lag daran, daß ich zuerst UDRIE enabled habe und DANACH in UDR die >Daten schreibe. >Jetz funktioniert es. Wirklich? Poste Code als Anhang. Wahrscheinlich ist der Bug nur kaschiert. >trotzdem lohnt es sich mit den Timeouts des Treiebrs zu experimentieren. Aber nur, wenn man weiß was man tut. >Wenn man von 0 auf z.B 200ms umstellt, dann kommen die Daten zwar >vollständig aber etwas abgehackt. Was mal nicht im Sinn des Erfinders ist. Der FT232 läuft ziemlich gut, auch mit Standardeinstellungen.
Mit abgehackt meine ich, daß die Pakete nicht mit Abstand kommen, sondern u.U. 3 oder 4 Pakete auf einmal, dafür mit grösserem Abstand. Sieht im besten Falle unschön aus, wenn vom µC die Angaben eines Drehencoders nicht gleichmässig kommen. Aber trotzdem: in einem englischsprachigen Forum wurde ich schon schief angemacht ob meiner Übertragunsgmethode. Vielleicht bin ich ja tatsächlich komplett auf dem Holzweg. Hier kommt mal ein Code-Auschnitt:
1 | void UARTRingbuffer_TX_CheckStart(void) |
2 | {
|
3 | if((UART_TX_Control.QueueRunning==0) && (RTS_LINE_FT232R==USART_READY) && |
4 | (UART_TX_Control.BufferBytesRemaining!=UART_TX_QUEUESIZE*sizeof(struct UART_Message))) |
5 | { //Übetragung anstossen .... |
6 | UART_TX_Control.QueueRunning=-1; //die Übetragung läuft jetzt formal |
7 | #ifdef __AVR_AT90CAN128__
|
8 | //UCSR1A |= (1<<UDRE1); //Flag UDRE löschen
|
9 | volatile uint8_t tmp_char=*UART_TX_Control.READ_Pointer; |
10 | UDR1=tmp_char; //Datenbyte in das Register UDR1 schreiben |
11 | UCSR1B = UCSR1B | (1<<UDRIE1); // Interrupt freigeben |
12 | //...danach werden die restlichen Bytes werden durch Interupt
|
13 | //gesendet.
|
14 | // Der Pointer wird erst NACH erfolgreichem Senden erhöht
|
15 | |
16 | |
17 | #elif __AVR_ATmega32__
|
18 | UDR=*UART_TX_Control.READ_Pointer; //Daten in temp. register laden |
19 | UCSRB = UCSRB | (1<<UDRIE1); |
20 | #endif
|
21 | } //if |
22 | } //end UARTRingBuffer_TX_CheckStart |
Und jetzt noch die IRQ-Routine ...
1 | /* Die nachfolgende Interruptroutine wird immer dann aufgerufen, wenn UDRE eintritt, d.h.
|
2 | UDR ist leer, resp. das nächste Byte kann gesendet werden */
|
3 | #ifdef __AVR_AT90CAN128__
|
4 | ISR(USART1_UDRE_vect) |
5 | #endif
|
6 | |
7 | #ifdef __AVR_ATmega32__
|
8 | ISR(USART_UDRE_vect) |
9 | #endif
|
10 | {
|
11 | #ifdef UART_DEBUG
|
12 | UARTRingTracker.TX_ByteCount++; //nur für Überwachungszwecke !! |
13 | #endif
|
14 | |
15 | UART_TX_Control.BufferBytesRemaining++; //Zeichen erfolgreich gesendet |
16 | UART_TX_Control.READ_Pointer++; //Pointer um eins erhöhen ... |
17 | |
18 | //... den Pointer ggf. auf Anfang setzen
|
19 | if(UART_TX_Control.READ_Pointer>= ((unsigned char *) &UART_TX+UART_TX_QUEUESIZE*sizeof(struct UART_Message))) |
20 | {
|
21 | UART_TX_Control.READ_Pointer=(unsigned char *) &UART_TX; |
22 | }
|
23 | |
24 | if(UART_TX_Control.BufferBytesRemaining<UART_TX_QUEUESIZE*sizeof(struct UART_Message)) |
25 | { // Es sind noch Zeichen übrig in der Queue |
26 | if((RTS_LINE_FT232R==USART_READY)) |
27 | { //Gegenseite empfangsbereit |
28 | // es !dürfen! weitere Zeichen gesendet werden ...
|
29 | #ifdef __AVR_AT90CAN128__
|
30 | UDR1=*UART_TX_Control.READ_Pointer; //Datenbyte in das Register UDR1 schreiben |
31 | #elif defined __AVR_ATmega32__
|
32 | UDR=*UART_TX_Control.READ_Pointer; |
33 | #endif
|
34 | }
|
35 | else
|
36 | { //Gegenseite *NICHT* empfangsbereit ! |
37 | //vorerst die Übetragung beenden. Der Marker für
|
38 | #ifdef __AVR_AT90CAN128__
|
39 | CLEARBIT(UCSR1B,UDRIE1); //Interrupt löschen |
40 | #elif defined __AVR_ATmega32__
|
41 | CLEARBIT(UCSRB,UDRIE); |
42 | #endif
|
43 | UART_TX_Control.QueueRunning=0; // Übetragung ist offiziell beendet (?) |
44 | |
45 | }
|
46 | return; //Interrupt bleibt aktiviert ... weitere Zeichen folgen |
47 | }
|
48 | else
|
49 | { //andernfalls -> aktuelles Paket ist komplett gesendet ! |
50 | #ifdef __AVR_AT90CAN128__
|
51 | CLEARBIT(UCSR1B,UDRIE1); //Interrupt löschen |
52 | #elif defined __AVR_ATmega32__
|
53 | CLEARBIT(UCSRB,UDRIE); |
54 | #endif
|
55 | UART_TX_Control.QueueRunning=0; // Übetragung ist offiziell beendet |
56 | |
57 | #ifdef UART_DEBUG
|
58 | UARTRingTracker.TX_PacketCounter++; //Zähler für vollständig gesendete Pakete erhöhen |
59 | #endif
|
60 | }
|
61 | } // Ende SIGNAL(...) |
> in einem englischsprachigen Forum wurde ich schon schief angemacht ob > meiner Übertragunsgmethode. Vielleicht bin ich ja tatsächlich komplett > auf dem Holzweg. Schief anmachen würde ich das [0] nicht nennen. Und komplett auf dem Holzweg bist Du auch nicht, aber es ist unnötig kompliziert. Das macht zukünftige Wartung nicht unbedingt einfacher. [0] http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=1023088
N. N. schrieb: > ... Vielleicht bin ich ja > tatsächlich komplett auf dem Holzweg. Ich habe jetzt nicht den ganzen Code durchdrungen, aber ich glaube dass du in der ISR Zeichen verlierst, wenn die Gegenseite gerade nicht empfangsbereit ist. Oder verwirfst du etwa den Puffer im Ganzen? Das wiederum wäre ja nicht unbedingt nötig, weil RTS/CTS ja "nur" das Hardware-Handshake ist. Es scheint aber, als würdest du es im Sinne von DTR/DSR (Anzeige der Betriebsbereitschaft, d.h. überhaupt erst mal eine Gegenstelle "da") behandeln. Eine "Umdeutung" der Signale ist in gewissen Grenzen sicherlich möglich, und auch Wurscht, solange du zwischen zwei selbst gebauten Geräten überträgst. Aber wenn du eine Gegenstelle nach Standard hast, kann das auch zu scheinbar unerklärlichem Verhalten. Grüße.
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.