8Bit Timer keine genaue Sekunde?

Gast #483576
Lesenswert?

Hallo zusammen,

laut Artikel:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr

lässt sich bei 4 Mhz keine exakte Sekunde per Overflow auf Timer0 8bit 
realisieren.

Aber laut:
https://mpg.dnsalias.com/~magerlu/rn-wiki/avrtimer_applet/

muss es gehen:

4 Mhz
Prescaler: 128
Timervorladen: 131

kommt genau 250 Overflows in einer Sekunde.

Was ist an meiner Rechnung falsch? Ich muss dann nur noch eine Variable 
bis 250 hochzählen und schon habe ich eine Sekunde.
Gast #483605
Lesenswert?

> Was ist an meiner Rechnung falsch?
In Deiner Rechnung fehlt die Zeit, die das Programm bei jedem Overflow 
braucht, um den Timer mit dem Startwert nachzuladen. Und bei 250 
Overflows pro Sekunde kann da auf Dauer schon eine ganz schöne 
Abweichung entstehen. Bei einigen 8051er-Controllern gibt es die 
Möglichkeit, dieses Nachladen verzögerungsfrei per Hardware zu machen. 
Bei den AVRs gibt es das nicht, es ist allerdings auch nicht 
erforderlich, da man ja CTC zur Verfügung hat. Und CTC macht im Prinzip 
dasselbe, nur umgekehrt... Man kann das natürlich (mit Overflow und 
Nachladen) in Assembler programmieren. Da weiß man genau, wie viele 
Takte es dauert, um den Timer nachzuladen und man kann diese Zeit dann 
zum Reload-Wert hinzuaddieren und damit kompensieren. Aber warum so viel 
Aufwand bei der Software, wenn der Controller das alles hardwaremäßig 
machen kann?
Gast #483606
Lesenswert?

>In Deiner Rechnung fehlt die Zeit, die das Programm bei jedem Overflow
>braucht, um den Timer mit dem Startwert nachzuladen.

Naja, bei einem Vorteiler von 128 wären 128 Takte bis zum nächsten 
Erhöhen des TCNT-Registers nötig.
Das sollte man hinkriegen...
Gast #483628
Lesenswert?

Ich habe eben im Datenblatt nachgelesen das der 8bit Timer vom 
ATTINY2313 auch Clear Timer on Compare Match (Auto Reload) machen kann.

Wie sieht der Code aus um in zu aktivieren? Von dem C-Tutorial wird man 
nicht schlauer weil die Register bei dem AVR anders sind.

Kann mir da einer helfen?
Gast #483630
Lesenswert?

> Hoffen wir das beste lieber Leser für unseren Titelhelden - Forts folgt
> das ist pluralis maiestatis, Wir dero Gnaden verfügen...

Mich stört es nicht, wenn ein Tutorial im Stil des gemeinsamen Handelns 
abgefasst ist. Ich bin ehrlich gesagt nie auf die Idee gekommen, das als 
"pluralis maiestatis" des Autors zu interpretieren und halte das jetzt 
auch für fehlinterpretiert. Sind "wir" lieber froh, dass es in der 
Artikelsammlung voran geht. Dran denken: Wer selber schreibt, darf 
selber bestimmen.
Gast #483667
Lesenswert?

>Sind "wir" lieber froh, dass es in der Artikelsammlung voran geht.

Ja, dagegen spricht ja auch nichts.
Ich bin halt gewöhnt, dass irgendwelche technischen Abhandlungen 
"unpersönlich" geschrieben sind.
#483715
Lesenswert?

Rahul, der Trollige wrote:
> Wer hat eigentlich diesen Wiki-Artikel geschrieben? Der klingt wie "So,
> jetzt machen wir den Mund schön weit auf"... (Ihn zu ändern habe ich
> aber keine Lust...)

Du kannst ihn gerne umschreiben. :-)

Ein Artikel über den ADC wäre da drinnen auch nicht schlecht.
Oder eine PWM
Oder wie man das Timing für ein Servo hinkriegt.
All die Fragen, die hier im Forum tagtäglich anfallen.

Ich wär überaus dankbar wenn mir jemand helfen würde, das
Tutorial weiter voranzutreiben. (So jetzt ist die Katze
aus dem Sack. Der Artikel, und ein paar Ergänzungen im LCD Teil
sind von mir)
Als nächstes möchte ich mir entweder einen kleinen Frequenz-
generator oder 'LED dimmen per WPM' vornehmen. Mal sehen ob
ich am Wochenende dazu komme.

