-
        

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 33

Thema: Timer beim ATMega32 in C

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    05.06.2012
    Beiträge
    14

    Timer beim ATMega32 in C

    Anzeige

    Hallo Gemeinde,

    ich habe mich extra hier angemeldet, da mir dieses Form sehr fachlich erscheint und die Leute relativ human miteinander umgehen^^.

    Ich hätte eine Frage zu den Timern - beim ATMega32 sollen es ja drei sein, falls ich richtig gelesen habe. Ich möchte jede Sekunde ein kleines Unterprogramm aufrufen - vereinfacht sagen wir mal ich möchte die Sekunden hochzählen. Getacktet wird mein µC mit 16Mhz (das Funktioniert auch bestens), aber wie genau muss ich die Timer (also den einen) einstellen, dass das Funktioniert und welchen der drei benötige ich überhaupt? Ich habe mich sehr viel eingelesen, verstehe die Technik, jedoch finde ich keinen nützlichen Code in C. Es wäre sehr toll, wenn mir jemand eine Seite nennen könnte, wo ich nicht nur den C-Code, sondern auch eine Erklärung zum Code finden würde - eine eigene Erklärung wäre mir jedoch am liebsten, so dass ich ggf. dazu Fragen stellen kann.

    Was ich bis jetzt verstanden habe:
    - Die Timer verlaufen parallel zum Code und unterbrechen die eigentlich ablaufende Schleife zur eingestellten Zeit, um ein Unterprogramm aufzurufen und kehren nach Abschluss dieses Programmes wirder zum Unterbrechungszustand zurück.
    - Es gibt den sog. Prescaler (Vorteiler), der den Grundtakt - bei mir 16Mhz - aufteilt, um sinnvoll damit umgehen zu können (überlicherweise in Zweierpotenzen)
    - üblicherweise Laufen Timer (falls man diese so einstellt) über und beginnen wieder bei Null, je nach Bitzahl (es gibt beim ATMega32 8- oder 16 Bit Timer) sind dies bei 8 Bit 256 Zählschritte und bei 16 Bit 65536 Zählschritte.

    Bitte korrigiert mich, falls etwas nicht stimmt.

    Wobei ich eure Hilfe benötige (bitte mit Erklärungen):
    1. Wie initialisiere ich einen Timer für die "ein sekunden Zählaufgabe"
    2. Wie rufe ich nach jeder Sekunde mein Unterprogramm auf?
    3. Muss man den Timer stoppen?

    Ich programmiere mit AVR Studio 4 und möchte kein externes Uhrenquarz mehr einbauen (Hardwarebedingt).

    Vielen Dank für die Hilfe.

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    Wilkommen im Forum,
    Grundsätzlich ist es egal welchen Timer du verwendest. Du kannst den Timer aber nur für eine Aufabe verwenden. Wenn du z.B. Timer0 für die PWM Erzeugung nutzt kannst du den Sekundentakt nicht mit dem Timer0 erzeugen. Du nimmst also einfach den ersten Timer den du noch nicht brauchst.

    Wenn eine Funktion hardwaremäßig im Controller ist (Timer, ADC, I2C, SPI, RS232,...) läuft dies unabhängig (wenn richtig konfiguriert) vom Programm. Auf Ereignisse wirst du mit Interrupts aufmerksam gemacht. Wenn z.B. der Timer überläuft wird ein Interrupt ausgelöst.

    Zum Timer: Du nimmst den größtmöglichen Prescaler. Wenn du 16MHz hast, brauchst du einen Prescaler von 1024. Somit erhältst du 16000000Hz / 1024 = 15625Hz. Das ist die Frequenz um die der Zählerwert des Timers um 1 erhöht wird. Bei 8Bit hättest du dann 256 Schritte (0-255) und bei 16Bit hast du 1024 Schritte (0-1023). Wenn du einen 16Bit Timer nimmst erhälts du eine Frequenz von 15625 / 1024 = ca.15,26Hz. Somit erhältst du 15,26 Überläufe/s (f=1/s). Mit der Wahl des richtigen Zählerwertes kannst du auf genau 16 Überläufe kommen. Jetzt musst du nur noch bis 16 Zählen und hast dann 1 Sekunde.

    Vielleicht hilft das weiter http://www.rn-wissen.de/index.php/Timer/Counter_(Avr)

    MfG Hannes

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    05.06.2012
    Beiträge
    14
    danke erst mal für die rasche antwort.

    kann es sein dass dir ein kleiner fehler unterlaufen ist. du schreibst:
    >>Bei 8Bit hättest du dann 256 Schritte (0-255) und bei 16Bit hast du 1024 Schritte (0-1023)<<
    sind es bei 16 bit nicht 0 - 65535?

    ansonsten würde mich genau das mit den interrupts interresieren - könntest du mir bitte ein codebeispiel posten?

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von robo_tom_24
    Registriert seit
    04.02.2012
    Ort
    Burgenland, Österreich
    Beiträge
    485
    Ja, bei 16bit sinds 65535 Schritte -> ~0.2 Hz

    Du kannst auch verschiedene Interrupts Auslösen: Überlauf, Timer hat bestimmten Wert
    Und je nachdem wie du das ganze aufbaust kannst du eigentlich jede beliebige Frequenz erzeugen - auch mit einem 8bit Timer
    Ich habs sogar geschafft mit einem 8bit Timer ein Servo anzusteuern, mit unterschiedlichen Prescalern usw - sehr interessant das ganze

    Gute Veranschaulichung der Register: klick

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    05.06.2012
    Beiträge
    14
    hmm.. danke aber ich such immer noch nach c-source-code....

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von robo_tom_24
    Registriert seit
    04.02.2012
    Ort
    Burgenland, Österreich
    Beiträge
    485
    Wie gesagt, schau dir die Tutorials an...
    Es ist besser etwas zu können als den ganzen Code zu kopieren, und so schwer istn nun auch nicht

    Welche Timer hast du schon in Verwendung?
    Bzw. Welche Timer-Pins?

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    05.06.2012
    Beiträge
    14
    benötige ich denn pins um einen timer starten zu können?
    timer im allgemeinen verwende ich noch nicht.

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von robo_tom_24
    Registriert seit
    04.02.2012
    Ort
    Burgenland, Österreich
    Beiträge
    485
    Neee...aber man kann den Timer direkt nach außen legen auf einen Pin...

    Aber ich helf dir mal ein bisschen....
    Du willst:
    Im 1Hz Takt wird eine Variable inkrementiert

    Du brauchst:
    Timer
    Prescaler
    Interrupt
    Interrupt-Routine
    Variable

    Einen fertigen Code wirst du wahrscheinlich nirgends finden - bekommen wirst du von uns auch keinen - nur Denkanstöße

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    05.06.2012
    Beiträge
    14
    hmm.. also wenn ich alles richtig kapiert habe, dann mal eine kleine nachfrage...

    TCCR1B |= (1<<CTC1)| (1<<CS02) | (1<<CS00);
    OCR1C = 15625;
    OCR1A = 0;
    TIMSK |= (1<<OCIE1A);
    wie ich den code verstehe:
    zeile eins ergibt den vorteiler mit wert 1024 (dann wird der interrupt ausgelößt).
    nach dem wert in zeile zwei (15625) wird wider bei null (wegen zeile drei) begonnen.
    zweile vier schaltet den interrupt wieder frei.

    berechnung:
    16Mhz / 1024 = 15625Hz
    1/15625Hz = 0,000064 Sek.

    funktion:
    der timer wir alle 0,000064 Sek. um den wert eins erhöht (+1).
    bei "OCR1C = 15625;" bedeutet das 0,000064 Sek. * 15625 = 1,00 Sek.
    der timer springt ab 15625 auf 0 und dann wird die interrupt routine ausgelößt und so geht es weiter und weiter und weiter....

    liege ich soweit richtig mit meiner interpretation?!
    und wie um gottes willen lege ich jetzt diese interrupt routine an?!

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Also.
    In deiner ersten Zeile stellst Du den Prescaler ein und sagst dem Timer, das das TCNT Register bei einem Comparematch 0 werden soll.
    In der zweiten Zeile gibst Du an, das das Comparematchregister 1C einen Wert von 15625 haben soll.
    In der dritten Zeile weist Du dem OCR1A Register den Wert 0 zu, was aber eigentlich keinen Sinn macht.
    In der vierten Zeile gibst Du den Interrupt bei Comparematch des 1A Comparematch frei.

    Nimm Zeile 2 raus und weise in Zeile 3 dem OCR1A den Wert 15625 zu.

    Das Ganze funktioniert nun so 16MHz/1024/15625 = 1Hz. Das passt dann schon mal.

    Das anlegen eines Interrupts ist von deinem Compiler abhängig.
    Soweit ich weiß muss man bei AVR GCC die interrupt.h Library includen #include <avr/interrupt.h> und kann dann mit der Funktion.
    ISR (Vektorname)
    {
    }

    Nach der Initialisierung und vor der Hauptschleife deines Programmes musst Du mit sei(); noch global die Interrupts frei geben.
    Sonst wird niemals ein Interrupt ausgeführt.

    Den Funktionsaufruf der Interruptroutine starten.
    Da gibts aber so viele Tutorials dafür, guck da einfach mal nach.

    In diesem Interrupt würde ich nur ein Flag setzen ( Bit Variable ) und im Hauptprogramm dieses Flag wieder löschen, sobald es verarbeiet wurde.
    Dadurch bleibt die Interruptroutine sehr kurz, was ja auch erwünscht ist.

Seite 1 von 4 123 ... LetzteLetzte

Ähnliche Themen

  1. Timer beim atmega8
    Von MrTaco im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 19.05.2010, 15:28
  2. ausschaltverzögerung beim einschalten (timer)
    Von Warloxx im Forum Elektronik
    Antworten: 7
    Letzter Beitrag: 03.09.2009, 19:55
  3. Timer => Fehlermeldungen beim compilieren
    Von The Man im Forum Assembler-Programmierung
    Antworten: 5
    Letzter Beitrag: 14.02.2007, 11:07
  4. Timer/Counter0 beim Butterfly
    Von Heiko R. im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 09.11.2005, 18:55
  5. Timer beim Mega16
    Von maw_hn im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 22.08.2005, 10:03

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •