PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme bei TMR0



chipo78
12.07.2015, 13:35
Hallo zusammen,
Hätte da ein kleines PROBLEM mit meinem Timer und den dazugehörigen Interrupt.
Möchte erstmal nichts anderes tun als mit dem Interrupt eine LED zum leuchten bringen.
Habe dazu einen PIC 16F628 mit dem internen takt konfiguriert und möchte das bei jedem Überlauf ein Interrupt ausgelöst wird.
Mein Problem ist jetzt das da leider nichts passiert, wenn ich die Hex Datei auf den Pic brenne.
Hier ist dazu mein Quellcode.
Danke schonmal im Vorraus.


void Timer_ini()
{
OPTION_REG = 0b11000000;
TMR0 = 0;
INTCON = 0b10100000;
}
unsigned counter ;
void Interrupt()
{
GIE_bit = 0;
T0IF_bit = 0;
counter++;
GIE_bit = 1;
return;

}

void main()
{
TRISB.RB5 = 0;
CMCON = 0x07;
Timer_ini();
if(counter >= 50)
{
PORTB.RB5 = ~PORTB.RB5;

}

while(1);
}

witkatz
12.07.2015, 18:54
Welcher Compiler wird benutzt? Wie sind die CONFIG Flags gesetzt?

// Und warum benutzt du nicht das CODE Tag zum lesbaren Code Einfügen?

Hier ein paar Bemerkungen zu deinem Codeschnipsel
1. Schreiben auf RB5 muss in der Endlosschleife passieren, sonst passiert endlos nichts ;-)
2. Das Rücksetzen des Counters auf 0 fehlt, ist das beabsichtigt?
3. Das Handling des GIE_bit wird normallerweise vom Compiler erledigt, das manuelle Setzen innerhalb der Interruptroutine ist überflüssig, kann sogar zu Fehlern führen, deswegen nochal die Frage, welcher Compiler wird benutzt? Was steht im Compilerhandbuch zu Interruptroutinen?

Gruß
witkatz

- - - Aktualisiert - - -

Noch was, C ist Casesensitiv. Wenn der Compiler

void interrupt(void);
als spezielle Interruptroutine deklariert, dann wird

void Interrupt(void);
gar nicht aufgerufen!

Klebwax
12.07.2015, 18:57
3. Das Handling des GIE_bit wird normallerweise vom Compiler erledigt, das manuelle Setzen innerhalb der Interruptroutine ist überflüssig, kann sogar zu Fehlern führen, deswegen nochal die Frage, welcher Compiler wird benutzt? Was steht im Compilerhandbuch zu Interruptroutinen?

Das erledigt nicht der Compiler, das macht der Chip selbst. Bevor man also nicht ganz genau weiß, was man tut, sollte man an diesem Bit im Handler nicht spielen.

MfG Klebwax

witkatz
12.07.2015, 19:07
Das erledigt nicht der Compiler, das macht der Chip selbst.
Ja, hast recht. Der Compiler übersetzt die Interruptroutine richtig mit RETFIE und der PIC macht den Rest. Mir schwante da was aus dem XC8 Handbuch dazu. Hier der entspr. Auszug:
Never re-enable interrupts inside the interrupt function itself. Interrupts are
automatically re-enabled by hardware on execution of the RETFIE instruction.
Re-enabling interrupts inside an interrupt function may result in code
failure.

Nachtrag:
Im MikroC Manual habe ich diesbezüglich keinen Hinweis gefunden. Das ist mMn eine Schwachstelle der MikroC-Dokumentation.

chipo78
12.07.2015, 21:35
Vielen Dank für die Hilfe. Habe den Code etwas umgeschrieben und jetzt funktioniert es. Benutze den Compiler von Micro C.
Einen Blick ins Handbuch erleichtert Fehleranalyse. In Assembler hab ich das GIE Bit immer im Code manuell gesetzt oder gelöscht. Hab es hier deshalb wahrscheinlich noch hingeschrieben. Leuchtet jetzt natürlich ein das es überflüssig ist.
Danke nochmal
Gruß Chipo

Klebwax
12.07.2015, 22:39
In Assembler hab ich das GIE Bit immer im Code manuell gesetzt oder gelöscht. Hab es hier deshalb wahrscheinlich noch hingeschrieben. Leuchtet jetzt natürlich ein das es überflüssig ist.

Es ist nicht überflüssig, es ist sehr gefährlicher Code, ob in C oder in Assembler. Wenn man nicht wirklich weiß, was man tut, sollte man weder in C noch in Assembler im Interrupthandler das Interrupt-Enable Bit anfassen.

MfG Klebwax