mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Empfange merkwuerdige Signale(Ausserirdische???)


Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
      }

Autor: Neo81 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmmmm, bist du auch ganz sicher, das dein Eingangssignal korrekt ist?

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
100%, habe mit Oszi gemessen.

Autor: bedenkenträger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Start - Stopbits usw stimmen auf Sender und Enpfängerseite?

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ü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?

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sind evtl. die Signalpegel invertiert?

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In dem Moment geb ich das aus, was im Speicher steht, also die letze
erfolgreich empfangene Char-Kette.

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, nicht invertiert, hab ich schon gecheckt.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du bitte diese Betreffsverstümmelungen unterlassen?

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Koenntest du bitte den Stock aus deinem Arsch nehmen Thomas?

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich guck grad mal nach. Hmmm, nein, ist grad nichts zu machen.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hei Thomas, du verstehst also doch Spass, Respekt(ernst gemeint).

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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???

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es funktioniert. hattest recht mit dem, dass printf einen
nullterminierten String sucht. Yalu ich liebe dich ;-).
Gruss Paule

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Yalu ich liebe dich

Aua ;-)

Trotzdem gern geschehen

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

      }

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, hattest Recht Yalu, der Compiler spuckt zwar dann ne Warnung aus,
aber es funktioniert!

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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];

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;
}

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Paule (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!!!!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.