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
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.
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
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ß
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.
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
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.
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.
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.
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.
@ 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.