Forum: Mikrocontroller und Digitale Elektronik genaue Frequenzen erzeugen


von Tilmann (Gast)


Lesenswert?

Hallo,

ich möchte gern mit einem ATtiny13 (nach Möglichkeit) genaue Frequenzen 
erzeugen: 20,1 kHz, 20,2 kHz, 20,3 kHz, 20,4 kHz.

Mit meinem Bascom-Code komme ich schon recht gut an die gewünschten 
Frequenzen heran; mein Versuch, ein Feintuning mittels manipulierter 
"$crystal"-Werte ist jedoch gescheitert (ich hatte ausgerechnet, daß 
wenn mir die vorhandene Frequenz um 1,6 % zu schnell ist, daß ich dann 
den Wert für den externen Oszillator um diesen Faktor höher angebe; der 
Wert, den ichdamit erhielt, war jedoch viel weiter vom Gewünschten 
entfernt).

Hat jemand eine Idee ?

Man kann natürlich einen schnelleren Oszillator nehmen, dann werden die 
Frequenzschritte, die von einem "nop" mehr oder weniger verursacht 
werden, geringer. Aber vielleicht gibt es ja noch eine elegantere 
Möglichkeit ?

Gruß Tilmann


______________________________________________________________________ 
__
'ATtiny13 soll mit 20,4 kHz takten. Erreicht werden 20,48 kHz.

$regfile = "attiny13.dat"
$crystal = 6553600         'externer Oszillator
$hwstack = 10
$swstack = 10
$framesize = 20
Config Portb.4 = Output

Do
Waitus 23              'us=µs

$asm                   'wechselt in Assembler-Code
nop                    'tue nichts
nop                    'ein solcher Befehl macht ca. 130 Hz aus
$end Asm               'zurückwechseln von Assembler in Bascom

Toggle Portb.4
Loop
End

von kukuk (Gast)


Lesenswert?

DDS macht es moeglich...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Google mal nach poor mans DDS

von Karl H. (kbuchegg)


Lesenswert?

Tilmann schrieb:

> Mit meinem Bascom-Code komme ich schon recht gut an die gewünschten
> Frequenzen heran; mein Versuch, ein Feintuning mittels manipulierter
> "$crystal"-Werte ist jedoch gescheitert

?
Das ist doch völliger Quatsch.
Das ist wie wenn du mit dem Auto von 80km/h auf 100km/h beschleunigst, 
indem du größere Reifen montierst, weil du nicht weißt, dass dein Auto 
auch ein Getriebe mit 5 Gängen hat.

> werden, geringer. Aber vielleicht gibt es ja noch eine elegantere
> Möglichkeit ?

Ja gibt es.
Dein µC hat Timer-Hardware mit.
Damit und zb dem CTC Mode bzw. einem PWM Modus kann man wunderbar 
Frequenzen erzeugen. Und zwar auf die Quarzschwingung genau.

von Sven (Gast)


Lesenswert?

Hi,

wie genau solls denn werden?

Die kleinste Zeitauflösung die du erreichen kannst ist 1 / 
Crystalfrequenz.
(In deinem Fall (im Source steht was von 6,5536 MHz) also 152,6 ns,
was bei 20KHz ca 0,3% sind.)

Ein bisschen einfacher als das mit NOPs zu erreichen ist sicherlich das 
ganze von nem Timer übernehmen zu lassen.
Bei 6,5536 MHz und ner Timerfrequenz von 20 KHz kommst auf ca 326 als 
Counter-Wert, du brauchst also nen 16Bit Timer.

Wenn ich das Datenblatt zur Oszillatorkalibrierung richtig verstehe kann 
man den Wert im Bereich von 0x00 bis 0x7F einstellen was zu einer 
Taktveränderung nem Faktor 2 führt. (Also ca 100%, wenn der 
Ursprungstakt stimmt ca. 50% - 150%). Du hast also nen Einstellbereich 
von 128 Schritten für ca 100%, macht ca 0,8% pro Schritt.

Fazit:
Mit dem OSCCAL kannst du weniger genau Kalibrieren als mit nem Timer
und bei 6,5 MHz wirst du maximal eine Auflösung von 150ns erreichen.

Gruß,
Sven

von Dietrich L. (dietrichl)


Lesenswert?

Sven schrieb:
> du brauchst also nen 16Bit Timer

d.h. es geht nicht mit dem ATtiny13. Der hat nur einen 8 Bit Timer.

Gruß Dietrich

