Forum: Mikrocontroller und Digitale Elektronik Rechteckgenerator mit Atmega8 timer Problem


von Ciesla tim (Gast)


Lesenswert?

Moin zusammen

Ich versuche gerade ein Rechteckgen. von 0 - 5KHz (linear) zu 
Programmieren. Der Compiler ist Bascom. Da der Analogwert nur zu 1024 
auflöst ist das ganze gestaffelt 0-1000 1000-2000 usw.. Die Linearität 
ist natürlich ein Problem, da die Rechnung an sich zeit, braucht und der 
Sprung in die ISR Beziehung auch ihre zeit benötigt. Das sind aber 
Fehler die Leicht ausgeglichen werden können da der Sprungfehler Linear 
wächst und der Rechnungsfehler beinahe statisch ist.
Alllsooo meine frage an die Community.

1.0 Wie kann ich z.b. einer Variable (single) sagen das sie nur 2 
stellen hinter dem komma auflösen soll.

1.1 Ich kann natürlich auch z.b Long variable nehmen und den wert *100 
rechnen. Nur dann muß ich das Komma setzen.
Wie setzt man ein Komma.

2.0 Das Hauptproblem ist aber das mein 16 Bit timer ab einem bestimmten 
wert anfangen soll zu zählen 0-65535. Der nimmt aber je nach prescale 
nur werte ab 23000 an. WARUM

von Ciesla tim (Gast)


Lesenswert?

Dazu wäre noch zu sagen das der Aufbau in der Form ist:
$regfile = "m8def.dat"

$crystal = 8000000

Config Portd = Output
Dim A as Word

Config Timer1 = Timer , Prescale = 256
Enable Timer1
On Timer1 Isr_von_timer1
Enable Interrupts
Timer1 = A

Do

A = xxx
blablabla
usw.
Loop
End

Isr_von_timer1:
Timer1 = 34285
Toggle Portd.0
Return

wenn der wert A < ca 30000 wird nicht in die Isr beziehung gesprungen.

von Rahul, der Trollige (Gast)


Lesenswert?

>Do

>A = xxx
>blablabla
>usw.
>Loop
>End

Interessant, was Bascom so an Befehlen unterstützt.

Übrigens unterstützt der mega8 schon in Hardware die PWM bzw. vriable 
Frequenzerzeugung...Sowas steht wie immer im Datenblatt.

>Ich versuche gerade ein Rechteckgen. von 0 - 5KHz (linear) zu
>Programmieren.

Das will ich sehen. Man kann zwar die Periodendauer linear verändern, 
aber die Frequenz?

von Hannes L. (hannes)


Lesenswert?

Ciesla tim wrote:
> Moin zusammen
>
> Ich versuche gerade ein Rechteckgen. von 0 - 5KHz (linear) zu
> Programmieren. Der Compiler ist Bascom. Da der Analogwert nur zu 1024
> auflöst ist das ganze gestaffelt 0-1000 1000-2000 usw..

Warum willst Du den Wert über ein Poti einstellen? Damit hast Du doch 
immer etwas Jitter drauf. Nimm doch lieber eine digitale Einstellung per 
Taster oder Drehencoder.

> Die Linearität
> ist natürlich ein Problem, da die Rechnung an sich zeit, braucht und der
> Sprung in die ISR Beziehung auch ihre zeit benötigt.

Das verstehe ich nicht. Du musst doch nur den Timer in die Betriebsart 
einstellen, dass er bei Compare den OC-Pin toggelt und von 0 beginnt 
(siehe Datenblatt, Kapitel Timer). Dann wird die Frequenz ohne Interrupt 
im Hintergrund von der Hardware erzeugt. Um sie einzustellen, legst Du 
die Dauer einer halben Periode (in Timerticks gemessen) in das 
OCR-Register.

> Das sind aber
> Fehler die Leicht ausgeglichen werden können da der Sprungfehler Linear
> wächst und der Rechnungsfehler beinahe statisch ist.

Was ist ein Sprungfehler?