Im Ernst. Dieses 'Wir haben ..' etc. stört mich selbst. Allerdings
muss man einmal in diesem winzigen Editorfenster einen Artikel
eintippen. Da siehst mann nämlich gar nichts. Und hinterher  ...
na ja, es war schon spät.
Moderator Persönliche Seite #483727
Lesenswert?

Karl heinz Buchegger wrote:

> Im Ernst. Dieses 'Wir haben ..' etc. stört mich selbst. Allerdings
> muss man einmal in diesem winzigen Editorfenster einen Artikel
> eintippen. Da siehst mann nämlich gar nichts. Und hinterher  ...
> na ja, es war schon spät.

Ich nehme den Mozilla mit dem mozex-Plugin.  Da kann man an die
Textfelder einen Editor seiner Wahl dranklemmen.
Gast #483728
Lesenswert?

>So jetzt ist die Katze aus dem Sack.

"Tach Herr Doktor!"

>Ich wär überaus dankbar wenn mir jemand helfen würde
Kann ich verstehen. Ich wäre aber vermutlich zu patzig...(mal schaun).
#483730
Lesenswert?

Rahul, der Trollige wrote:
>>In Deiner Rechnung fehlt die Zeit, die das Programm bei jedem Overflow
>>braucht, um den Timer mit dem Startwert nachzuladen.
>
> Naja, bei einem Vorteiler von 128 wären 128 Takte bis zum nächsten
> Erhöhen des TCNT-Registers nötig.
> Das sollte man hinkriegen...

Wie ist das eigentlich:
Wenn ich den Timer vorlade, wird dann die interne Prescaler-
Teiler-Kette ebenfalls auf 0 gesetzt?
Gast #483733
Lesenswert?

>wird dann die interne Prescaler-Teiler-Kette ebenfalls auf 0 gesetzt?

Nein, warum auch? Es sind ja zwei verschiedene Register.
Wenn man CSx = 0 setzt, bleibt der TCNT-Inhalt ja auch erhalten.

>Naja, bei einem Vorteiler von 128 ...
Der ist aber eher selten einstellbar...

>Ich nehme den Mozilla mit dem mozex-Plugin.  Da kann man an die
>Textfelder einen Editor seiner Wahl dranklemmen.

Kann man nicht einfach einen Text-Editor (z.B. PN2) seiner Wahl nehmen 
und dann per Copynpaste die Sachen rüberkopieren? (Ich habe mich bisher 
nur "konsumierend" mit Wikis beschäftigt...)
#483734
Lesenswert?

Rahul, der Trollige wrote:
>>wird dann die interne Prescaler-Teiler-Kette ebenfalls auf 0 gesetzt?
>
> Nein, warum auch? Es sind ja zwei verschiedene Register.
> Wenn man CSx = 0 setzt, bleibt der TCNT-Inhalt ja auch erhalten.

Das dachte ich mir.
Dann hat man immer noch dasselbe Problem (nur etwas kleiner).
Sobald der Vorteiler nicht 1 ist, kann man nicht taktgenau
nach x Zyklen eine Aktion ausführen lassen.
Moderator Persönliche Seite #483746
Lesenswert?

Karl heinz Buchegger wrote:

>>>wird dann die interne Prescaler-Teiler-Kette ebenfalls auf 0 gesetzt?

>> Nein, warum auch? Es sind ja zwei verschiedene Register.
>> Wenn man CSx = 0 setzt, bleibt der TCNT-Inhalt ja auch erhalten.

> Das dachte ich mir.

Bei neueren AVRs kann man den Vorteiler anhalten und gemeinsam
mit dem Timer starten.

> Dann hat man immer noch dasselbe Problem (nur etwas kleiner).
> Sobald der Vorteiler nicht 1 ist, kann man nicht taktgenau
> nach x Zyklen eine Aktion ausführen lassen.

Über CTC-Mode, ggf. halt mit dem OCx-Ausgang.
#483760
Lesenswert?