von Sven (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das ist doch völliger Quatsch.
> Das ist wie wenn du mit dem Auto von 80km/h auf 100km/h beschleunigst,
> indem du größere Reifen montierst, weil du nicht weißt, dass dein Auto
> auch ein Getriebe mit 5 Gängen hat.

Warum völliger Quatsch?
Ich hatte bis eben auch angenommen das ich mit dem OSCCAL Register 
wesentlich genauer kalibrieren kann. Dann wär es doch eine akzeptable 
Methode gewesen eine sonst nicht zu erreichende Auflösung durch diesen 
Trick zu erreichen...
Sicherlich unüblich und nicht zu empfehlen bei Code den man leicht 
verstehen soll, aber doch durchaus zielführend.

Wobei sich das ja (soweit meine Rechnung richtig ist) sowieso erledigt 
hat weil man eben keine besonders hohe Auflösung mit dem OSCCAL hat...

Gruß

von Floh (Gast)


Lesenswert?

Dietrich L. schrieb:
> d.h. es geht nicht mit dem ATtiny13. Der hat nur einen 8 Bit Timer.

Geht schon, kann man softwaretechnisch aufbohren mit einer Zählvariable 
im Timeroverflowinterrupt.

von spess53 (Gast)


Lesenswert?

Hi

>Mit dem OSCCAL kannst du weniger genau Kalibrieren als mit nem Timer
>und bei 6,5 MHz wirst du maximal eine Auflösung von 150ns erreichen.

Kalibieren kann man nur den internen RC-Oszillator. 6,5536MHz ist ein 
Quarz(-Oszillator). Da geht das nicht.

Mit CTC erreicht man diese Frequenzen mit einer Abweichung von 
0,015...0,259%. Ein 8-Bit-Timer reicht.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Dietrich L. schrieb:
> Sven schrieb:
>> du brauchst also nen 16Bit Timer
>
> d.h. es geht nicht mit dem ATtiny13. Der hat nur einen 8 Bit Timer.

Geht auch.
Sagt ja keiner, dass man in jedem ISR Aufruf den Pin toggeln muss.

Ist aber zugegebenermassen etwas umständlicher zu programmieren, wenn es 
universell einstellbar sein soll.

von Karl H. (kbuchegg)


Lesenswert?

Sven schrieb:
> Karl Heinz Buchegger schrieb:
>> Das ist doch völliger Quatsch.
>> Das ist wie wenn du mit dem Auto von 80km/h auf 100km/h beschleunigst,
>> indem du größere Reifen montierst, weil du nicht weißt, dass dein Auto
>> auch ein Getriebe mit 5 Gängen hat.
>
> Warum völliger Quatsch?

Weil man Frequenzen nicht dadurch erzeugt, dass man den µC mittels 
waitus warten lässt, sondern in dem man dein Timer den Job erledigen 
lässt.
Dafür ist er da.

Und völliger Quatsch ist es, den Compiler bezüglich der Taktfrequenz 
anzulügen, damit der den waitus genau so generiert, dass dann hinten 
nach die gewünschte Frequenz rauskommt.

von J. S. (engineer) Benutzerseite


Lesenswert?

Martin Wende schrieb:
> Google mal nach poor mans DDS
Was ist an dieser "poor man" DDS so Besonderes? Ich habe den Artikel 
gelesen und nichts Aussergewöhnliches vorgefunden.

Floh schrieb:
> Geht schon, kann man softwaretechnisch aufbohren mit einer Zählvariable
> im Timeroverflowinterrupt.
Genau auf das DDS-Prinzip läuft das auch hinaus, wobei man mit einem 
HW-Timer die Möglichkeit hat, ihn früher umzusteuern, wenn man das 
geschickt tut und er es verträgt.

"Genaue" Frequenzen bekommt man deshalb aber trotzdem nicht hin. DDS 
liefert für beliebige Frequenzen (abgesehen von denen, die genau 
ganzzahlig passen) immer ein Phasenrauschen, weil immer ein 
Frequenzsprung vollzogen wird. Dieses kann man, wenn man eine klassische 
DDS nutzt, automatisch erzeugen und sich vom Ergebnis überraschen 
lassen, oder es durch geschickte Ansteuerung minimieren - vor allem in 
Verbindung mit einem nachgeschalteten Filter, das auf den Frequenzsprung 
durch mit Phasenveränderung und Amplitudenveränderung reagiert. Sowas 
geht aber nur mit einem schnellen FPGA und Signalvorverarbeitung.

Mit einem UC böte sich an, dessen Taktfrequenz zu regeln. Man braucht 
einen Oszillator/ein PLL, die manuell aufgebaut ist und der man Energie 
zuführen kann, um sie zu beschleunigen. Dann könnte man die Frequenz um 
einige Prozente tunen, um mit einer groben DDS hinzukommen.

Die ersten halbdigitalen Synthesizer in den 80ern haben das so gemacht.

von Kein Name (Gast)


Lesenswert?

Mit Kapazitätsdioden den Quarz ziehen?
Wenn der Timer durch 2000/2001/2002... teilt, könnten die +-300ppm so 
gerade ausreichen.

von J. S. (engineer) Benutzerseite


Lesenswert?

Kein Name schrieb:
> Mit Kapazitätsdioden den Quarz ziehen?
So ungefähr. Beim leichten und sanften "Ziehen" kann man zwar die 
Frequenz nicht dauerhaft grossartig ändern, aber dynmisch beschleunigen, 
also die Phase vorziehen oder nach hinten drängen und darum geht es. 
Letztlich ist das zwar auch ein Tanz um die eigentliche Frequenz, aber 
sie ist weich und nicht so sprunghaft, wie der Bruch bei der DDS, die ja 
gewissermassen ständig kleine Bruchstücke von idealen Sinuswellen so 
aneinderreiht, dass im Mittel - nicht aber lokal - die Frequenz stimmt.

von skorpionx (Gast)


Lesenswert?

http://www.sprut.de/electronic/pic/projekte/ad7008/ad7008.htm

Das habe ich gebaut, funktioniert SUPER. Das ist mit PIC aber 
umschreiben
auf ATtiny13 sollte kein Problem sein.

von Sven (Gast)


Lesenswert?

@ Karl Heinz Buchegger:

Ah, jetzt hab ich überhaupt erst verstanden was Tilmann vor hatte... Das 
ist in der Tat nicht besonders sinnvoll.

Ich hatte ja in meinem Beitrag ein vollkommen anderes Konzept 
angesprochen, nämlich die Oszillatorkalibrierung zu missbrauchen, was 
sich ja nun aus mehreren Gründen als nicht funktionierende Idee 
herausgestellt hat.


Mir stellt sich jetzt mal wieder die Frage: Wozu eigentlich das ganze... 
Vielleicht kann man ja an anderer Stelle was anpassen um das gewünschte 
Ergebnis zu bekommen.

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.