PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer >>> CPU-Takt



frabe
07.06.2019, 11:34
Hallo zusammen.
Befasse mich neuerdings mit dem Thema Timer und Interrupt.

Schon bei dem CPU-Takt für den Timer1 komme ich ins schleudern.
Der ATtiny84 taktet intern mit 8MHz (CKSEL2=1). Nun stelle ich die CPU gerne auf 1MHz;
#define F_CPU 1000000UL

Wird der Timer nun 1MHz verwenden?

Ceos
07.06.2019, 12:13
#define F_CPU 1000000UL
das makro wird intern benutzt um zeiten die du in sekunden oder millisekunden angibst in takte, schleifen und timerwerte umzurechnen und muss immer exakt dem entsprechen was du in den fuses konfigurierst, sonst stimmt keine delay und auch kein timer (falls du irgendwelche libs verwendest)

richtig wäre

#define F_CPU 8000000UL

um den timer jetzt nur mit 1mhz takten zu lassen müsstest du den prescaler in dem passenden timer control register auf 8 setzen

das makro hat jedenfalls ncihts direkt mit irgendwelchen timern zu tun sondern dient einzig als grundlage zur umrechnung von zeit im bezug auf deine CPU clock

frabe
07.06.2019, 12:25
richtig wäre
#define F_CPU 8000000UL


Mir geht es bei einer niedrigen F_CPU um Energieschohnung, da ich überhaupt keine HF-Anwendungen habe.
Mit dem Timer/Presacling gehe ich auf einen 1ms-Interrupt.

Warum macht es dennoch Sinn die CPU auf 8MHz laufe zu lassen?

021aet04
07.06.2019, 12:54
Wenn du in den Fuses den internen Takt mit Teilung 8 (Werkseinstellung) verwendest du effektiv 1MHz, dadurch musst du auch beim F_Cpu 1MHz einstellen.
Wenn du die Teilung 8 entfernst, läuft der uC mit 8MHz und dann musst du bei F_Cpu 8MHz einstellen.
Wenn du einen Quarz, externen Takt,... verwendest, muss du bei F_Cpu die Taktfrequenz der Quelle einstellen.

F_Cpu wird nur für interne Berechnungen verwendet, das wurde aber schon gesagt.

MfG Hannes

Ceos
07.06.2019, 13:13
Teilung 8 (Werkseinstellung)

Sorry das habe ich total vergessen :D

Um noch mehr Strom zu sparen könntest du auch den 128kHz Watchdog Oszillator nehmen, wenn das ausreicht?

(Bedenke dass du evtl. die ISP Frequenz deutlich senken musst um noch mit dem Chip zu reden, bin mir nicht sicher ob der im ISP Modus auch bei 128kHz taktet oder weieder auf den internen OSC zurückschaltet)

frabe
07.06.2019, 16:25
Danke für deine Tips!

CPU-Einstellung habe ich unter FUSES gerade nicht gefunden - wird Werksseitig auf 8MHz stehen - macht wohl auch kein Sinn uC auf 1MHz runter zu takten...
Werde mich nächste Wo weiter damit beschäfigen.

oberallgeier
07.06.2019, 17:26
.. Schon bei dem CPU-Takt für den Timer1 komme ich ins schleudern. Der ATtiny84 taktet intern mit 8MHz (CKSEL2=1). Nun stelle ich die CPU gerne auf 1MHz; #define F_CPU 1000000UL ..Hallo frabe.

