www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anfängerfrage mit Timern


Autor: RambusZambus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo! Stehe mit Timern noch ein wenig auf Kriegsfuß. Angenommen, mein
Takt ist 3686000 Hz und ich benutze einen Prescaler von 64.

Daraus folgt: Dieser Takt wäre dann nur noch 3686000/64 = 57593,75 Hz

Aber wenn ich z.B. jede halbe Sekunde, also mit 2 Hz eine Aktion
auslösen will, wie mach ich das? Dachte an 57593.75/(57593.75/2)=2

Oder ist das so falsch wie ich da herangehe?

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
0,5s*57596,75Hz ist der Wert, bei dem der Timer ein Interrupts uaslösen
soll. Entweder 65536-diesem Wert für ein Overflow-Interrupt oder diesen
Wert in OCR im CTC-Modus schreiben.

Autor: RambusZambus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber im 8 Bit-Modus muss das ja auch gehen? CTC usw. gibts ja nur für
16-Bit timer laut Datenblatt.

Habe nun mal TIMSK mit TOIE0 genommen. Aber wo schreibe ich den Wert
dann überhaupt rein? Das fehlt und ich hab keine Ahnung wo das hin
soll?

Und wie ist Überlauf des Datenregisters gemeint? Wenn er über 255
kommt? oder muss ich ihm meinen Wert übergeben? Stehe da momentan echt
auf dem schlauch, verzeihung :(.

Hier mal der ganze code
int main(void)
{

DDRD = 0xFF;             // kompletter PORTD als Ausgang
PORTD = 0xFF;  

//Timer

TCCR0|= (1<<CS01)|(1<<CS00); //prescaler 64
sei();    //Setzt globales Interupt
TIMSK = (1<<TOIE0);


for(;;) {
  

        SIGNAL(SIG_OVERFLOW0) //Interrupt auslösen
{
        PORTD &= ~((1<<PD0));
}
  
   
     
}
  
  }

Autor: RambusZambus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, hab jetzt doch den 16-Bit-Counter genommen, da gibts einfach mehr
funktionen (auch wenn das doch mit dem 8-Bitter auch gehen müsste)?

Wo ist jetzt noch der Fehler (s.u.), eigentlich müsste doch nach ca.
1,1 Sekunden der Port auf Low gezogen werden? Laut Tutorial passt das
so zusammen, wenn ich das so richtig verstanden habe:

Der Timer der mit CPU_CLK/64 läuft, und damit den TCNT1L bis 65535
hochzählt. Wenn er diesen Wert erreicht hat, löst TIMSK = (1<<TOIE1)
nen Timer1 Overflow Interrupt aus, der dann von der
ISR(TIMER1_OVF_vect) empfangen wird und dann ein interrupt event
ausgelöst wird (z.B. Port schalten etc).
#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{

DDRD = 0xFF;             // kompletter PORTD als Ausgang
PORTD = 0xFF;  

  
  
//Timer

TCCR1B = (1<<CS11)|(1<<CS10); //prescaler64

TCNT1L; //16-Bit Aufwärtszähler

sei(); //Setzt globales Interupt

TIMSK = (1<<TOIE1); //WENN UEBRLAUF , dann interrupt
  







for(;;) 
  {



  ISR(TIMER1_OVF_vect) 
  
    {      
    PORTD &= ~((1<<PD0));
    }
     
  }
  
}

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher der 10000 am Markt befindlichen Controller spielt denn hier?

Das ganze ist doch sehr hardwareabhängig, um einen Zusammenhang zu
bekommen, oder?

Gruß

Dietmar

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher Takt ist 3686000 Hz? Quarz???

Grundsätzlich geht das etwa so:

Timer Reload Wert = (Taktfrequenz / Prescaler) * Überlaufzeit in
Sekunden

Konkret für 1/2 Sekunde:

Timer Reload Wert = (3686000 / 64) * 0,5

Timer Reload Wert = 57593,75 * 0,5

Timer Reload Wert = 28796,875

runden:

Timer Reload Wert = 28797

Gruß

Dietmar

Autor: RambusZambus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Controller ist ein AT90s85815, der Quarz läuft mit 3686000 (SK500).

Okay, nun weiss ich wie man das macht. Aber wo der Fehler oben im
zweiten Code steckt, da rätsele ich immer noch herum (da hab ich
wiegesagt ohne Vergleichswert gearbeitet, der EInfachheit halber nur
einen Überlauf.

Danke

Gruß,

RZ

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

Bewertung
0 lesenswert
nicht lesenswert
> Aber wo der Fehler oben im
> zweiten Code steckt, da rätsele ich immer noch herum

Das faengt schon mal damit an, dass man in C innerhalb
einer Funktion keine weitere Funktion definieren kann.
Genau das versuchst Du aber mit Deinen ISR Funktionen.

Autor: RambusZambus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aah, danke das wars. Jetzt steht die ISR außerhalb der main-Funktion und
erhöht eine Zählvariable. Nun klappt es superb =).

Danke!

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.