Hallo! Ich versuche eine Implusbreite mittels der Capture-Funktion eines 16F877 zu realisieren. ´Sprut's Seite hat dabei schon prima geholfen, es fehlt mir aber irgendwie noch ein wenig Information zum grundsätzlichen Ablauf. Die Init sieht etwa so aus: banksel CCP1CON clrf CCP1CON bcf CCP1CON,CCP1M0 bcf CCP1CON,CCP1M1 bcf CCP1CON,CCP1M3 bsf CCP1CON,CCP1M2 banksel PIE1 BSF PIE1,CCP1IE banksel PIR1 clrf PIR1 clrf PIR2 BSF INTCON,GIE BSF INTCON,PEIE Die Interrupts kommen korrekt an der erwarteten Flanke, ich habe einen Logic-Analyzer sowohl am Eingang (zu messende Größe) als auch an meinem Zestausgang. De3r Int sieht so aus: movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register movf PCLATH,w ; move pclath register into w register movwf pclath_temp ; save off contents of PCLATH register banksel PORTC bsf PORTC,0 ; Zur Ereignisanzeige-ASnfang im Analyzer auf 1 setzen ;Capture-Interrupt? btfss PIR1,CCP1IF goto intEnde ; Interrupt kam von wo anders movfw CCPR1H ; High Teil movwf CapHigh ; in den Speicher nach 'CapHigh' schreiben movfw CCPR1L ; Low Teil movwf CapLow ; in den Speicher nach 'CapLow' schreiben clrf TMR1L clrf TMR1H clrf CCPR1H clrf CCPR1L bcf PIR1,CCP1IF ; Flag löschen intEnde ; geretteten Status wieder zurückschreiben movf CapHigh ; Entscheiddung 0 oder 1 sublw .120 ; Schwellwert btfss STATUS,C ; Übergehe next wenn Übertrag=1 goto SetBit ; ; Bit 7 Soll die Definition von 0 oder 1 anzeigen, funktioniert aber nicht richtig!! ; clrw PreamCount ; keine Preambel! bcf PORTC,7 ; eine Null!! goto SetEnd SetBit bsf PORTC,7 ; eine Eins!! incf PreamCount,1 movf PreamCount subwf D'14' btfss STATUS,Z goto SetEnd clrf PreamCount bsf PORTC,6 ; Preambel-Marker nop nop nop nop nop nop nop bcf PORTC,6 SetEnd bcf PORTC,0 ; Zur Ereignisanzeige-Ende im Analyzer auf 0 setzen movf pclath_temp,w ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt Sinn und Zweck soll sein, daß alle Abstände zwischen den Int-Ereignissen, die kleiner/gleich 120 Mikrosekunden als 1-Wert darzustellen, alle Zeiten zwischen zwei Interrupts die größer alls 120 Mikrosekunden sind sollen eine 0 darstellen. Der Capture-Mechanismus kopiert laut Sprut (und auch laut der PIC-Doku) die Werte von Timer0 in temporäre Variablen. Was ich irgendwie nicht so richtig verstanden habe: muß ich den Timer dann selbst zurücksetzen? Gibt bes vielleicht einen eleganteren Weg, die Pulsbreiten per Schwellwert zu bestimmen? Ich bin noch relativer PIC-Neuling, habe früher sehr viel mit x86-Assembler programmiert und denke leider noch immer nicht wirklich in RISC-Instruktionen.... Aber Übung soll ja den Meister machen. mfg Hagen Schlömer
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.