Forum: Mikrocontroller und Digitale Elektronik Exakte Zeiten bei uC wichtig??


von Knuddel P. (knopf)


Lesenswert?

bei uC´s hängen ja die Zeiten der steps von der Taktfrequenz ab. Sowiel 
ich weis aja auch die Uhren. Wie erhält man dann genaue Zeiten zum 
bwiepiel Abfragen alle 100ms oder Waits? ich denke bei RS232 und 
Ethernet ist das ja auch nicht bedeutungslos.

Gruß

Ralf

von Oliver (Gast)


Lesenswert?

Wie genau brauchst du es denn? Der Normalfall ist ein Quarz für den 
Prozessortakt. Der liefert den Grundtakt für alles weitere, auch für die 
UART und die Timer, mit der üblichen Quarzgenauigkeit. Das reicht für 
RS232 und Ethernet allemal aus.

Oliver

von Dennis (Gast)


Lesenswert?

Der interne Takt eines Atmegas kann laut Datenblatt um 10% abweichen... 
Hab ich selber gehabt bei meinem, benutze deswegen jetzt nen externen 
Quarz Oszilalator, kostet allerdings 1,55 bei Reichelt aber ist auf alle 
Fälle sien geld wert. Bei mir läuft seit 2 Tagen ne Uhr und die geht auf 
die Sekudne genau

von Knuddel P. (knopf)


Lesenswert?

Ich meine nicht die Schwankungen der Taktfrequenz und Instabilität. Wenn 
du 4 MHZ teilst kommst du nicht auf 1 Hz.

von Christian R. (supachris)


Lesenswert?

Klar, wenn man einen 16-Bit-Timer laufen lässt, der alle 40000 Impulse 
einen Interrupt gibt. Im Interrupt zähle ich dann eine Variable hoch. 
Hat die Variable den Wert 100 erreicht, ist genau* eine Sekunde rum.

*so genau wie der Quarz eben ist.

von Michael U. (amiga)


Lesenswert?

Hallo,

Vorteiler 128 -> 31250, 8Bit-Counter mit 250 -> 125, Zählregister für 
den Rest. Oder andere Kombination...
Die geraden Frequenzen (4,8,10,12,16) lassen sich immer mit wenig 
Resourcen auf 1Hz bringen.

Gruß aus Berlin
Michael

von Knuddel P. (knopf)


Lesenswert?

Die Timer können das nicht von sich aus oder?

von Peter D. (peda)


Lesenswert?

Knuddel Pudel wrote:
> Die Timer können das nicht von sich aus oder?

Wozu?

Warum sollte man extra nen Timer nur für den Sekundentakt verschwenden?

In der Praxis braucht man eh nen Timer mit höherer Interruptrate, z.B. 
1ms oder 10ms.
Und dann in dem Interrupt noch ne Variable runter zu zählen is ja nun 
kein Akt.

Das ist ja der Witz an Softwarelösungen, daß man sich mit nur einem 
Hardwaretimer 100 verschiedene virtuelle Timer programmieren kann.


Peter

von Christian R. (supachris)


Lesenswert?

Man hat ja mehrere Timer. Ich arbeite mit dem MSP430 meist mit allen 
verfügbaren Timern, extern einen TCXO mit 32.768 kHz angeschlossen für 
die Software-RTC, und andere Sachen, die exakt laufen müssen, die 
anderen Timer meist am DCO-Takt für die weniger genauen Sachen.

von Knuddel P. (knopf)


Lesenswert?

ah ich verstehe. man kann die vorgesfchlagenen quarze 4 mhz oder 16 so 
im Timer einstellen dass man immer auf 1ms 10 ms oder 100ms kommt. dann 
ist der Rest klar. mir ging es nur darumm dass man nicht irgendwas 
Rationales kekotzes bekommt wie zum Beispiel 66,2312345ms odder so.

von AVRFan (Gast)


Lesenswert?