> Alllsooo meine frage an die Community.

Gute Idee.

>
> 1.0 Wie kann ich z.b. einer Variable (single) sagen das sie nur 2
> stellen hinter dem komma auflösen soll.

Das Rechnen mit gebrochenen Zahlen ist für den AVR Schwerstarbeit, das 
sollte man vermeiden.

>
> 1.1 Ich kann natürlich auch z.b Long variable nehmen und den wert *100
> rechnen. Nur dann muß ich das Komma setzen.

Das ist der bessere Weg.

> Wie setzt man ein Komma.

In Assembler könnte ich Dir das erklären, in BASCOM weiß ich das nicht.

>
> 2.0 Das Hauptproblem ist aber das mein 16 Bit timer ab einem bestimmten
> wert anfangen soll zu zählen 0-65535. Der nimmt aber je nach prescale
> nur werte ab 23000 an. WARUM

Auch das kann ich nicht nachvollziehen.
Um einen Timer zum Zählen zu bewegen, trägt man eine Taktquelle (z.B. 
Vorteiler) in sein entsprechendes Steuerregister ein. Dazu kommen noch 
die entsprechenden Bitmuster ("Schalterstellungen") für die gewünschte 
Betriensart des Timers. Nicht jede Betriebsart erfordert, dass der Timer 
Interrupts auslöst, das Toggeln des OC-Pins oder das Erzeugen einer PWM 
geht komplett in Hardware ohne Interrupt.

...

von Ciesla tim (Gast)


Lesenswert?

Erstmal danke für die schnellen Antworten.
Ich habe nicht sonderlich viel Erfahrung mit Controllern. Darum viel mir
als erstes Timer und toggeln ein.

Die Idee war eigentlich über ein zweites Poti2 Verschiedene
Bereiche Anzusprechen z.b 0-1000 Hz.
Die Zuweisung erfolgt mit einer case Anweisung in der Prescale jedes mal 
neu definiert wird. In jeder case Anweisung soll der wert des Poti1
abgefragt werden und über eine einfache Rechnung soll der Startwert von 
timer1 neu eingetragen werden. Diesen wert steht in der case Anweisung 
und in der Isr Bez.
So habe ich auf dem Qsi eine schöne Rechteckspannung.

Da ich den Timer1 aber nicht von 0 an zählen lassen kann sondern von 
einem viel höheren wert sind einige Frequenzbereiche nicht zu 
Generieren(Scheiße).

Wenn das ganze über die Hardware laufen kann ist das natürlich um 
einiges besser. Ich versuche mich mal in dieser Richtung schlau zu 
machen.

Jetzt zur Pwm Idee. Da müste ich doch auch so vorgehen und Über das poti 
den Wert abfragen und eintragen oder.

ps: mit sprungfehler meine ich die Zeit die benötigt wird um die 
unterfkt aufzurufen zu toggeln und zurückzuspringen.

von Uwe (Gast)


Lesenswert?

Hi!
Schau dir mal die CTC-Mode eines 16 Bit-Timers an.
Mit 16 MHz Takt kannst du dein Rechtecksignal mit einem Raster von 
62,5ns verstellen. Der Frequenzbereich erstreckt sich dann von 
122,072..Hz bis
8 MHz ohne Vorteiler. für deine geforderten 5KHz ist die Auflösung also 
recht akzeptabel. unter den 122.. Hz musst du nur den Vorteiler mit 
einschalten.
Sollte das nicht ausreichend sein?

Viel Erfolg, Uwe

von Ciesla tim (Gast)


Lesenswert?

Ich muß da noch mal Nachfragen.

Irgendwie bekomme ich das mit den variablen nicht hin. Sind sie single 
für die genauigkeit ist der wert genau nur tritt dann ein timigfehler 
auf. Mit Word ist der Rundungsfehler echt mies und das timing ist 
besseer. Dann muß ich das Ergebnis ja noch auf dem LCD Display ausgeben 
wofür ich wieder rechnen muß und die Rundungsfehler noch gravierender 
werden(Word).

