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
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
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
Ich meine nicht die Schwankungen der Taktfrequenz und Instabilität. Wenn du 4 MHZ teilst kommst du nicht auf 1 Hz.
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.
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
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
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.
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.
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.
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.
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?
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
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.
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
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?
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?
>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.
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
> 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.
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.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.