Hallo Leute, ich bin gerade dabei einen gewissen Teil eines Protokolls (MIDI-Program-Change-Befehle) mit meinem PIC entgegenzunehmen. Das tut noch nicht so ganz wie ich will. Der ProgChange-Befehl setzt sich folgendermaßen zusammen: C nn pp C= Hex C (bin 12) nn = Channelnumber (in diesem Beispiel noch 0) pp = Preset von 1 bis 127. Es wird also immer ein Status- und ein Datenbyte gesendet. Schaltung und eigentlicher UART-Empfang funktionieren. Mit folgendem Code hab ichs getestet: ISR btfss PIR1, RCIF ; Pruefen ob Interupt durch Receive ausgeloest wurde goto ISREND ; Wenn nein, gehe zu Ende von ISR movfw RCREG ; Empfangsregister auslesen movwf preset ; nach preset schreiben call RS232Send bcf PIR1, RCIF ; Receive-Interupt-Bit wieder loeschen ISREND retfie ; Zurückkehren aus Interuptroutine damit kann ich eben eine 3 schicken und bekomme 003 angezeigt usw... Und dies soll nun die nue ISR mit Auswertung sein, hier passieren seltsame, teils unwillkürlich scheinende Dinge. sieht an den 7-segmentern so aus, also ob teilweise mehrere (alle?) presets durchlaufen werden. Hat vl. jemand einen tip? ISR btfss PIR1, RCIF ; Pruefen ob Interupt durch Receive ausgeloest wurde goto ISREND ; Wenn nein, gehe zu Ende von ISR movfw RCREG ; Empfangsregister auslesen btfsc Flags,1 ; Wurde schon ein Statusbyte (Bit1) empfangen? goto EmpfangStatusByte ; Wenn nein gehe zu Empfang Statusbyte goto EmpfangDatenByte ; Wenn ja, gehe zu Empfan Datenbyte EmpfangStatusByte movwf Bytetemp ; Schreibe Empfangsbyte in TempVariable movlw h'C' ; Als erstes wird der Hexwert "C"(=Programm Change) subwf Bytetemp,0 ; vom Sekundären Empfangspuffer abgezogen subwf Channel,0 ; Danach Wird die Kanalnummer abgezogen btfss STATUS,Z ; Ist das Ergebnis = "0" ? goto MAIN ; Wenn nein, gehe zurück zu Main bsf Flags,1 ; Markiere dass der erste Teil Empfangen wurde goto ISREND ; Beende ISR EmpfangDatenByte bcf Flags, 1 ; Setze Empfangsbytezuordnung wieder zurück, für die ; Nächste Nachricht movwf Bytetemp ; Schreibe Empfangsbyte in TempVariable sublw D'127' ; Ziehe Maximalwert ab btfsc STATUS, Z ; Ist das Ergebnis Null? goto PresetZuweisung ; Wenn ja, gehe zur Zuweisung btfsc STATUS, C ; Ist das Carry-Bit gesetzt? goto PresetZuweisung ; Wenn ja, gehe zur Zuweisung goto ISREND ; Wenn nein, dann Wars wohl nix! PresetZuweisung movfw Bytetemp movwf preset goto ISREND ISREND call RS232Send bcf PIR1, RCIF ; Receive-Interupt-Bit wieder loeschen retfie ; Zurückkehren aus Interuptroutine irgendwie versteh ich nicht o ganz wie ich mit dem simulator umgehen soll.....
Also ich hab nicht den ganzen Code durchforstet, aber der Befehl GOTO MAIN innerhalb der ISR ist da bestimmt NICHT richtig. Die ISR sollte eigentlich immer mit RETFIE abgeschlossen werden - sonst STACK-Overflow und dann undefiniertes Programmverhalten. Ich würde einfach mal an dieser Stelle weitersuchen. TK
Hey! Danke! muss natürlich zu ISREND springen. kanns jetzt leider hier auf der Arbeit nicht direkt auprobieren ob ds alles war, aber war natürlich schon n dämlicher leichtsinsfehler! herzlichen dank!
Hi nochmal, bin gerade weiter am rumprobieren, aber irgendwie verbessert sich nichts. der aktuelle code ist: ISR btfss PIR1, RCIF ; Pruefen ob Interupt durch Receive ausgeloest wurde goto ISREND ; Wenn nein, gehe zu Ende von ISR movfw RCREG ; Empfangsregister auslesen movwf Bytetemp btfsc Flags,1 ; Wurde schon ein Statusbyte (Bit1) empfangen? goto EmpfangStatusByte ; Wenn nein gehe zu Empfang Statusbyte goto EmpfangDatenByte ; Wenn ja, gehe zu Empfan Datenbyte EmpfangStatusByte movfw Bytetemp sublw h'C' ; Konstante C (Prog-Change kennung) abzihen subwf Channel,0 ; Danach Wird die Kanalnummer abgezogen btfss STATUS,Z ; Ist das Ergebnis = "0" ? goto ISREND ; Wenn nein, beende empfang bsf Flags,1 ; Markiere dass der erste Teil Empfangen wurde goto ISREND ; Beende ISR EmpfangDatenByte bcf Flags, 1 ; Setze Empfangsbytezuordnung wieder zurück, für die ; Nächste Nachricht movfw Bytetemp sublw D'127' ; Ziehe Maximalwert ab btfsc STATUS, Z ; Ist das Ergebnis Null? goto PresetZuweisung ; Wenn ja, gehe zur Zuweisung btfsc STATUS, C ; Ist das Carry-Bit gesetzt? goto PresetZuweisung ; Wenn ja, gehe zur Zuweisung goto ISREND ; Wenn nein, dann Wars wohl nix! PresetZuweisung movfw Bytetemp movwf preset goto ISREND ISREND call RS232Send bcf PIR1, RCIF ; Receive-Interupt-Bit wieder loeschen retfie ; Zurückkehren aus Interuptroutine
Also wenn ich mir den Code der ISR mal ansehe, kann ich sonst keine gravierenden Probleme mehr erkennen. Frage: Wie gehst Du mit Fehlübertragungen um? z.B. Overflow oder FrameError. Wenn sowas passiert, dann sollte RCREG nicht mehr verarbeitet werden. Wenn mehrere Interrupts aktiviert sind, dann sollten alle Interrupts verarbeitet werden, bevor man über RETFIE rausspringt, da sonst eben nur ein INT verarbeitet wird und ein anderer evtl. nicht mehr aktiviert werden kann, weil das FLAG durch RETFIE automatisch gelöscht wird. Was passiert denn genau in deinem Programm? Wie äußert sich der Fehler. Vielleicht liegts ja auch an der Ausgabe über die Segmentanzeige??? Vielleicht kommt ja ein Interrupt zu einem 'ungünstigen' Zeitpunkt?? Gruß TK
Gleich noch einen hinterher: Schau mal hier http://www.piclist.com/techref/microchip/rs232.htm Da ist ein Auszug aus der Overflow / FrameError Behandlung gezeigt. Könnte hilfreich sein. Gruß TK
es gibt nur diesen einen interupt. Das mit der Oveflowbehandlung muss ich mir mal genauer anschauen
Mein Problem war sehr dummer natur!!! Das DatenBYTE im Midiprotokoll besteht ja aus zwei hexwerten ich schicke also mit kanal null 0xC0 . Dann kann ich natürlich im Programm nicht einfach 0xC abziehen! ich mach ja dann 192-12 = 0 und frag mich warums nicht passt. hab irgendwie den übeblick zwischen nipples und bytes verloren!
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.