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
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!
Eine eigene Frage?
Dieser Thread ist über 19 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.