mikrocontroller.net

Forum: Compiler & IDEs Timer_Anfängerproblem


Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sehrwitzig ⌂⌂ (sehrwitzig)
Datum:

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-(

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit ATmega 103

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...


Autor: Pointer (Gast)
Datum:

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Prima, bei mir leuchtets nur, ohne blinken...

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

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Berichtigung:
Gibt es doch, aber dann:

External clock source on T1 pin. Clock on rising edge

Autor: Thorsten (Gast)
Datum:

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

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Register heißen beim mega103 und mega32 gleich.

Autor: Pointer (Gast)
Datum:

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

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Pointer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So jetzt gehts in den Osterurlaub, vorher noch einkaufen.(seufts)

Tschüs und schöne Ostern.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Thorsten (Gast)
Datum:

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

Thorsten

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anhang:

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

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten (Gast)
Datum:

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

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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>...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Erazer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
 @Thorsten

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Erazer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha!!!!!!!!
Das ist es.
Du brauchst eine neue Version der AVR Lib.

Autor: Erazer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit welcher Version Von AVR Studio arbeitest Du?

Autor: Erazer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das beweist wieder:

Warnungen zur Compilerzeit werden zu Fehler in der Laufzeit!

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Erazer (Gast)
Datum:

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...ich habe die Version 4.12 mit dem Servicepack 4....

Autor: Erazer (Gast)
Datum:

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...alles klar, werde ich bei Geldenheit machen.

Besten Dank für die Info

Thorsten

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.