Ceos und Hannes (021aet04) haben ja schon hingewiesen dass durch die Fuses unter anderem die Taktquelle des Controllers bestimmt wird und auch die Einstellung der internen Taktquelle. Zu den Fuses gibts Gehirnnahrung noch im RN-Wissen hier (klick (https://rn-wissen.de/wiki/index.php?title=Avr#Die_Fusebits)) und als Hilfe auch nen Fuse-Calculator (nochKlick (http://www.engbedded.com/fusecalc/)). Die Fuses sind also Einstellungen des Controllers die üblicherweise über das Programmiergerät zugänglich sind, die aber nichts mit der eigentlichen Programmierung in Form des Maschinencodes zu tun haben (es gibt Ausnahmen). Damit das Programm aber richtig laufen kann, muss der Programmcode die vom Benutzer gewählte Einstellung enthalten.

Das Datenblatt zum tiny84 (meins ist 8006K–AVR–10/10) schreibt dazu
..
6.2.2 Calibrated Internal 8 MHz Oscillator
.. The device is shipped with the CKDIV8 Fuse programmed ..und weiter
..
6.2.6 Default Clock Source
.. resulting in 1.0 MHz system clock ..
Mir geht es bei einer niedrigen F_CPU um Energieschohnung .. Warum macht es dennoch Sinn die CPU auf 8MHz laufe zu lassen? ..Es macht dann keinen Sinn die CPU auf 8 MHz laufen zu lassen. Und auch darauf gibts mehrere Hinweise im >>ganzen<< Datenblatt unter dem Stichwort "low power". Und schon auf Seite 1 des Datenblattes steht:
......• Low Power Consumption
..........– Active Mode (1 MHz System Clock): 300 μA @ 1.8V

Das ist nur der Hinweis des Herstellers auf den niedrigen Verbrauch bei 1 MHz und geringer Versorgungsspannung - das ist keine Vorschrift. Man kann durch den niedrig taktenden internen 128kHz-Oszillator vermutlich noch niedrigere Verbräuche erzielen (dazu habe ich keine Erfahrungen). Möglicherweise kann man mit noch niedrigerem Takt, z.B. nem Uhrenoszillator mit 32.768 kHz im Stromverbrauch noch weiter runterkommen. Ausführliches dazu wieder im Datenblatt ab S25, 6.2 Clock Sources. Also - niedriger Stromverbrauch ist duch vielerlei Einstellungen möglich - wie immer die lästige, mühselige Wahl des Anwenders.

Hoffe das hilft Dir auch weiter.

frabe
11.06.2019, 12:52
@oberallgeier, erst einmal VIELEN DANK für deine Ausführungen.
uC wird bei mir mit 5VDC betrieben.
Brauchte bis lang noch keine genauen Timer mit Interrupt - meine schwarzern Flecken - aber unendlich wichtig!

frabe
11.06.2019, 15:05
Hier kann ich nur eine 8MHz anwähler;
34211
Einen 8fach (Vor-)teiler habe ich leider auch nicht gefunden;
34213

Wo "verstecken" sich die Parameter zur CPU-f Einstellung?

Ceos
11.06.2019, 15:09
F_CPU wird nicht dort festgelegt sondern als precompiler konstante oder per define im code

im 2ten Bild LOW.CKDIV8 ist AN, das heißt deine CPU taktet mit OSC/8 = 1 Mhz, da OSC 8Mhz ist

Um mal ins Detail zu gehen, im Code für die Atmel Treiber und internen Funktion (von delay.h) zum Beispiel werden Formel benutzt um die Anzahl an Takte Vs Frequenz zu errechnen um korrekt und deterministisch arbeiten zu können, damit delay_ms(1000) auch genau eine Sekunde dauert.

Die Formel verwendet dann den "Platzhalter" F_CPU wo eigentlich eine Frequenz stehen müsste, also quasi so etwas wie eine Variable!
Es ist aber keine Variable sondern eneben nur ein Platzhalter.
Beim compilen geht der Preprozessor/Precompiler einmal über den Code, sammelt alle #defines und andere precompiler Schlüsselwörter ein und bildet sich so eine Art Notizzettel welcher Code eingeblendet und ausgeblendet wird und welche Platzhalter mit welchem Inhalt überschrieben werden ("Suchen und ersetzen" wenn man es so nennen will)

Nach diesem Schritt sollte sich dein Code so lesen als hättest du überall die F_CPU Frequenz von Hand eingetragen und dieser wird dann am Ende fertig compiliert.

frabe
12.06.2019, 13:31
im 2ten Bild LOW.CKDIV8 ist AN, das heißt deine CPU taktet mit OSC/8 = 1 Mhz, da OSC 8Mhz ist
Bei LOW.CKDIV8 war ich mir unsicher - daher hier Dank für die Bestätigung!

Die Formel verwendet dann den "Platzhalter" F_CPU wo eigentlich eine Frequenz stehen müsste
Aber auch der 2ten Teil deiner Ausführung war in mir ein Wissens-Wackelkandidat, da in div. Fachliteraturen bei einigen Prog F_CPU eingetragen wurde und bei anderen nicht.
Nun hat sich FÄLSCHLICHER WEISE in meinem Kopf Gedanke fest gesetzt, dass die Fuse-Prozessor-Geschweindgkeit nur dann greift, wenn KEIN F_CPU im Prog.code steht.
Dank dir auch hier für deine tolle und einfache Ausführung!!!

Abschließend zu meinem Verständnis: Sollte in Fuse und F_CPU unterschiedliche Frequenzen eingetragen sein, meckert der Compiler nicht, funktioniert auch das Programm im Ablauf, aber berechnete Zeiten werden falsch interpretiert/umbesetzt.

Ceos
12.06.2019, 13:34
Der Compiler kennt nur die Infos die du ihm gibst und das ist bestenfalls das F_CPU Makro, die fuses kann dein compiler nicht wissen, das ist eine andere Baustelle :)

und wenn du falsche Zeiten gibst rennt deine sleep_ms(1000) eben in 1/8tel Sekunden durch statt einer ganzen Sekunde wenn das CKDIV8 nicht an ist