Jörg Wunsch wrote:
> Karl heinz Buchegger wrote:
>
>>>>wird dann die interne Prescaler-Teiler-Kette ebenfalls auf 0 gesetzt?
>
>>> Nein, warum auch? Es sind ja zwei verschiedene Register.
>>> Wenn man CSx = 0 setzt, bleibt der TCNT-Inhalt ja auch erhalten.
>
>> Das dachte ich mir.
>
> Bei neueren AVRs kann man den Vorteiler anhalten und gemeinsam
> mit dem Timer starten.
>
>> Dann hat man immer noch dasselbe Problem (nur etwas kleiner).
>> Sobald der Vorteiler nicht 1 ist, kann man nicht taktgenau
>> nach x Zyklen eine Aktion ausführen lassen.
>
> Über CTC-Mode, ggf. halt mit dem OCx-Ausgang.

Ja klar. Das war ja auch der Sinn dieses Uhr-Artikels im
Tutorium. Irgendwie die Kurve vom Overflow zum CTC zu kratzen.
Möglichst so, dass der geneigte Leser was dabei lernt,
dabei irgendwas prakisch Brauchbares rauskommt und
gleichzeitig auch noch die Motivation für einen CTC
rübergebracht wird :-)
Ist gar nicht so einfach, das alles unter einen Hut zu
kriegen. Wenn dann auch noch das Programm nicht allzulang
sein soll ....
Gast #483773
Lesenswert?

> TCCR0A = (1<<WGM01);
> TCCR0B = (1<<CS01); // PS = 8
> OCR0A = 249; // 500ms

Oh 2 Register ... ist das nicht nur bei dem 16-bit Timer so?

OCR0A = 249;  //500ms wie kommst du auf diesen Wert? Kannst du hier mal 
eine Rechnung machen?
z.B. für den Fall das ich genau 1000ms haben will?
Gast #483778
Lesenswert?

Ich finde nichts zu dem Thema.
Meine Vermutung ist, dass der Prescaler wirklich nur durch Verändern der 
CS-Bits zurückgesetzt wird.
Aber das sollte man auch in der ISR machen können...

Anderseits: Wenn CTC möglich ist, braucht man kein manuelles 
Timer-Nachladen (in C sowieso nicht). In Assembler wäre man noch dicht 
genug an der Maschine...
Gast #483784
Lesenswert?

>Kannst du hier mal eine Rechnung machen?
Muß ich?

8/4MHz sind 2µs. 2µs * 250 = 500µs

Mist! Vertippt hat er sich auch noch.

So gerade Taktfrequenzen sind leider nicht "binärsystemkompatibel"...

Ich habe mir für sowas eine (Excel-)Tabelle gebastelt.
Mal sehen, wie die zuhause in OpenOffice.org 2.0 aussieht...
Gast #483787
Lesenswert?

> Ich finde nichts zu dem Thema.
Im Datenblatt (in diesem Fall vom Tiny2313) im Abschnitt "Timer/Counter0 
and Timer/Counter1 Prescalers"...

Wie Jörg schon angedeutet hat, man kann den Prescaler über das PSR10-Bit 
im SFIOR zurücksetzen. Ein Ändern der CS-Bits setzt den Prescaler aber 
nicht zurück! Außerdem ist darauf zu achten, dass Timer 0 und Timer 1 
(sofern vorhanden) den selben Prescaler benutzen.
Gast #483794
Lesenswert?

>> Ich finde nichts zu dem Thema.
>Im Datenblatt (in diesem Fall vom Tiny2313) im Abschnitt "Timer/Counter0
>and Timer/Counter1 Prescalers"...

Gut, dass du das gefunden hast - da brauche ich nicht weiter suchen.
Gast #483798
Lesenswert?

> Gut, dass du das gefunden hast
Naja, ich weiß nicht, wenn ich Infos zum Prescaler haben will, dann 
schau ich doch im Kapitel "Prescaler" im Datenblatt nach... Ich bin eben 
kein Zauberer, der als erstes das Buch raussucht, das mit der 
Fragestellung am wenigsten zu tun hat...;-) (TP, The Last Hero, wenn ich 
mich recht erinnere...)
Gast #483876
Lesenswert?

> TCCR0A = (1<<WGM01);
> TCCR0B = (1<<CS01); // PS = 8
> OCR0A = 249; // 500ms

mmhh da stimmt was nicht.

SIGNAL(TIMER0_COMPA_vect)
{
  countTimer0++;
}