Die Hardware-Timer können genaue Takte bereitstellen; das ist (u. a.) 
ihr Zweck. Sie können nur keine sehr niedrigen Frequenzen (Sekundentakt) 
direkt erzeugen, wegen begrenzter Bitbreite und verfügbarer 
Vorteilerwerte.  Möchte man eine niedrige Frequenze haben, ist das 
jedoch überhaupt kein Problem: Dazu lässt man einfach einen 
Harware-Timer mit einer höheren Frequenz "ticken" und teilt diese 
Basisfrequenz dann mit einem "Software-Timer" weiter herunter.  Das ist 
einfach eine Zählvariable, die immer weitergezählt wird, bis sie einen 
Maximalwert erreicht hat, und, dort angelangt, wieder auf Null gesetzt 
wird.  Für die Software-Timer gibt es keine Grenzen; man kann die 
Überlaufwerte wählen, wie man will, man kann soviele Software-Timer 
installieren, wie man will (alle "angetrieben" von einem einzigen 
Hardware-Timer), und man kann, falls sinnvoll, mehrere davon 
kaskadieren, und damit sind dann beliebig lange exakte Wartezeiten 
realisierbar.

von Bastler (Gast)


Lesenswert?

Man kann aber nur ganzzahlig teilen.
Deshalb gibt auch so "krumme" Quarztakte.

Ansonsten kann es schon vorkommen, dass man 10,03ms erhält anstatt den 
gewollten 10,00ms. Kommt aber auch auf die Taktung an.

von Knuddel P. (knopf)


Lesenswert?

Ahja, also so ungefähr wird es also reichen und für genauere Werte 
braucht man einen Uhrequarz.
Wie ist es mit der RS232 Schnittstelle die brauche doch auch oft 
ungerade Baudraten zum Beispiel 19000Boud oder so?

von Peter D. (peda)


Lesenswert?

Knuddel Pudel wrote:
> Ahja, also so ungefähr wird es also reichen und für genauere Werte
> braucht man einen Uhrequarz.

Nö.

Welcher Quarz ist wurscht, ob 12MHz oder 32kHz.
Ohne Abgleich geht jede Uhr nicht sonderlich genau.

Aber mit etwas Schulmathematik (Rechnen mit gebrochenen Zahlen) kriegt 
man den Abgleich in Software gut hin.

In der Codesammlung ist ein Beispiel.


Peter

von Christian R. (supachris)


Lesenswert?

Den "Uhrenquarz" hab ich nur drin, damit der MSP430 im Low Power Mode so 
wenig wie möglich Strom verbraucht. Das ist allerdings kein normaler 
Quarz sondern ein TCXO von Epson. Extrem wenig Strom und hohe 
Genauigkeit. Dienst bei mir als Sample-Takt für den ADC.

Die Baudraten bekommt man (ohne Modulator) am besten aus den 
Baudraten-Quarzen, z.B. 7,3728MHz.

von Matthias Kölling (Gast)


Lesenswert?

Was ist das eigentlich für ein Gejammer bezüglich Baudratenquartze?
Ich fahre 115200 Baud problemlos über 3m mit einem 16MHz Quartz, was 
eine Abweichung von 2% bringt.

Gruß Matthias

von Knuddel P. (knopf)


Lesenswert?

Dein quarz ist ineresannt. Aber ich vermute, dass er über alle 
Temperaurbereiche nicht so sicher anschwingt wie ein Quarz der höher 
bestromt ist. Allerdings nimmt bei höher Belastung auch die Genauikeit 
von quarzen ab. Ist also ein Kompromiß, denke ich mal.

Wie macht ihr das mit den Timern und anschließenden Zählern? Der Timer 
lößt ja aienen Interrupt aus beim Nulldurchgang. Bei der Inerruptroutine 
kann man schon eine Variable hochzählen aber wie ist die dann 
Inerruptfähig?

von Christian R. (supachris)


Lesenswert?

Knuddel Pudel wrote:
> Dein quarz ist ineresannt. Aber ich vermute, dass er über alle
> Temperaurbereiche nicht so sicher anschwingt wie ein Quarz der höher
> bestromt ist. Allerdings nimmt bei höher Belastung auch die Genauikeit
> von quarzen ab. Ist also ein Kompromiß, denke ich mal.

Versteh ich nicht. War ich gemeint?

von Timmo H. (masterfx)


Lesenswert?

>Wie macht ihr das mit den Timern und anschließenden Zählern? Der Timer
>lößt ja aienen Interrupt aus beim Nulldurchgang. Bei der Inerruptroutine
>kann man schon eine Variable hochzählen aber wie ist die dann
>Inerruptfähig?

Du hast einen Timer der z.B. alle 1000 Takte einen Interrupt auslöst. In 
dieser interrupt-Routine hast du dann z.B. eine globale Variable die du 
immer inkrementierst. Wenn diese Variable dann einen bestimmten Wert 
erreicht springst du einfach in eine Funktion die z.B. eine LED blinken 
lässt. Das muss man z.B. machen wenn du mit deinem Timer keine 1 Sekunde 
hinbekommt (aufgrund der Taktfrequenz, bzw. nur 8 Bit Timer) sondern 
z.B. nur genau auf 25ms.

