Hei Leute, Ich will 2 uC mit der seriellen Schnittstelle verbinden. Zum Test habe ich den einen uC eine Endlos-Folge von A's senden lassen. Das klappt auch ganz gut(danke Stefan und Karl-Heinz :-)). Ich will nun 6 aufeinanderfolgende Zeichen(in diesem fall A's) empfangen. Wenn ich aber nun versuche dieses Signal mit nachfolgendem Code zu empfangen, passiert etwas merkwuerdiges: Zuerst empfange ich immer 6 P's und zwar immer P's. Dann unterbreche ich das Signal kurz und nun empfange ich immer A's egal wie oft ich das Signal noch wieder unterbreche. Kann sich das einer erklaeren????????? Ausserdem ist hinter den 6A's ein riesen langer Rattenschwanz an Zeichen(ca.16 Stueck) was ich ebenfalls nicht evrstehe. Vielleicht hat jemand von euch eine Ahnung. Falls es euch hilft der uP ist ein Rabbit 3000. VG Paule #define EINBUFSIZE 127 //Ein-/Ausgangsbuffer #define EOUTBUFSIZE 127 #class static //************************************************ void SerEReceive(char *s) { auto int i; serEopen(9600); //serieller Port Initialisierung serErdFree; serErdFlush; serEflowcontrolOff(); serEdatabits(PARAM_8BIT); while(1) { i=serEread(s,6,20); //i gibt an wieviele Bytes printf("%s*%d*",s,i);//erfolgreich empfangen wurden } //hier geschieht das Unfassbare!!!! serEclose(); } //************************************************ main () { const char s1[]="B"; SerEReceive(s1); }
Hmmmmm, bist du auch ganz sicher, das dein Eingangssignal korrekt ist?
Start - Stopbits usw stimmen auf Sender und Enpfängerseite?
Ich habe auf beiden uC nichts besonderes eingestellt. Beide 8 Datenbit und Standart ist beim Rabbit 1 Stoppbit, also muessten Start und Stoppbit passen oder?.
Überdenke deine Programmlogik! Was gibst du im Moment aus, wenn kein Zeichen empfangen wurde? Ist das richtig? Wie könnte man erkennen, dass kein Zeichen empfangen wurde?
In dem Moment geb ich das aus, was im Speicher steht, also die letze erfolgreich empfangene Char-Kette.
Könntest du bitte diese Betreffsverstümmelungen unterlassen?
Ich guck grad mal nach. Hmmm, nein, ist grad nichts zu machen.
Ein A wird (incl. der Start-/Stopbits, bei 8 Datenbits, 1 Stopbit und keiner Parität) als 0100000101 übertragen, viele As entsprechend als 0100000101010000010101000001010100000101... ^ ^ ^ ^ Startest du erst den Sender und dann erst den Empfänger, wird der Sender irgendein 0-Bit, das auf ein 1-Bit folgt, als Startbit interpretieren, bspw. auf eines der mit ^ markierten. Der Empfänger liest also 00000101010000010101000001010100000101... Das erste Byte (incl. Start-/Stopbit) ist 0000010101 Dies entspricht einem P, die folgenden Bytes natürlich entsprechend. Unterbrichst du den Sender für eine Weile sendet er ständig 1-Bits (das ist der Ruhezustand). Danach synchronisiert sich der Empfänger auf das richtige Startbit. Dann klappt's auch mit den As.
Das klingt gut, danke. 1. Frage beantwortet. Danke Yalu. BIst wohl kein son Stuemper wie ich ;-). Aber weisst du auch warum 16 Zeichen Muell hinter jeden empfangenen A's stehen???
Ich kenne weder den Rabbit noch die Funktion ser Eread, aber vermutlich liegt es an Folgendem: serEread liest 6 Bytes von der Schnittstelle und schreibt diese in s. Wenn s mit dem format "%s" (also als String) ausgegeben wird, muss s nullterminiert sein, sonst findet printf das Stringende nicht und zeigt solange Zeichen an, bis es zufälligerweise eine Null findet. Füge mal die Zeile s[i] = '\0'; vor dem printf ein. Des Weiteren ist const char s1[] = "B"; nicht richtig. Damit wird s1 mit der Göße 2 angelegt ('B' und das Nullzeichen), was zu klein ist, um 6 + 1 Zeichen zu speichern. Das kann seltsame Folgen haben. Außerdem ist das const nicht richtig, denn du willst die Variable ja ändern (normalerweise sollte der Compiler mindestens eine Warnung ausgeben). Also besser durch char s1[7]; ersetzen.
Es funktioniert. hattest recht mit dem, dass printf einen nullterminierten String sucht. Yalu ich liebe dich ;-). Gruss Paule
> Yalu ich liebe dich
Aua ;-)
Trotzdem gern geschehen
Hei Leute, nochmal ne Frage: Das Programm laeuft jez einwandfrei, wenn ich es in den SRAM-speicher compiliere, sobald ich es aber in den EEPROM-Speicher compiliere(was ich natuerlich irgendwann muss) wird auf dem Bildschirm BBBBBBBBBBBBBBBBB ausgegeben statt AAAAAA. Wenn ich nach SRAM compiliere bringt der Compiler die Warnung: line 1014 : WARNING IDBLOCK.LIB : Cannot access user block while running in RAM. Wenn ich nach EEPROM compiliere kommt keine Fehlermeldung, aber wie gesagt, dann funktionierts au net. Vielleicht kann einer von euch Geniusen mir weiterhelfen. Nochmals VG Paule. Unten habe ich den aktuellen Code gepostet. #define EINBUFSIZE 127 //Ein-/Ausgangsbuffer #define EOUTBUFSIZE 127 #define DINBUFSIZE 127 //Ein-/Ausgangsbuffer #define DOUTBUFSIZE 127 #class static //************************************************ void SerEReceive(char *s) { auto int i; serEopen(9600); //serieller Port Initialisierung serErdFree; serErdFlush; serEflowcontrolOff(); serEdatabits(PARAM_8BIT); do { i=serEread(s,6,20); } while(i<6); s[i] = '\0'; printf("%s",s); for(i=0; i<29999; i++) {i++; i--;} ; serEclose(); } //************************************************ main () { const char s1[]="BBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; brdInit(); //Prototypboard initialisieren Start: SerEReceive(s1); SerDwrite(s1); //nicht wichtig fuer Problem goto Start; }
Lass doch endlich mal das const in der Definition von s1 weg! Wie schon oben gesagt: Du willst die Variable ja ändern. Das const bewirkt vermutlich, dass der Compiler s1 ins ROM legt, weswegen die Bs nicht durch die As überschrieben werden können.
Ich muss aber die Variable als const deklarieren, sonst nimmt sie der Compiler nicht an. Oder wie genau soll ich sie deklarieren, damit s1 ins Ram gelegt wird?
OK, hattest Recht Yalu, der Compiler spuckt zwar dann ne Warnung aus, aber es funktioniert!
Was meckert der Compiler, wenn du das const weg lässt? Geht auch char s1[7]; (ohne Initialisierung) nicht? Evtl. hilft es, wenn du das const durch static ersetzst (vielleicht kann der Compiler keine Array auf den Stack legen, wie gesagt, ich kenne weder die Rabbit-Architektur, noch den Compiler), also so: static char s1[] = "BBBBBBBBBBBBBBBBB"; oder so: static char s1[7];
const ist englisch und bedeutet 'konstant'. Wenn etwas konstant ist, dann geht der Compiler davon aus, dass es sich nie aendern wird. Was sich aber niemals aendert kann auch in einem Eprom abgelegt werden. Du willst aber, dass sich die Variable ändern kann. Du willst ja, dass die Zeichen von der Seriellen dort abgespeichert werden. Also kann diese Variable nicht const sein! Verstehst du das nicht? > const char s1[]="BBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; Wozu schreibst du da überhaupt was hinein? Es wird ja sowieso von der Empfangsroutine überschrieben. Lass das halt einfach weg. Abgesehen davon, ist char s1[] = "BBBBBBBBBBBBBBBBBBBBBBBBBBBB"; 100% legaler, richtiger C Code. Wenn dein Compiler das nicht annimmt, dann hat er einen Fehler. Aber wie gesagt, du brauchst da nichts vorgeben, da die Empfangsroutine ja sowieso was reinschreibt: char s1[20]; /* Platz für 20 Zeichen */ > Ich muss aber die Variable als const deklarieren, sonst nimmt sie > der Compiler nicht an Das ist der blödeste Grund überhaupt. Solange du so programmierst kann man dir nur einen Rat geben: Kauf dir ein Buch über C Grundlagen.
Ihr habt ja so recht. Ich habe gedacht, const bedeutet, dass der String an einer festen Stelle gespeichert wird, aber dazu benutzt man ja static(tragische Verwechslung). Jetzt wird mir so einiges klar.... Der Compiler spuckt jetzt auch keine Warnung mehr aus. Danke und sorry wegen meiner Unfaehigkeit.
Hello again, wieder Probleme.... Der uC sendet mit untem geposteten Programm nix, nur wenn ich eine Endlosschleife mit serDwrite mache, dann klappts einwandfrei. Das versteh ich ueberhaupt nicht, ist doch sehr komisch oder, dass er nur bei einer Endlosschleife sendet. Er gibt auch immer an, dass er 6 Zeichen erfolgreich gesendet hat. kann vielleicht jemand den Code checken oder weiss jemand was??? VG Paule #define DINBUFSIZE 127 #define DOUTBUFSIZE 127 #class static //************************************************ void SerDwrite(char *s) { int i,j; j=0; serDopen(9600); serDwrFree; serDwrFlush; serDflowcontrolOff(); serDdatabits(PARAM_8BIT); while(j<6) { j=serDwrite(s,6); } //return-Wert von j ist //erfolgreich //gesendete Bytes serDclose(); } //************************************************ main () { char s1[50]; gets(s1); SerDwrite(s1); //Habe unten die Fkt-Def. von SerDwrite //angehaengt, falls es was hilft } /* START FUNCTION DESCRIPTION ******************************************** serDwrite <RS232.LIB> SYNTAX: int serDwrite(void *data, int length); DESCRIPTION: Transmits length bytes to serial port D. This function is non-reentrant. PARAMETER1: data : data structure to write to serial port D length: number of bytes to write RETURN VALUE: The number of bytes successfully written to serial port D. END DESCRIPTION **********************************************************/ nodebug int serDwrite(void *data, int length) { static int bytesleft; static char *p; p = (char *)data; bytesleft = length; if (cbuf_wrlock(spd_ocbuf)) { while (bytesleft) { bytesleft -= cbuf_put(spd_ocbuf, p+(length-bytesleft), bytesleft); spd_starttx(); } cbuf_wrunlock(spd_ocbuf); } return length - bytesleft; }
Hi. Habe es nun auch mit andern Sendefunktionen(serDputs) ausprobiert und es ist immer das gleiche, nur wenn ich eine Endlosschleife dranhaenge, funktioniert es. Ist das vielleicht generell so, das ich eine Schleife o.ae. programmieren muss, um seriell Daten zu versenden??? Komme nicht weiter an der Stelle, habe alles ausprobiert, waer cool wenn mir jemand helfen koennte. Gruss Paule
Möglicherweise ist die Schnittstelle noch nicht bereit, wenn du bereits versuchst Zeichen zu senden. Die while() Schleife probiert es halt solange, bis tatsächlich mal 6 Bytes rausgegangen sind. Das übertüncht die Probleme. Um diese These zu prüfen, schau dir den Rückgabewert von serDwrite() an, wenn du kein while() verwendest. Ich vermute die Probleme in einer nicht handbuchgemäßen Initialisierung der seriellen Schnittstelle in Verbindung mit der Funktion cbuf_wrlock(). Steht im Datenblatt vom µC und dessen UART was von einzuhaltenden Delays und was macht die Funktion cbuf_wrlock() in deinem Spezial-C?
du hattest Recht Stefan, das Problem war, dass ich die serielle Schnittstelle schon geschlossen hab, obwohl noch nicht alle Daten aus dem Buffer gelesen wurden. Ich hab das Problem dann geloest, indem ich das dazugehoerige Statusregister abgefragt hab und erst bei erfolgter Sendung die Schnittstelle geschlossen habe. Danke fuer den Tipp!!!!!
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.