mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART_ Werte empfangen???


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum Freunde

Ich habe mir ein kleines Terminal Programm in VBA geschrieben mit dem
ich einzelne Werte über der Serielle Schnittstelle COM1 zu meinem
Controller senden kann.

So weit so gut.

Jetzt möchte ich diese Zeichen mit meinem Controller AT89S8252
empfangen und auswerten.

Das Problem liegt jetzt darin ich kann ein Zeichen empfangen, sende ich
aber ein zweites passiert gar nichts. Woran liegt das mache ich noch
ein Fehler im Code?

Muss ich irgent einen Puffer nach dem Empfangen wieder leeren oder
setzten???

Mit freundlichen Grüßen
Christian


Auszug aus meinem Quellcode

void main()
{
   unsigned char speicher_1;

   LCD_INI();
   LCD_text(0x80,"EMPFANGEN");
   LCD_kursor(2);
   COM_INI();

   while(1)
   {
  zeit();
  while(RI==0);
  speicher_1 = SBUF;
  LCD_variable(0x97,speicher_1);
   }
}

Autor: ispodvala (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weiß nicht, ob deine C-Routinen das machen, aber RI muß per Software
gelöscht werden.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht das dann wohl so aus??

void main()
{
   unsigned char speicher_1;

   LCD_INI();
   LCD_text(0x80,"EMPFANGEN");
   LCD_kursor(2);
   COM_INI();

   while(1)
   {
      zeit();
      RI = 0;
      speicher_1 = SBUF;
      LCD_variable(0x97,speicher_1);
   }
}

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wofür ist zeit() gut? Warte lieber, bis ein Zeichen da

{while (!RXC);  //USR.7
 xxx=SBUF;      //das lesen von SBUF löscht automatisch das RXC-Flag
}

Wenn du sowieso nicht mit receiver-interrupt arbeitest, brauchst du
auch das Int-flag nicht

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Crazy horse

das ist auf jeden Fall eine bessere Lösung. Kannst du mir noch sagen
was RXC ist. Das kenne ich nicht..

Wie würdest du denn so ein Problem angehen?? Gibt es insgesamt eine
bessere Lösung.

Christian

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"das ist auf jeden Fall eine bessere Lösung. Kannst du mir noch sagen
was RXC ist. "
steht doch extra dabei, Bit7 des USR-Registers. Wird immer gesetzt,
wenn ein Zeichen empfangen wurde - lies dir mal das Kapitel über die
UART des AVR durch.

"Wie würdest du denn so ein Problem angehen?? Gibt es insgesamt eine
bessere Lösung."

die beste Lösung ist immer die, die mit minimalem Aufwand das leistet,
was man will. Ich persönlich kann Programme nicht leiden, die zur Not
ewig auf ein event warten - und wenn das nicht kommt, steht alles. Wenn
das Programm aber sowieso nichts anderes macht, als empfangene Zeichen
aufs Display zu schreiben, ist das allerdings egal - kommt nichts, wird
nichts geschrieben, der Effekt ist der Gleiche.
Ich betreibe die serielle Schnittstelle eigentlich immer im Interrupt
mit Empfangsbuffer, ankommende Zeichen werden in einen Buffer
geschrieben, das Hauptprogramm kann prüfen, ob was angekommen ist und
die Daten lesen, wenn nichts da ist - eben nicht.

Christian

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok vielen Danke für die gute Info.

Ich glaube ich muss mich jetzt mit den Interrupt beschäftigen.
Genau das was du da beschreibst brauche ich.

"Interrupt mit Empfangsbuffer"

Hast du vieleicht ein paar Allgemeine Infos oder ein Quellcode Beispiel
in C.

Christian

Autor: ispodvala (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich dachte eigentlich an so etwas:

void main()
{
   unsigned char speicher_1;

   LCD_INI();
   LCD_text(0x80,"EMPFANGEN");
   LCD_kursor(2);
   COM_INI();

   while(1)
   {
  zeit();
  while(RI==0);
  speicher_1 = SBUF;
  RI=0;
  LCD_variable(0x97,speicher_1);
   }
}

Was RXC ist, weiß ich auch nicht. Übrigens auch nicht, was ein
AT89S8252 mit AVR gemeinsam hat, außer dem Hersteller.

Autor: Christian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ispodvala
danke für deine Antwort. Es funktioniert !!

Kannst du mir etwas zu "Interrupt mit Empfangsbuffer" sagen?
oder hast du vieleicht einen guten LINK oder Quellcode für mich.

Christian

Autor: ispodvala (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm..

du mußt eine ISR (Interrupt Service Routine) schreiben, in der daß
empfangene Byte unter der Speicherstelle, auf die global definierter
Zeiger zeigt abgelegt wird und der Zeiger für das nächste Byte
inkrementiert wird (RI=0 setzen nicht vergessen :). Das Hauptprogramm
überprüft, ob der Zeiger sich vom Initialwert(Konstante) unterscheidet.
Und wenn es so ist, den Puffer ausliest und den Zeiger zurücksetzt.
Wie du dem Compiler sagst, daß es eine ISR ist, steht in der Doku.

Viel Erfolg.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ispodvala

Das ist Neuland für mich...
Aber ich werde das schon hin bekommen.

Christian

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bisschen kompizierter ist es schon.
Am einfachsten arbeitet es sich mit einem Ringbuffer, sagen wir mal 8
byte gross.
Zur Verwaltung benutzt man 3 Register, einen Schreibpointer, einen
Lesepointer und ein Zählregister (Anzahl der empfangenen Bytes).
-Zeichen wird empfangen -> Rx-Int wird ausgelöst
-das byte wird an der durch den Schreibpointer addressierten
Speicherzelle abgelegt
-der Schreibpointer wird erhöht und geprüft, ob dabei die max.Adresse
überschritten wurde, wenn ja, auf die Anfangsadresse zurücksetzen
-byte-Zähler erhöhen fertig.

Gelesen wird, wenn Zeit dafür ist. Zuerst prüfen, ob der Counter > 0
wenn ja:
-ein byte aus der durch den Lesepointer adressierten Speicher holen
-Lesepointer erhöhen, wenn > max_Adresse zurücksetzen
-byte-Zähler erniedrigen

Wenn man es ganz gut machen will, kann man noch ein Flag für den
Bufferoverrun (mehr Zeichen empfangen, als der der Buffer aufnehmen
kann) programmieren, damit man erkennen kann, dass etwas verloren
wurde.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo crazy horse

Ich kann es nur noch mal wiederholen vielen Dank für die super
Anleitung. Ich glaube das hilft mir auf jeden Fall sehr weiter.

Ich ärger mich gerade mit meinem Handy herum.
Ich sende meinem Handy den Befehl "AT ccr" und möchte nun das OK
empfangen. Es kommt aber leider gar nichts...

Meine Aufgabe ist es eine SMS mit dem Controller auszuwerten..
Senden ist kein Problem nur das Empfangen..
Ich weiß nicht warum.

Grüße Christian

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.