Hallo, ich versuche gerade mit den Zählern zu hantieren. Ich hätte gerne, das wenn der Zähler 1 'überläuft' ein Interrupt ausgelöst wird. Dazu habe ich folgedes in mein C Programm eingefügt: SEI(); TCCR1B=0b00000101; //Prescaler = 1024, normal Mode TIMSK=0b00000100; //Bei überlauf von Timer 1 ==> ISR Die Interrupt Routine lautet: ISR (TIMER1_OVF_vect) { LcdCursorOn(); } Leider funktioniert das aber nicht so wie ich mir das vorstelle, und kann keinen Fehler finden... Könnte mir bitte jemand helfen ?? Gruss Christian
Immer diese unpräzisen Fragestellungen... Was genau verleitet Dich zu der Annahme, dass 'es nicht funktioniert'? Hast Du es im Simulator oder in der Hardware getestet? Was macht die Funktion 'LcdCursorOn()' genau? Was für ein µC? Welcher Takt? Wie sieht der Rest vom Code aus???...
@Johnny: Da fehlt noch die Frage nach der Taktquelle für den Timer... Ich vermute ja fast, dass da jemand einen Bug gefunden hat...
Die Funktion LcdCoursorOn() schaltet lediglich den Coursor beim Display ein. Da dies nicht funktioniert gehe ich davon aus, das es nicht funktioniert. Getestet wurde das in der Hardware, es handelt sich dabei um einen ATmega 32 mit internen Takt. Hier der Code: int main(int argc, char* argv[] ) { int d=0; InitWaage(); LcdInit(); UartInit(); sei(); while(1){ if ( PIND & (1<<PIND4)){ TCCR1B=0b00000101; TIMSK=0b00000100; d=LesenVonWaage(d); TCCR1B=0b00000000; //TIMSK=0b00000000; SETRDY; SendenAnSps(d); } else{ ClrBit(PORTD,6); LcdWriteStr("Idle"); DelayS(1); LcdClear(); } } //end while } ISR (TIMER1_OVF_vect) { LcdWriteChar(1); }
Du hältst den Timer ja auch immer wieder an, bevor der irgendwas machen kann. Die Funktion 'LesenVonWaage()' kenne ich zwar nicht, aber wenn der Timer mit Prescaler von 1024 läuft und Du ihn alle paar µs startest und ein paar µs später schon wieder anhältst, kannst Du lange warten, bis der auch nur einen einzigen Takt hochzählt...
Damit es klarer wird: 'Interner Takt' heißt ja wahrscheinlich 1 MHz. Also bei Prescaler-Einstellung 1024 gibts alle 1024µs einen Zählerinkrement. Wenn der Timer gestartet wird (TCCR1B=0b00000101;) und TCNT1 0 ist, wird letzteres nach ungefähr 1 ms auf 1 erhöht. Und das ganze muss 65536 mal passieren, bis ein Überlauf eintritt (also mehr als 65 Sekunden unter 'normalen' Bedingungen). Das gilt aber nur dann, wenn der Timer nicht immer schon nach kurzer Zeit (möglicherweise schon vor dem ersten Inkrement) wieder angehalten wird. Der Prescaler wird ja bei jedem Schreibvorgang auch zurückgesetzt, wodurch der Timer überhaupt nichts macht, wenn das was zwischen TCCR1B=0b00000101; und TCCR1B=0b00000000; steht weniger als 1024 Taktzyklen dauert (was zumindest ziemlich wahrscheinlich ist).
Das ganze ist als 'Schutz' gedacht falls die Waage nicht bereit ist und nicht auf die Anforderung reagiert. Deswegen halte ich den ja auch wieder an ... Aber selbst wenn ich 5 min warte und die Waage ausgeschaltet ist, also nicht reagiert springt er mir nicht in die ISR rein.
Damit wären wir wieder bei der Sache mit dem Code: Solange Du nicht mitteilst, was die Funktion LesenVonWaage(d) genau macht, siehts da ziemlich finster aus...
Schau Dir als "Schutz" mal den WatchDog an. (Datenblatt Seite 39) Rick
Soll kein Geheimnis sein ... Das Problem ist, wenn jemand die Waage nicht einschaltet und trotzdem versucht über die SPS den Waagen Wert einzulsesen bleibt mein Programm stehen, da er nach dem senden vom W auf eine Antwort der Waage wartet....
Wenn Du Probleme mit dem Timer vermutest, dann schmeiß den ganzen Schrunz raus, der damit nichts zu tun hat und laß ihn endlich mal frei atmen (laufen). Einen Fehler muß man systematisch einkreisen und nicht planlos rumprobieren. Ein LCD zum Debuggen ist mit Vorsicht zu genießen, es braucht ne Weile, ehe was angezeigt wird, und da kann es schon längst wieder überschrieben worden sein. Nimm lieber eine LED, die sieht man im Dunkeln selbst noch 1µs leuchten. Peter
Wtd bringt mir hier leider nichts, da er ja einen Reset macht, und ich würde aber lieber in der ISR einen Fehlercode ausgeben....
Peter hat trotzdem recht. Wenn du Probleme mit dem Timer hast, dann fang ein 2-tes Testprojekt an, das sich nur mit dem Timer besdchäftigt und mit sonst nichts anderem. Dadurch konzentrierst du deine Gedanken auf diesen Problemkreis und hast nicht noch 20 andere Dinge die in dem Programm schief gehen können. An diesem Testprogramm kannst du dann nach Herzenslust rumprobieren und auch das Programm nach Lust und Laune umbauen um zu sehen wie die Dinge wirklich funnktionieren. Auf die Art lernst du schon fast spielerisch, wie man mit einem Timer (oder was anderem) umgeht und kannst das Gelernte dann viel schneller in deinem eigentlichem Program umsetzen.
So, also in meinem 'Extra' Projekt geht es ... Nur nicht wenn ich es in mein eiegntliches Projekt einbinde gehts nicht. Könnte es sein, da ich ja die serielle Übetragung absichern möchte, das dort Interupts deaktiviert werden. Würde zwar keinen Sinn ergeben aber.... Zur erinnerung: Ich fordere einen Wert von der Waage an und warte auf diesen. Damit der Microcontroller nicht bis in alle ewigkeit wartet wollte ich durch einen Timer Überlauf erreichen, das eine Fehlermeldung ausgegeben wird. Anbei mal noch die Funktion für Senden/Empfangen ...
Nein. Wenn du nicht explizit einen cli() machst, laufen die Interrupts weiter wie gehabt. Bist du absolut, 100% sicher, dass die ISR nicht aufgerufen wird?
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.