Hallo zusammen, ichhabe ein etwas gröeres Programm in dem ich zur Abarbeitung einer Funktion einen Timer benötige. Da ich mit Timern noch nie was zu tun hatte hab ich mit nun vorgenommen dass ich auf meinen ATMEGA32 einfach mal ein Timer-Testprogramm draufspiel, damit ich den prinzipiellen Umgang mit Timern lerne. Das Programm sollte so Funktionieren, dass die LED`s auf meinem STK500 alle 1,9 Sekunden blinken. Leider funktionier garnichts. Da ich kein Oszi hab kann ich nichtmal überprüfen ob überhaupt ein Takt rauskommt. Hier das Progrämmchen: /**************************************** T I M E R T E S T P R O G R A M M ****************************************/ #include <avr/io.h> #include <avr/interrupt.h> ISR( TIMER1_OVF_vect ) { PORTB ^= 0xff; }//end ISR int main (void) { PORTB = 0xff; //Pullup DDRB = 0xff; //Ausgang TCCR0 = ((1<<CS00) | (1<<CS01) | (0<<CS02)); /*************************************** Prescaler auf 64 8MHz / 64 = 125KHz 125KHZ / 65536Hz = 1,9Hz (65536 weil 16Bit Timer verwendet wird ***************************************/ TIMSK = (1<<TOIE0); /*************************************** Interrupts aktivieren und damit Timer starten Sobald nun ein Overflow auftritt wird ein der Interrupt ausgelöst! ***************************************/ sei(); /************************************** (sei=SET ENABLE INTERRUPT) **************************************/ while(1) /************************************** {} Endloschleife **************************************/ }//end main Ist an dem Code was falsch? Danke Thorsten
ISR( TIMER1_OVF_vect ) { PORTB ^= 0xff; }//end ISR ISR( TIMER1_OVF_vect ) { PORTB = 0xff; }//end ISR Die LED's beim STK500 sind low aktiv. D.h. PORTB = 0x00; Dann leuchten sie. Du must die LED nicht nur einschalten, sondern auch wieder ausmachen.
Du verwendet die ISR vom Timer1, hast aber den Timer0-Interrupt aktiviert und konfiguriert!
@Pointer, ...diese Aussage hab ich im Forum entdeckt.... ************************************************************** PORTC ^= 0xff; Da schalte ich einfach den Ausgang vom PORTC um. Wenn an einem Pin bisher eine 0 war, dann wird eine 1 daraus und umgekehrt. Eine angeschlossene LED wird also entweder ein oder aus geschaltet, bei jedem Aufruf des Interrupts.... ************************************************************** Somit hätte sich nämlich mein wiedereinschalten der LED´s erledigt....
@ Sehrwitzig stimmt, hab ich komplett übersehn.... Hab meinen Code nun abgeändert: . . . TCCR0 = ((1<<CS10) | (1<<CS11) | (0<<CS12)); TIMSK = (1<<TOIE1); . . . Funzt leider immer noch nicht :-(
So funktionierts bei mir. /**************************************** T I M E R T E S T P R O G R A M M ****************************************/ #include <avr/io.h> #include <avr/interrupt.h> ISR( TIMER1_OVF_vect ) { PORTB ^= 0xff; }//end ISR int main (void) { PORTB = 0xff; //Pullup DDRB = 0xff; //Ausgang TCCR1B = ((1<<CS10) | (1<<CS11)); //| (0<<CS12)); /*************************************** Prescaler auf 64 8MHz / 64 = 125KHz 125KHZ / 65536Hz = 1,9Hz (65536 weil 16Bit Timer verwendet wird ***************************************/ TIMSK = (1<<TOIE1); /*************************************** Interrupts aktivieren und damit Timer starten Sobald nun ein Overflow auftritt wird ein der Interrupt ausgelöst! ***************************************/ sei(); /************************************** (sei=SET ENABLE INTERRUPT) **************************************/ while(1) // ************************************** {} // Endloschleife // ************************************** }//end main
...hmmm mit ATMEGA103... Müsste dann doch theoretisch auch mit ATMEGA32 funktionieren, oder?!? Also im Datenblatt hab ich nachgeschaut der TIMER1 ist jedenfalls ein 16Bit Timer, so dass meine Berechnung eigentlich auch passen müsste...
Prima, bei mir leuchtets nur, ohne blinken... Schön dass mein Programm funktioniert, blöd nur dass es bei mir nicht tut :-(((
TCCR1B = ((1<<CS10) | (1<<CS11)); Alle drei bits setzen wie bei dir geht nicht. Diese Kombination gibt es laut Datenblatt nicht. Also Teiler /64.
Berichtigung: Gibt es doch, aber dann: External clock source on T1 pin. Clock on rising edge
ja klar, aber den verwende ich ja nicht, hab den internen 8MHz Clock in Betrieb....
Schau dir den geänderten Code von mir genau an. Damit blinkts. Takt -> 4MHz
Bei deinem Code hast Du die Klammern in der While-Schleife noch auskommentiert. /**************************************** T I M E R T E S T P R O G R A M M ****************************************/ #include <avr/io.h> #include <avr/interrupt.h> ISR( TIMER1_OVF_vect ) { PORTB ^= 0xff; } //end ISR int main (void) { PORTB = 0xff; //Pullup DDRB = 0xff; //Ausgang TCCR1B = ((1<<CS10) | (1<<CS11)); /*************************************** Prescaler auf 64 8MHz / 64 = 125KHz 125KHZ / 65536Hz = 1,9Hz (65536 weil 16Bit Timer verwendet wird ***************************************/ TIMSK = (1<<TOIE1); /*************************************** Interrupts aktivieren und damit Timer starten Sobald nun ein Overflow auftritt wird ein der Interrupt ausgelöst! ***************************************/ sei(); /************************************** (sei=SET ENABLE INTERRUPT) **************************************/ while(1) // ************************************** {} // Endloschleife // ************************************** }//end main
So jetzt gehts in den Osterurlaub, vorher noch einkaufen.(seufts) Tschüs und schöne Ostern.
...ich habe mir das von dier geänderte Programm kopiert. Ich mein, egal ob ich jetzt mit 8MHz oder mit 4MHz fahre, meine Blinkzeit würde so nur von 1,9 Hz auf 0,95 Hz reduziert werden, was fürs menschliche Auge aber beides deutlich sichtbar machen müsste. Bin so langsam echt am verzweifeln, sitz nämlich bereits den ganzen Tag an dem Bullshit....
...Also, dann wünsch ich dir nen schönen Urlaub und besten Dank, mög der Osterhase dich reich beschenken :)) Thorsten
@ Thorsten: mal ganz dumm gefragt: hast du den PORTB mit den LEDs auf dem STK500 auch richtig verbunden? Alle Jumper richtig gesetzt? Normalerweise sollte das Teil laufen!
ALso mein STK500 ist eigentlich defekt. Die Programmierung über STK500 funktioniert nicht mehr. Da ich aber von meinem Lehrer ein JTAGICE MK2 ausgeliehen hab, und den entsprechenden Adapter dazu naturlich auch, programmier ich nun über diesen. Somit heist dass doch für mich dass die Jumper etc. auf dem Board relativ egal sind und ich nur meinen PORTB mit den LEDßs verbinden muss, dass hab ich getan....
Anhang: wenn ich zudem meinem PORTB gleich unter "int main (void)" an Stelle von 0xff die 0x00 zuweise leuchten alle LED´s...
Also scheint der PORTB zu funktionieren, aber der Timer läuft nicht. Probier mal testweise den globalen INT mit SREG |= (1<<SREG_I); freizugeben.
...das versteh ich jetzt nicht, wie soll ich dadurch meinen Timer starten?
Hab' grade gesucht welche lib man für das sei(); einbinden muss, hab's leider nicht mehr gefunden. Kann sein dass du das noch machen musst. Das 'I'-Bit im SREG ist der globale Interrupt, ohne den kann der TOIE1 nicht ausgeführt werden. Das ist sozusagen die 'Freigabe' für alle Interrupts. Ich habe mich ein bischen falsch ausgedrückt: der Timer läuft schon, aber der INT wird nicht ausgeführt. Die Variante SREG |= (1<<SREG_I); funktioniert auch ohne lib. Einfach mal testen.
Alles klar, werde ich morgen gleich mal testen, muss jetzt leider auf nen Geburtstag. Denke aber dass mir nach dem fünften Bier bestimmt ne Lösung einfällt :-)) Schönen Abend noch und nochmals Vielen Dank für die Unterstützung Thorsten
POste noch mal dein komplettes Programm. Mal sehen ob der immer noch drinnen ist: > Hab meinen Code nun abgeändert: > > . > . > . > TCCR0 = ((1<<CS10) | (1<<CS11) | (0<<CS12)); > TIMSK = (1<<TOIE1); > . Du konfigurierst immer noch den Timer 0. Die CS kannst du abändern solange du willst, aber TCCR0 gehört zweifellos zum Timer 0.
> Hab' grade gesucht welche lib man für das sei(); einbinden muss, hab's > leider nicht mehr gefunden. Kann sein dass du das noch machen musst. Das steht in der <avr/interrupt.h>...
> Die Variante SREG |= (1<<SREG_I); funktioniert auch ohne lib. Einfach > mal testen. Sollte man aber nicht benutzen, weil der Zugriff damit nicht atomar ist. Da die interrupt.h sowieso eingebunden ist, muss auch sei() funktionieren.
So, nun endlich wieder Feierabend :-) @ Karl heinz Buchegger Ich hatte da oben nen Schreibfehler drin, hab natürlich mit TCCR1B meinen Timer1 konfiguriert. Hab mir für mein Problemchen allerdings nun was überlegt, was in etwa so funktionieren soll: Ich erzeuge mit einem NE555 einen 1Hz-Takt, welchen ich dann ungefähr so verarbeite: if (Px=0) set Flag if ((Px=1)&&(Flag=1)) { inc counter; clear Falg; } Dass der Code so natürlich noch nicht brauchbar ist weis ich, aber in etwa müsste dass soch so gehen. Der Vorteil dabei ist, dass ich mit nem NE555 nen genauen 1Hz Takt hinbekomme und dies dann auch einen relativ vernüftige Zeitbasis darstellt... greez Thorsten
@ Thorsten >Ich erzeuge mit einem NE555 einen 1Hz-Takt, welchen ich dann ungefähr so >verarbeite: ??? Wozu brauchst du den NE555 wenn du einen uC hast? Der kann den 1 Hz takt LOCKER erzeugen. >Der Vorteil dabei ist, dass ich mit nem NE555 nen genauen 1Hz Takt >hinbekomme und dies dann auch einen relativ vernüftige Zeitbasis >darstellt... ??? Du solltest dich DRINGEND mal über die Genauigkiten von NE555 und einem uC mit Quarz informieren. MfG Falk
@Thorsten Bekommst Du beim Compilieren irgendwelche Warnungen angezeigt? Der Code oben von Pointer ist O.K. Damit sollte jeder AVR arbeiten.
ja, ich bekommen zwei Warnungen: ../Timer.c:10: warning: return type defaults 'init' in function ISR ../Timer.c:12: warning: control reaches end of non-void function Thorsten
Das beweist wieder: Warnungen zur Compilerzeit werden zu Fehler in der Laufzeit!
...das ist aber schwul. Die erste Wrnung hab ichmit nem return 0; wegbekommen, die zweite ist dann wohl dass was mir das Problem bereitet.... Naja, dann werde ich eben die NE555 Variante versuchen. Besten Dank! Thorsten
...alles klar, werde ich bei Geldenheit machen. Besten Dank für die Info Thorsten
> > Naja, dann werde ich eben die NE555 Variante versuchen. > Oh, Mann. In der Zeit in der du den NE555 auf 1 sek konfigurierst, hast du deine Software upgedated und den Timer am laufen.
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.