Hallo, ich habe ein Problem bei der Programmierung des PIC16f690. Ich möchte die übliche Anwendung einer Uhrenschaltung mit einem 32768Hz Uhrenquarz programmieren. Aus dem Grund erzeuge ich mit einem Vorteiler von 32:1 einen Interrupt im sekundentakt. Soweit so gut. Allerdings möchte ich zu Testzwecken einfach im sekundentakt erst einmal eine LED des PIC Kit 2 an und ausschalten. dazu verODERe ich den PORTC mit einer Bitmaske... (0x01) Das Problem: DIE VERDAMMTE LED BLEIBT IMMER AN!!!! Assembler Code: #include <p16F690.inc> __config (_XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF) takt EQU .32768 whelp EQU 0x20 shelp EQU 0x21 maske EQU 0x22 org 0 goto start org 4 goto interrupt start: bsf STATUS,RP0 ;Bank1 clrf TRISA ;Port A, B und C Ausgang clrf TRISB clrf TRISC movlw B'00000100' ;interner Taktteiler auf 256 movwf OPTION_REG bsf STATUS,RP1 ;Bank2 clrf ANSEL ;alle I/O Ports digital clrf ANSELH bcf STATUS,RP1 ;Bank 0 bcf STATUS,RP0 bsf INTCON,T0IE ;TMR0 & Interrupts freigeben bcf INTCON,T0IF bsf INTCON,GIE clrf PORTA ;Port A, B und C Low clrf PORTB clrf PORTC goto loop loop: goto loop interrupt: movf PORTC,w xorlw 0x01 movwf PORTC bcf INTCON,T0IF retfie end Bitte seht mir nach falls es sich um einen trivialen Fehler handelt... Aber das treibt mich in den Wahnsinn.
Fehler Interrupt: erst mal Register retten Alternative: 32768-Quarz an den Timer1 und den frei laufen lassen
uxdx schrieb: > noch was: auch PEIE frei geben Unsinn - der Timer0 braucht den PEIE nicht. Gruß Jens
das mit dem Register retten ist mir durchaus bewusst. Allerdings dachte ich in meinem Fall, dass dies vernachlässigbar ist, da ich den Inhalt der Register sowieso nicht brauche. Mir ist sowieso schleierhaft was es mit dem "Register retten" auf sich hat. Kann mal jemand etwas ausholen und mir die Hintergründe erklären warum man ein Register "retten" muss? Kann das die Ursache für das fehlerhafte Verhalten sein?
Warum Register retten? z.B. ein ganz trivialer Fall: der Wert 0x55 soll in die Speicherstelle "var1" geschrieben werden...also ..... movlw 0x55 movwf var1 ..... jetzt tritt währen der Ausführung von "movlw 0x55" ein Interrupt auf und in der Interruptroutine wird W verwendet und bekommt dabei den Wert 0xff (nur als Beispiel). Was landet dann nach Ende der Int-Routine wohl in "var1"??
Ok das verstehe ich. Allerdings verstehe ich immer noch nicht warum meine LED nicht blinkt sondern dauerhaft an ist. Durch das XORLW müsste doch das Bit bei jedem Interrupt umgedreht werden... Und da "loop" ja nur eine Endlosschleife ist dürfte das weggelassene retten der Register ja auch keine Rolle spielen oder verstehe ich da noch was falsch?
Andy K schrieb: > bsf STATUS,RP1 ;Bank2 > clrf ANSEL ;alle I/O Ports digital > clrf ANSELH > bcf STATUS,RP1 ;Bank 0 Andy K schrieb: > start: > bsf STATUS,RP0 ;Bank1 > clrf TRISA ;Port A, B und C Ausgang > clrf TRISB > clrf TRISC > movlw B'00000100' ;interner Taktteiler auf 256 > movwf OPTION_REG > bsf STATUS,RP1 ;Bank2 > clrf ANSEL ;alle I/O Ports digital > clrf ANSELH > bcf STATUS,RP1 ;Bank 0 > bcf STATUS,RP0 Erst schaltest Du auf Bank1 und dann mit bsf STATUS,RP1 auf Bank 3 !!! und nicht wie gewünscht auf Bank2. Da fehlt noch: bcf STATUS,RP0
KLASSE! DAS WAR DIE LÖSUNG!!!! Durch die falsche Bankauswahl war scheinbar Port C nicht korrekt als Digital I/O definiert... oh man. die einfachen fehler sind die schlimmsten... Vielen Dank für die rege Anteilname!
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.