Hallo, ich hab einen PIC programmiert und möchte über die serielle Schnittstelle Daten empfangen. Insgesamt werden 2 Byte über die serielle Schnittstelle geschickt. 1. Byte ist der Befehl und das 2te Byte sind die Daten. Leider kann ich aber nur den Befehl verarbeiten und keine Daten. Weiß vielleicht jemand, was ich möglicherweise falsch programmiert habe? Programmausschnitt: ;Interrupt ;RS232-Empfänger-Interupt? btfss PIR1,RCIF goto intEnde ; Interrupt kam von wo anders movfw RCREG ; RS232-Register auslesen movwf Zeichen ; und in den Speicher nach 'Zeichen' schreiben ;verarbeiten von Zeichen ;Interruptende
Könnte es evtl. sein, das ein Framing Error (PC sendet mit Parität, PIC empfängt im 8-Bit Modus) auftritt? MfG Steffen
Das Interupt-Flag wird durch lesen von RCREG gelöscht. Das ist richtig. Das Framing-Error Bit wird beim Lesen auch gelöscht, da lag ich eben falsch. Möglicherweise tritt ein Overrun ein, der muss dann durch die Software gelöscht werden (CREN löschen und wieder setzen). Sonst können keine Daten mehr empfangen werden. Eine andere Möglichkeit währe, das irgendwo im Rest des Programmes der Interupt ausgeschaltet wird.
das CREN lösche ich aber auch jedes mal wieder, damit der Fehler schon gar nicht auftreten kann Pic16F628
Hallo, was steht den nach dem Auslesen im PIR1 Register noch drin? Bei nur 2 Datenbyte dürfte ein Overrun noch nicht auftreten.
im MPLAB das Register ins watch window aufnehmen und beobachten beim Durchsteppen. Bis morgen. MfG Manfred Glahe
CREN muss auf jeden Fall wieder gesetzt werden, da sonst der Empfang gestoppt wird. Das Löschen und setzen von CREN setzt die komplette Empfangslogig zurück. Das sollte nur passieren, wenn wirklich ein Overrun aufgetreten ist (was bei zwei Byte nicht passieren dürfte). Also wenn OERR gesetzt ist. Wird die Empfangslogig so zurückgesetzt, dann geht wahrscheinlich dadurch das zweite Byte verloren. MfG Steffen
Hallo, da ich den f628 selbst noch nicht einsetze habe ich mal im datenblatt nach geschaut und folgendes gefunden: org 4 ; Interrupt beginnt immer bei Adresse 4 int movwf w_temp ; status retten swapf STATUS,w movwf status_temp ;RS232-Empfänger-Interupt? btfss PIR1,RCIF goto intEnde ; Interrupt kam von wo anders movfw RCREG ; RS232-Register auslesen movwf Zeichen ; und in den Speicher nach 'Zeichen' schreiben bcf PIR1,RCIF ; interrupt-Flag löschen intEnde ; geretteten Status wieder zurückschreiben swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie Diese Rutine löscht explizit das INT Flag Bit wieder! Ich würde erst einmal im POLL Modus versuchen das RCIF Bit im PIR1 Register (ADR0ch) zu testen. Damit können sie erst mal überprüfen ob eine 2 Byte Übertragung überhaupt vom Sender stattfindet und ob alle anderen Bedingungen (Baudrate, Framing, Handshake usw.)korrekt sind. Auf diesem Level arbeite ich noch gern mit einem Scope zur Kontrolle. MfG Manfred Glahe
Auszug aus dem Datenblatt: "RCIF is a read-only bit, wich is cleared by the hardware. It is cleared when the RCRREG register has been read and is empty." Ich setze den 16F628 ein. Daher kann ich die Richtigkeit bestätigen. Mir ist aber noch etwas anderes aufgefallen. Die veröffentlichten Codesegmente haben beide den gleichen Fehler. RCREG hat die Adresse 0x1A und PIE1 die Adresse 0x8C, liegt also in Bank 1. Vielleicht liegt da der Fehler? MfG Steffen
Sorry, hab PIE1 und PIR1 verwechselt. Also ist der oben gezeigte Code richtig. MfG Steffen
Ohne den kompletten Code kann man da nichts weiter dazu sagen. Wird denn das erste Byte auch richtig empfangen? Sind in der ISR alle Interupts gesperrt (INTCON,GIE=0)? Sonst könnte es dazu kommen, das während der Auswertung von Zeichen erneut ein Interupt durch das 2. Byte ausgelöst wird. Das würde dann aber auch schnell einen Stack-Overflow auslösen. MfG Steffen
Hallo, im Datenblatt des 16F628 ist unter 12.3 die Vorgehensweise gut beschrieben wie die asynchrone Funktion benutzt wird. Übersehen werden in der Regel die sebstverständlichen Einstellungen, und gesucht wird unter den etwas verborgeneren. Meine Erfahrung ist, daß ich dann doch irgendetwas übersehen oder als bereits getan angesehen hatte. MfG Manfred Glahe
das erste Byte wird richtig empfangen und das 2te Byte kommt nicht mehr an. GIE habe ich auch gelöscht. An welcher Stelle muss ich das eigendlich genau löschen?
Hallo, ich mach das immer am Ende der Int Rutine. Aber der global INT muß ja nicht gelöscht werden (gilt ja auch für andere Quellen). Ist das 1. Byte denn in Ordnung, entspricht es dem gesendeten Character? Mal Bitmuster wechseln. Wer oder Was ist der Sender, mal mit Hyperterminal probieren. Der Uart hat ein serielles Schieberegister und ein paralell Register so daß beide Byts empfangen werden können. Was steht denn als 2. Byte im seriellen Register für ein bitmuster? Arbeiten Sie mit MPLAB, dann mit watch windows ansehen. Aus der Ferne ist ansonsten nicht mehr viel zu tun. MfG Manfred Glahe
Hab mir gerade noch mal die Doku angeschaut. Ein Interupt löscht automatisch INTCON,GIE und retfie setzt es wieder. Daran kann es also nicht liegen. MfG Steffen
Hallo Steffen, einmal heißt es im Datenblatt "RCIF ist nur lesbar", und dann unter 12.3-10 wieder lösche das ADEN und RCIF Bit. Die meinen wohl indirekt. Aber aus dem Timing Diagramm geht eindeutig hervor, daß das RCIF Bit durch Auslesen des Bufferregisters automatisch gelöscht wird. Wenn ich den Type vorliegen hätte würde ich das jetzt mal mit MPLAB untersuchen. Womit arbeitest Du? MfG Manfred Glahe
Ich arbeite ebenfalls mit MPLAB. Der oben gezeigte Code sollte soweit OK sein. Ich verwende fast den selben, nur das ich vorher teste ob der Emfangsinterupt (Systembedingt) auch freigegeben ist und es funktioniert ohne Probleme. Das Problem kann daher (denke ich mal) nur in der Auswertung des empfangenen Bytes liegen. Man hat schnell mal anstatt movfw Byte movlw Byte geschrieben, dann w ins FSR und eine Schleife mit indirekter Adressierung und schon sind die ganzen SFR futsch. Solche Fehler übersieht man dann einfach. Da hilft wirklich nur Schritt für Schritt durch die ISR und dabei alle wichtigen Register beobachten. Evtl. könnten wir ja mal über den gesammten Code schauen aber dafür bäuchten wir ihn erst. MfG Steffen
Ich habe mal schnell drübergeschaut. Dabei ist mir aufgefallen, das ja eine ganze Menge Code in der ISR abgearbeitet wird. Könnte es da nicht evtl. doch passieren, das der Interupt vom 2. Byte eintrifft, wenn gerade die ISR abgearbeitet wird? Ich denke zwar, das der PIC dann sofort nach dem RETFIE wieder in die ISR Springen würde, bin mir da aber nicht ganz sicher. Wenn zufällig ein TMR0-Interupt und ein Recive-Interupt gleichzeitig auftreten wird der Recive-Interupt nicht abgearbeit. Ich persöhnlich halte die ISR immer so kurz wie möglich. Bei der seriellen Kommunikation schreibe ich jedes Byte erst einmal in einen Puffer. Ist der empfangene Datensatz vollständig, wird in der ISR ein Flag gesetzt und dann im Hauptprogramm das Ganze in aller Ruhe ausgewertet. Ich würde das Programm erst einmal soweit reduzieren, das nur die serielle Datenübertragung (nur der reine empfang ohne große Auswertung) stehen bleibt und dann den Rest wieder einbauen. Dann kann man leichter mal dies oder jenes testen. So umfangreich wie das Programm ist verliert man schnell den Überblick. Noch ein Hinweis zum TMR1-Interupt: Das Interuptflag sollte nur zurückgesetzt werden, wenn es auch ein TMR1-Interupt war, sonst geht einer der während der Abarbeitung der ISR auftritt "verloren". MfG Steffen
super, danke für die schnelle Antwort, dann werde ich das jetzt mal etwas abändern
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.