Forum: Compiler & IDEs Timer_Anfängerproblem


von Thorsten (Gast)


Lesenswert?

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

von Pointer (Gast)


Lesenswert?

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.

von Sehrwitzig ⌂. (sehrwitzig)


Lesenswert?

Du verwendet die ISR vom Timer1, hast aber den Timer0-Interrupt 
aktiviert und konfiguriert!

von Thorsten (Gast)


Lesenswert?

@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....

von Thorsten (Gast)


Lesenswert?

@ 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 :-(

von Pointer (Gast)


Lesenswert?

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

von Pointer (Gast)


Lesenswert?

Mit ATmega 103

von Thorsten (Gast)


Lesenswert?

...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...


von Pointer (Gast)


Lesenswert?

Ja eben.
Nachfolger vom 103 ist glaube ich der Mega128
Es blinkt schön.

von Thorsten (Gast)


Lesenswert?

Prima, bei mir leuchtets nur, ohne blinken...

Schön dass mein Programm funktioniert, blöd nur dass es bei mir nicht 
tut :-(((

von Pointer (Gast)


Lesenswert?

TCCR1B = ((1<<CS10) | (1<<CS11));
Alle drei bits setzen wie bei dir geht nicht. Diese Kombination gibt es 
laut Datenblatt nicht.
Also Teiler /64.

von Pointer (Gast)


Lesenswert?

Berichtigung:
Gibt es doch, aber dann:

External clock source on T1 pin. Clock on rising edge

von Thorsten (Gast)


Lesenswert?

ja klar, aber den verwende ich ja nicht, hab den internen 8MHz Clock in 
Betrieb....

von Pointer (Gast)


Lesenswert?

Die Register heißen beim mega103 und mega32 gleich.

von Pointer (Gast)


Lesenswert?

Schau dir den geänderten Code von mir genau an.
Damit blinkts.
Takt -> 4MHz

von Pointer (Gast)


Lesenswert?

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

von Pointer (Gast)


Lesenswert?

So jetzt gehts in den Osterurlaub, vorher noch einkaufen.(seufts)

Tschüs und schöne Ostern.

von Thorsten (Gast)


Lesenswert?

...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....

von Thorsten (Gast)


Lesenswert?

...Also, dann wünsch ich dir nen schönen Urlaub und besten Dank, mög der 
Osterhase dich reich beschenken :))

Thorsten

von Sonic (Gast)


Lesenswert?

@  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!

von Thorsten (Gast)


Lesenswert?

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....

von Thorsten (Gast)


Lesenswert?

Anhang:

wenn ich zudem meinem PORTB gleich unter "int main (void)" an Stelle von 
0xff die 0x00 zuweise leuchten alle LED´s...

von Sonic (Gast)


Lesenswert?

Also scheint der PORTB zu funktionieren, aber der Timer läuft nicht.
Probier mal testweise den globalen INT mit
SREG |= (1<<SREG_I);
freizugeben.

von Thorsten (Gast)


Lesenswert?

...das versteh ich jetzt nicht, wie soll ich dadurch meinen Timer 
starten?

von Sonic (Gast)


Lesenswert?

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.

von Thorsten (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von johnny.m (Gast)


Lesenswert?

> 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>...

von johnny.m (Gast)


Lesenswert?

> 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.

von Thorsten (Gast)


Lesenswert?

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

von Falk (Gast)


Lesenswert?

@ 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

von Erazer (Gast)


Lesenswert?

 @Thorsten

Bekommst Du beim Compilieren irgendwelche Warnungen angezeigt?
Der Code oben von Pointer ist O.K.
Damit sollte jeder AVR arbeiten.

von Thorsten (Gast)


Lesenswert?

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

von Erazer (Gast)


Lesenswert?

Aha!!!!!!!!
Das ist es.
Du brauchst eine neue Version der AVR Lib.

von Erazer (Gast)


Lesenswert?

Mit welcher Version Von AVR Studio arbeitest Du?

von Erazer (Gast)


Lesenswert?

Das beweist wieder:

Warnungen zur Compilerzeit werden zu Fehler in der Laufzeit!

von Thorsten (Gast)


Lesenswert?

...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

von Erazer (Gast)


Lesenswert?

Du hast aber noch nicht auf die Frage geantwortet:
Mit welcher Version Von AVR Studio arbeitest Du?

von Thorsten (Gast)


Lesenswert?

...ich habe die Version 4.12 mit dem Servicepack 4....

von Erazer (Gast)


Lesenswert?

Upgrade auf Version 4.13 und WinAVR 4.1.1 (wichtig).
Dann sollte das Problem aus der Welt sein.

von Thorsten (Gast)


Lesenswert?

...alles klar, werde ich bei Geldenheit machen.

Besten Dank für die Info

Thorsten

von Karl H. (kbuchegg)


Lesenswert?

>
> 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
Noch kein Account? Hier anmelden.