von Reinhard R. (reirawb)


Lesenswert?

Um eine Einschätzung der Quarzfrequenz bezüglich der Eignung für
bestimmte zu erzeugende Takte zu erhalten, empfiehlt sich eine
Primfaktorzerlegung der Quarzfrequenz. Bei relatv glatten
Quarzfrequenzen geht das sehr gut auf dem Papier, für "krumme"
Frequenzen empfiehlt sich:

http://www.mathepower.com/primfaktor.php

Am Beispiel der schon erwähnten "krummen" Frequenz von 7,3728MHz
sieht man, das gerade diese bezüglich der mögliche Kombinationen
sehr variabel ist:  2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*3*5*5

Es komm aber auch immer auf das gewünscht Ergebnis an, für die
Erzeugung von Baudraten sehr geeignet, für die Erzeugung von
dekadische Frequenzen oberhalb 100Hz ungeeignet.

Gruß Reinhard

von Unbekannter (Gast)


Lesenswert?

> Man kann aber nur ganzzahlig teilen.

Nein, man kann beliebig (rational) teilen. Das einzige Manko daran ist 
etwas Phasenjitter. Der ist bei niedrigen Teilergebnissen aber 
prozentual sehr klein. Selbst bei höheren Frequenzen ist er oft kleiner 
als die erlaubte Toleranz. Von daher selten ein Problem.

von Knuddel P. (knopf)


Lesenswert?

Ein quartz wird ungenauer, wenn man ihn belastet. Je mehr Belastung 
desto mehr driftet er von der Frequenz weg. allerdings schwingt er dafür 
auch leichter an beim Einschalten. du musst dir das so vorstellen wie 
ein Parallelkreis. Wird er nicht belastet so ist der Parallelkreis sehr 
schmalbandig. Wird er belastet wird er Breitbandig. Baut man damit einen 
Oszillator, so ist das Einschwingen bei einem breiteren Kreis günstiger, 
dafür aber auch breitbandiger. Ein quarz kann in Sereien und auch in 
Parallelresonaz betreiben werden. Sprich wie ein Schwingkreis.Die 
Resonanz von Serein und Parallelresonanz sind nicht gleich. Beim Kauf 
ist daher darauf zu achten o die Angegebene Frequenz bei seren oder 
parellelresonanz gilt. Sie leigen aber nicht weit voneinander weg. Zum 
Beispiel
 100Mhz und 98Mhz.

von Knuddel P. (knopf)


Lesenswert?

Wenn Du als Timer einen Inerrupt auslöst und in dieser Routine eine 
globale Variable hochgezählt wird und bei Erreichen enes Wetes irgendwo 
hingesprungen wird wird dann doch die Inerruptroutine nicht richtig 
beendet oder?

von Karl H. (kbuchegg)


Lesenswert?

Knuddel Pudel wrote:
> Wenn Du als Timer einen Inerrupt auslöst und in dieser Routine eine
> globale Variable hochgezählt wird und bei Erreichen enes Wetes irgendwo
> hingesprungen wird wird dann doch die Inerruptroutine nicht richtig
> beendet oder?

Doch.
Dazu gibt es mehrere Möglichkeiten:
* In der Interruptbehandlung rufst du eine weitere Funktion
  auf. Diese erledigt ihre Arbeit und kehrt zur Interruptroutine
  zurück, woraufhin auch diese returniert.

* In der Interruptroutine wird keine weitere Funktion aufgerufen,
  sondern nur ein Merker (ein Flag) gesetzt, dass etwas zu geschehen
  hat. Innerhalb der Hauptschleife wird laufend dieses Flag ausgewertet
  und die betreffende Funktionalität bei Bedarf angestossen
ungefähr so:
1
uint8_t Timer;
2
volatile uint8_t MachWas;
3
4
ISR( .... )
5
{
6
  Timer++;
7
  if( Timer == 100 ) {
8
    Timer = 0;
9
    MachWas = 1;
10
  }
11
}
12
13
int main()
14
{
15
  ....
16
17
  MachWas = 0;
18
19
  while( 1 ) {
20
21
    if( MachWas == 1 ) {
22
      MachWas = 0;
23
24
      .....  das angeforderte abarbeiten
25
    }
26
  }
27
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.