Neue Idee die Frequenzen 0-5KHz zu generieren das klappt schon. Nur die 
Genauigkeit laßt zu wünschen übrig.
Um Ressourcen zu Sparen da alles schon sehr labil ist wäre es dann nicht 
sinnvoll die Frequenzen zu generieren und über einen Zweiten Atmega8 
diese zu messen und auszugeben?
Ich setzt mich jetzt mal hin und schau ab das besser klappt.

Wenn jemand eine Bessere Idee hat nur her damit

von Hannes L. (hannes)


Lesenswert?

Ciesla tim wrote:
> Ich muß da noch mal Nachfragen.
>
> Irgendwie bekomme ich das mit den variablen nicht hin. Sind sie single
> für die genauigkeit ist der wert genau nur tritt dann ein timigfehler
> auf.

Das Rechnen mit Fließkommazahlen ist für den AVR Schwerstarbeit. Wenn Du 
dann noch den Pin vom Programm aus toggeln musst, dann kommt der AVR 
nicht mehr nach.

> Mit Word ist der Rundungsfehler echt mies und das timing ist
> besseer. Dann muß ich das Ergebnis ja noch auf dem LCD Display ausgeben
> wofür ich wieder rechnen muß und die Rundungsfehler noch gravierender
> werden(Word).

Meiner Meinung nach benötigst Du eine 16-Bit-Ganzzahl, die in einigen 
Hochsprachen auch 'Integer' genannt wird. Denn der Timer arbeitet ja mit 
16-Bit-Ganzzahl, 'Single' (also Fließkommazahl einfacher Genauigkeit) 
kennt der Timrer nicht, warum um alles in der Welt sollte man damit 
rechnen??

>
> Neue Idee die Frequenzen 0-5KHz zu generieren das klappt schon. Nur die
> Genauigkeit laßt zu wünschen übrig.

0 kHz klappt immer, lass das Gerät einfach aus. Aber zwischen 0 und dem 
unteren einstellbaren Wert wird es problematisch. Der untere 
einstellbare Wert wir durch den Zählumfang des Timers (64K, also 65536) 
begrenzt. Zwar auch durch den Vorteiler, aber im Sinne einer feinen 
Abstimmbarkeit sollte dieser möglichst klein gehalten werden.

> Um Ressourcen zu Sparen da alles schon sehr labil ist wäre es dann nicht
> sinnvoll die Frequenzen zu generieren und über einen Zweiten Atmega8
> diese zu messen und auszugeben?

Nein, das ist nicht sinnvoll, denn die Ressourcen des AVRs sind allemale 
ausreichend. Du musst sie nur nutzen. Also:
- Frequenzerzeugung am OC-Pin per Hardware des Timers
- Einstellung der Periodendauer statt der Frequenz (Umrechnung in 
Frequenz
  nur für die Anzeige)
- ADC-Abfrage mit Hysterese nachrüsten, um (funktionsbedingten) Jitter 
zu
  vermeiden

> Ich setzt mich jetzt mal hin und schau ab das besser klappt.
>
> Wenn jemand eine Bessere Idee hat nur her damit

Bessere Idee?
- Datenblatt (Vollversion) des AVRs lesen (und verstehen), besonders
  das Kapitel Timer
- BASCOM-Dokumentation lesen und versuchen zu ergründen, wie viele
  Ressourcen von ganz simpel erscheinenden BASIC-Befehlen gefressen
  werden

...

von Ciesla tim (Gast)


Lesenswert?

Danke Hannes

Ich bin gerade im Praktikum (FH) und das ich Bascom Volllenasteniker bin 
geht's hier nur um das Ergebnis. Ich will hier auch niemanden ein Loch 
in den Bauch fragen.
Darum habe ich mich für die 2 AVR Variante entschieden.
Ich messe die Impulse pro Sekunde, das klappt für f >500 erstaunlich 
genau. Und bei f<500 messe ich die Zeit zwischen 2,4 oder 8 Impulsen muß 
noch schauen was das beste Ergebnis bringt.
Trotzdem bin ich weiten Vorschlägen nicht abgeneigt

Am Wochenende werde ich mir dann wohl oder übel den Langenscheid 
schnappen und mir das Datenblatt vorknüpfen.

Wenn dann mal alles Klappt setzte ich den Quell-code hier rein.

>Meiner Meinung nach benötigst Du eine 16-Bit-Ganzzahl, die in einigen
>Hochsprachen auch 'Integer' genannt wird. Denn der Timer arbeitet ja mit
>16-Bit-Ganzzahl, 'Single' (also Fließkommazahl einfacher Genauigkeit)
>kennt der Timer nicht, warum um alles in der Welt sollte man damit
>rechnen??

Ich will dem timer keine Single verpassen. Nur die Rechnug damit der 
Rundungsfehler klein bleibt. Denn bei einigen bereichen von prescale 
kommt es auf die letzte zahl an. Hab die Rechnung von 1-5KHz(besser) für 
jedes Prescale mit c++ ausgeben lassen da sieht man das ganz gut. Nur 
der letzte wert habe ich in word konvertiert. Und das ist schon sehr 
ungenau.

Mein erster Vorschlag war eine Tabelle mit 5000 einträgen a 5 zeichen na 
ja das ging dann nicht ganz.

von daniel (Gast)


Lesenswert?

@Hannes

> Wie setzt man ein Komma.

> In Assembler könnte ich Dir das erklären, in BASCOM weiß ich das nicht.

Das wuerde mich mal fuer Assembler interressieren.
Also ich habe eine binaere Zahl in einem Register des ATmega8. Sagen wir 
123 und nun soll es eine 12,3 sein. Wie wird das in Assembler 
programmiert ?

Vielen Dank
daniel

von Hannes L. (hannes)


Lesenswert?

Meine Hedanken dazu nochmal zum Mitmeißeln:

- Mit der Eingabe (Poti-ADC, besser was Digitales wie Taster oder
  Drehgeber) nicht die Frequenz eingeben wollen, sondern die (halbe)
  Periodendauer, also die Ganzzahl, die Du in das Compare-Register
  des Timers schreibst. Da Du den Timer nicht mit einer "Frequenz"
  füttern kannst, sondern nur mit einer (halben) Periodendauer, macht
  das Eingeben einer Frequenz und anschließende Umrechnen in die
  Periodendauer (zum Timer füttern) keinen Sinn.

- Den Timer in die Betriebsart schalten, in der er den OC0A oder 
OC0B-Pin
  direkt beim Compare-Ereignis toggelt und sich selbst löscht, ohne dass
  ein Interrupt ausgelöst werden muss. Das kostet dann keine (absolut
  keine!!) Rechenzeit.

- Den eingestellten Periodenwert zur Frequenz umrechnen und am LCD
  anzeigen. Damit bekommt der Benutzer das Gefühl, die Frequenz
  eingegeben zu haben, obwohl er ja nur einen timertauglichen Wert für
  die Periodendauer eingibt/ändert.

- Falls die Eingabe per Poti erfolgen muss, dann noch eine Hysterese
  einbauen, die dafür sorgt, dass ein neuer Wert erst dann übernommen
  wird, wenn er mehr als 2..3 Werte vom alten Wert entfernt ist. Das
  beruhigt die Eingabe und damit auch die erzeugte Periodendauer bzw.
  Frequenz.

- Sinnvoll wäre vermutlich eine Art Bereichswahl mittels Up/Down-Tasten
  und eine Feinabstimmung innerhalb des Bereiches. Mit den Up/Down-
  Tasten stellst Du den Grundwert (16 Bit Ganzzahl) im Raster von 1024
  ein, zu dem Du dann den (per Hysterese beruhigten) ADC-Wert des Potis
  addierst.

...

von Hannes L. (hannes)


Lesenswert?

daniel wrote:
> @Hannes
>
>> Wie setzt man ein Komma.
>
>> In Assembler könnte ich Dir das erklären, in BASCOM weiß ich das nicht.
>
> Das wuerde mich mal fuer Assembler interressieren.
> Also ich habe eine binaere Zahl in einem Register des ATmega8. Sagen wir
> 123 und nun soll es eine 12,3 sein. Wie wird das in Assembler
> programmiert ?

Eine Zahlenausgaberoutine für 16 und 24 Bit findest Du in der 
Include-Datei LCDprint auf dieser Seite:
http://www.hanneslux.de/avr/stopuhr/index.html
Das genze Projekt ist zwar (aus heutiger Sicht) nicht das Nonplusultra, 
aber es funktioniert.


>
> Vielen Dank
> daniel

Nix zu danken

...

von Karl H. (kbuchegg)


Lesenswert?

Gar nicht.
Der springende Punkt ist, dass du das Komma nur zur
Anzeige brauchst. Du speicherst nach wie vor 123 im
Register. Und bei der Ausgabe gibst du vor der Einerstelle
ein Komma aus.

Das ist ein bischen so wie beim Rechnen mit Geld.
Du willst €2.20 und €3.70 addieren, hast aber
keine Kommastellen zur Verfügung.
Kein Mensch sagt aber, dass du das in Euro rechnen musst.
Rechne es halt in Cent. €2.20 sind 220 Cent. €3.70 sind
370 sind. Jetzt haben wir schöne ganze Zahlen.
220 + 370 macht 590. Bei der Ausgabe schmuggeln wir vor
der 2.ten Stelle wieder ein Komma an und schreiben
noch ein € davor:   €5.90

Natürlich gibt es Fälle, bei denen man echte Gleitkomma-
arithmetik braucht. Aber gerade im µC Bereich kommt man
mit so einer Systematik (die man Fixkomma nennt) sehr, sehr
weit.

von daniel (Gast)


Lesenswert?

Vielen Dank fuer die schnellen und hilfreichen Antworten.
Das Prinzip merk ich mir ! :)
daniel

von Karl H. (kbuchegg)


Lesenswert?

@Hannes

> Eine Zahlenausgaberoutine für 16 und 24 Bit findest Du in der
> Include-Datei LCDprint auf dieser Seite:
> http://www.hanneslux.de/avr/stopuhr/index.html
> Das genze Projekt ist zwar (aus heutiger Sicht) nicht das
> Nonplusultra, aber es funktioniert.

Da ich gerade an Erweiterungen im AVR-Tutorial arbeite:
Darf ich mir aus deinen Sourcen Dinge dafür klauen.

Ich wäre auch froh, wenn du ein oder 2 Kapitel übernehmen
könntest. Was ich in nächster Zeit brauchen würde:
Einführung in den ADC; wie steuert man ein Servo an.



von Hannes L. (hannes)


Lesenswert?

Karl heinz Buchegger wrote:
> @Hannes

Grüß Gott, Karl Heinz...

>
>> Eine Zahlenausgaberoutine für 16 und 24 Bit findest Du in der
>> Include-Datei LCDprint auf dieser Seite:
>> http://www.hanneslux.de/avr/stopuhr/index.html
>> Das genze Projekt ist zwar (aus heutiger Sicht) nicht das
>> Nonplusultra, aber es funktioniert.
>
> Da ich gerade an Erweiterungen im AVR-Tutorial arbeite:
> Darf ich mir aus deinen Sourcen Dinge dafür klauen.

Selbstverständlich darfst Du das. Es ist ja auch nicht alles auf meinem 
Mist gewachsen, Ich habe da nur (auf niedrigerem Niveau) 
nachgeschrieben, was ich an Beispielen von Peter, Andreas, Andy und 
einigen anderen verstanden habe. Wohlbemerkt, verstanden und 
nachempfunden, nicht blind kopiert...

>
> Ich wäre auch froh, wenn du ein oder 2 Kapitel übernehmen
> könntest. Was ich in nächster Zeit brauchen würde:
> Einführung in den ADC; wie steuert man ein Servo an.

Mit dem WIKI tu ich mich sehr schwer. Außer der gelegentlichen Korrektur 
einiger Tippfehler oder einiger falschen bzw. missverständlichen 
Aussagen halte ich mich da sehr zurück.

Der Grund liegt darin, dass es dort einige "hochwissenschaftliche" 
Darstellungen gibt, die zwar sehr intelligent aussehen, aber jeden 
Einsteiger sofort zum Rückzug animieren. In dieser Liga kann und will 
ich nicht mitspielen. - Sorry...

...

von Peter D. (peda)


Lesenswert?

Hannes Lux wrote:

> Das Rechnen mit Fließkommazahlen ist für den AVR Schwerstarbeit. Wenn Du
> dann noch den Pin vom Programm aus toggeln musst, dann kommt der AVR
> nicht mehr nach.

Na na, nicht gleich übertreiben.

O.k. kann schon mal ne ms dauern und ist damit noch 1000-mal schneller, 
als Du nen neuen Wert eingibst.

Und das ist ja das hüpfende Komma:

Die Rechnung ist nur bei Frequenzänderung einmalig notwendig !

Auf die Genauigkeit der Frequenz hat also die Rechenzeit keinerlei 
Einfluß.

Also nimm ruhig float, wenn Du kannst.


Der Rest wurde ja schon gesagt: Timer in Mode 4 und Pin-Toggle 
anschalten, fertig.


Peter


P.S.:
Wert mit Potis eingeben ist total ungenau, nimm einfach die UART und ein 
Terminalprogramm.

von Ciesla tim (Gast)


Lesenswert?

Morgen zusammen. (nochmal)

Irgendwie scheine ich das Prinzip noch nicht so ganz geschnallt zu 
haben.
So sieht das Testprog bei mir aus.

$regfile="m8def.dat"
$cristal=8000000
$baud=9800

Config pinb.1=output

Enable Timer1
Config Timer1=timer,Prescale 1024,Compare A=toggle
start Timer 1

Do

Compare1a=65000

loop
end

Da müßte b.1 doch mit 14,57 Hz toggeln. Tut er aber nicht. Wo ist der 
Fehler.

Die Sache mit dem Drehgeber ist echt genial werde ich auf jeden fall 
versuchen einzubauen.
Falls hier einer drin ist im Prog sind keine Schreibfehler!

von Karl H. (kbuchegg)


Lesenswert?

> 14,57 Hz toggeln

Wie kommst du auf 14.57Hz?

8000000 / 1024 = 7812.5 Hz
7812.5 / 65000 = 0.12 Hz

Also alle ~ 8 Sekunden toggelt der Pin

Ob die Timer-Konfiguration so stimmt, kann ich nicht sagen.
Da versteh ich zuwenig von BASCOM.

> Falls hier einer drin ist im Prog sind keine Schreibfehler!
Dafür gibt es ja auch Cut&Paste.
Im Programmeditor vom BASCOM markierst du deinen kompletten
Text und drückst Strg-C.
Dann gehst du hier ins Forum und setzt den Text mittels Strg+V
wieder ein. -> geht schneller, ist weniger Tippaufwand und
du postest hier die gleichen Fehler die du auch in deinem
Programm hast.

von Hannes (Gast)


Lesenswert?

> Ob die Timer-Konfiguration so stimmt, kann ich nicht sagen.
> Da versteh ich zuwenig von BASCOM.

Und hier zeigt sich der Hauptmangel von BASCOM.
Durch diese unsinnigen Config-Möglichkeiten wird der Benutzer 
(Programmierer?) davon abgehalten, die Steuerregister des AVRs (seiner 
internen Peripherie) selbst einzustellen, sich also selbst um jedes Bit 
zu kümmern, wie es das ASM-Programmierer und der C-Programmierer tun 
muss. Und daher sprechen wir (BASCOMer <-> Rest der Welt) 
unterschiedliche Sprachen und verstehen uns nicht bzw. selten.

Weniger ist manchmal mehr. Mit einem BASCOM, das auf diesen ganzen 
Config-Krams verzichtet, dafür aber den erzeugten ASM-Code bereitstellt, 
hätte ich mich vermutlich anfreunden können, wenn ich es rechtzeitig in 
die Hände bekommen hätte.

...

von Ciesla tim (Gast)


Lesenswert?

>Wie kommst du auf 14.57Hz?

f = (quarz/prescale)/(65536-X)

und x ist hier 65000

von Ciesla tim (Gast)


Lesenswert?

Ohhhh nein stimmt gar nicht, die Formel gilt wenn man ihn von x starten 
lässt.

Alles klar das erkärt einiges.

von Rahul, der Trollige (Gast)


Lesenswert?

>f = (quarz/prescale)/(65536-X)
>und x ist hier 65000

ja, macht ja nichts.
Du benutzt ja (offensichtlich) den Toggle-Modus. Da wird bei jedem 
Erreichen des OCR1-Wertes der Ausgang umgeschaltet.
Und das passiert etwa alle 8 Sekunden...
Was hindert dich eigentlich daran, dir mal das Datenblatt anzugucken und 
dazu Fragen zu stellen? Mit irgendwelchen Rate-Bascom-Programmen wird 
das nichts.

von Ciesla tim (Gast)


Lesenswert?

Ju hu alles geht wie es soll (fast).
Ich lasse den Timer1 ab einem bestimmten wert starten, bei Überlauf 
toggeln und (man möge mir verzeihen) mit einem 2 AVR Messen. Das ganze 
ist sogar ziemlich genau.
Nun das hoffentlich letzte Problem.

Daten:16MHz Quarz, prescale 1 ab 400, 16 bit timer
Man muß zwei mal toggeln um eine Periode zu generieren das ist klar.
Bei 5 KHz sind das 10000 Wechsel. Da der Timer aber nur Ganzzahlen Frist 
ist die Auflösung bei 5 KHz pro zahl 2,5 Hz. Gibt es eine Möglichkeit 
das genauer zu bekommen.

von Karl H. (kbuchegg)


Lesenswert?

Manchmal frag ich mich schon warum der Rest des Forums
sich eigentlich den Mund fusselig redet. (Äh: die
Finger wund tippt)

Benutze den CTC Modus des Timers und du kannst das
alles lösen. Auf einem Mega8. Und der fadisiert sich
dabei noch und kann nebenbei noch teuflisch schwierige
quadratische Gleichungen lösen.

CTC = Clear Timer on Compare

Du lässt den Timer laufen und stellst den Endwert ein.
Wenn der Timer den Endwert erreicht hat, toggelt er
den Pin und setzt sich selbst auf 0 zurück.
Und das alles in Hardware. Du brauchst nichts tun.
Du musst nur den Timer richtig konfigurieren und den
gewünschten Endwert einstellen, den Rest macht der Timer
ganz alleine.

von Peter D. (peda)


Lesenswert?

Ciesla tim wrote:

> Daten:16MHz Quarz, prescale 1 ab 400, 16 bit timer
> Man muß zwei mal toggeln um eine Periode zu generieren das ist klar.
> Bei 5 KHz sind das 10000 Wechsel. Da der Timer aber nur Ganzzahlen Frist
> ist die Auflösung bei 5 KHz pro zahl 2,5 Hz. Gibt es eine Möglichkeit
> das genauer zu bekommen.


Ja, das geht bei diesem Prinzip nicht anders:

16MHz  2  1600 = 5000Hz
16MHz  2  1599 = 5003Hz

D.h. Du hast bei 5kHz etwa 3Hz Schritte.

Allerdings kann man tricksen, indem man bei jedem Compareinterrupt nen 
anderen Comparewert lädt entsprechend dem Fehler.

Dann ist zwar ne einzelne Periode auch nicht genauer, aber im Mittelwert 
über mehrere Perioden wirds besser.


Peter

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.