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); } }
weiß nicht, ob deine C-Routinen das machen, aber RI muß per Software gelöscht werden.
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); } }
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
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
"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
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
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.
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
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.
Danke ispodvala Das ist Neuland für mich... Aber ich werde das schon hin bekommen. Christian
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.
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
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.