TIMER0_COMPA_vect wird nicht nochgezählt :-(

Hab auch sei() gemacht und TIMSK |= (1 << OCIE0A );
Gast #483885
Lesenswert?

> Das Compare Register OCR1A wird mit dem Wert 39999 vorbelegt.
Aus dem Tutorial

Bei mir sagt der Compiler: main.c:76: warning: large integer implicitly 
truncated to unsigned type

bei OCR0A = 3999; // 1 sec

Wie groß darf OCR0A sein?
Gast #483892
Lesenswert?

ARRGG im dem Tutorial 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr ist wirklich 
einiges schiff, oder ich versteh es nicht:

> Timer 1, ein 16 Bit Timer, wird mit einem Vorteiler von 1 betrieben. Dadurch > 
erreichen wir, dass wir den Timer taktgenau arbeiten lassen können. >Zusätzlich 
wird noch das WGM12 Bit bei der Konfiguration gesetzt. Dadurch >wird der Timer in 
den CTC Modus gesetzt. Dabei wird der Inhalt des Timers >hardwaremäßig mit dem 
Inhalt des OCR1A Registers verglichen. Stimmen beide >überein, so wird der Timer 
auf 0 zurückgesetzt und im nächsten Taktzyklus ein >OCIE1A Interrupt ausgelöst. 
Das Compare Register OCR1A wird mit dem Wert >39999 vorbelegt. Dadurch vergehen 
exakt 40000 Taktzyklen von einem Compare >Interrupt zum nächsten.

Wie kommt er auf 40000 Taktzuylen bis zum nächsten Compare Interrupt ??
Gast #483954
Lesenswert?

>Wie kommt er auf 40000 Taktzuylen bis zum nächsten Compare Interrupt ??

Er hat es errechnet...

>Wie groß darf OCR0A sein?

Da OCR0A 8 Bit breit ist, ist grösste Wert 255.

OCR1A = 40000 dürfte eine Zeitbasis von 10ms ergeben bei 4MHz 
Taktfrequenz.
Wie er darauf gekommen ist, steht da ja beschrieben.

>mmhh da stimmt was nicht.
Such! Finde den Fehler!
#483963
Lesenswert?

Richard Brose wrote:
> ARRGG im dem Tutorial
> http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr ist wirklich
> einiges schiff, oder ich versteh es nicht:
>
> Wie kommt er auf 40000 Taktzuylen bis zum nächsten Compare Interrupt ??

Ich wollte eine schöne runde Zahl haben.
Bei 4 Mhz möchte ist es doch naheliegend den Timer bis
40000 zählen zu lassen. Im Interrupt dann noch bis 100
zählen und 1 Sekunde ist um.
Man hätte den Timer auch bis 20000 zählen lassen können
und im Interrupt dann bis 200 (so wars ursprünglich sogar,
bis ich kurz vor "Artikel speichern" nachmal umgedreht habe :-)
Ein Timerwert von 10000 wäre nicht so gut, denn dann müsste
man im Interrupt bis 400 zählen. Und 400 passt nicht mehr
in 1 8-Bit Register.
Ein Timerwert von 50000 wäre auch gegangen, dann müsste man
halt im Interrupt bis 80 zählen. Das hätte die CPU-Last noch
ein klein wenig gesenkt.
60000 hingegen ist ganz schlecht, weil 60000 kein ganzzahliger
Teiler von 4 Millionen ist.

Ich hab aber dann trotzdem 40000 genommen. Dadurch taucht
der Interrupt alle 1/100 Sekunden auf. Vielleicht baut
ja mal wer eine Erweiterung auf eine Stoppuhr, dann kriegt
er die 1/100 Sekunden gratis. Vielleicht bins auch ich
der das macht, nachdem ich beschrieben habe, wie man
mit 4 7-Segmentanzeigen einen Multiplex macht, 2 Lichtschranken
an die Ports gebaut habe und damit die Fallzeit eines Körpers
gemessen habe um daraus g zu berechnen :-) So ein Tutorium soll
ja auch Spass machen.
#484156
Lesenswert?

Rahul, der Trollige wrote:
>>um daraus g zu berechnen :-) So ein Tutorium soll
>>ja auch Spass machen.
>
> Sowas macht dir Spaß? Da kann ich mir andere Sache besser vorstellen.

Physik hat mir schon immer Spass gemacht.
Muss ja nicht g sein. Kann ja auch die Rundenzeit auf
einer Autorennbahn sein oder ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren