PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : atmega als variabler rechteckgenerator ?



kolisson
15.01.2008, 15:27
hallo ihr,
da ich die letzten wochen weniger mit atmel und bascom gearbeitet habe und vielmehr mit analoger elektronik habe ich gerade eine art kreative blockade, was den atmel angeht.

ich benötige einen rechteckgenerator mit variabler frequenz (im bereich 400khz bis 600khz).
es würde reichen, wenn ich die frequenz in 10khz (oder evt 5khz) schritten variieren könnte.
das tastverhältnis sollte so bei 50% liegen.

spontan denke ich da natürlich an hardware-pwm und / oder timer/counter.

zur verfügung habe ich mega8 und mega 88.

hat einer von euch da vielleicht mal den entscheidenden hinweis, mich auf die richtige fährte zu bringen.

gruss klaus

Andree-HB
15.01.2008, 15:59
...vielleicht einfach so :


dim a as word 'je kleiner, je höher die Ausgabefrequenz

do
waitus a
toggle Portx.x
loop
end

kolisson
15.01.2008, 16:59
klar...
das geht als "quick and dirty" lösung.
aber wie geht es elegant ?

mit dieser schleife kann man ja mit dem prozessor sonst nix mehr machen, ohne den rechteck zu gefährden.

gruss klaus

stefan_Z
15.01.2008, 21:49
Hmm vielleicht ne Hardware-PWM mit 50/50 duty-cycle?
Oder eigene Routine mit ISR...

nikolaus10
16.01.2008, 09:34
Timer-Interrupt ?

oberallgeier
16.01.2008, 10:04
Genau, Timer-Interrupt.

a) (Irgendeinen) Timer auf Interrupt im CTC-modus initialisieren. So nach dem Muster (hier für den mega168, in C, weil ich kein Basic mache):


TCCR0A |= (1<<WGM01); // Timer im CTC-Mode, Top=OCRA (doc S104)
TCCR0B |= (1<<CS01); // Prescaler 1/8 / Clock <- CPU (doc S106)
OCR0A = 125; // Preset 125 für 50µs bei 20Mhz
TIMSK0 |= (1<<OCIE0A); // Tmr/Cntr0 CompareA interrupt enabled
und dann - z.B. auf Tastendruck, den Vorteiler auf einen entsprechenden Wert setzten und den Preset OCRnx:

OCR0A = 125; // Preset 125 für 50µs bei 20Mhz
TIMSK0 |= (1<<OCIE0A); // Tmr/Cntr0 CompareA interrupt enabled
Dann kommt am entsprechenden Pin Deine gewünschte Frequenz (wenns richtig initialisiert ist). Und Du kannst das mit OCIEnx auch bei Bedarf aus- und wieder einschalten.

Viel Erfolg,

chr-mt
16.01.2008, 11:06
dim a as word 'je kleiner, je höher die Ausgabefrequenz

do
waitus a
toggle Portx.x
loop
end

Geht nicht, da waitus keine Variablen zulässt, im Gegensatz zu waitms.

Gruß
Christopher

kolisson
20.01.2008, 19:39
danke für die antworten. irgenwie klappt das nicht immer mit der emailbenachrichtigung, wenn man antworten bekommen hat. insofern lese ich das erst jetzt.

muss ich jetzt erstmal drüber nachdenken, was oberallgeier da schrieb.

also dann bis später wieder.

gruss klaus

kolisson
21.01.2008, 01:54
sooooo. nun habe ich mir das mit dem ctc mal angesehen und möchte mal nachhören,
ob ich das so richtig sehe.

sagen wir mal ich hätte nen takt von 8mhz.

sagen wir mal der prescaler wäre auf 1.

laut der formel im datenblatt kann ich je nach inhalt des OCRnx registers
minimal durch 2 teilen und von hier an in 2er schritten steigend (also 2..4..6..8 usw.)

bei einer teilung von 20 (also OCRnx=9) hätte ich 400khz.
bei ocrnx=8 hätte ich dann eine teilung von 18 ..das entspricht 444khz.

also 1 schritt = 44khz

um also die gewünschte auflösung von etwa 10khz zu erreichen müsste ich den mega dann wohl mit 35,2mhz takten, was nicht geht.

wenn ich hier also jetzt keinen denkfehler drinne habe, ist die idee von oberallgeier für meine zwecke nicht geeignet.

trotzdem danke ich für den denkanstoss. da konnte ich mich mal wieder mit einem unbeachteten kapitel des datenblattes beschäftigen.

gruss klaus

oberallgeier
21.01.2008, 08:50
Hallo Klaus,


... habe ... das mit dem ctc mal angesehen ...Das gibt schon mal einen Pluspunkt (psssst - nicht weitersagen: ich habe immer wieder Dinge abgeschrieben und ans Laufen bekommen ohne sie zu verstehen - aber meistens hinterher versucht, das Getane zu verstehen).


... nachhören, ob ich das so richtig sehe ...
Vermutlich ist es doch etwas anders - und auch anders beschrieben.

Wir schauen und das mal an. Nehmen wir also mal das doc2545 für den mega48/88/168, bei mir steht drauf Rev. 2545M–AVR–09/07 - also aktuell seit letztem September. Gehe nach S 96, Punkt 14.7.2 Clear Timer on Compare Match (CTC) Mode.

In Clear Timer on Compare or CTC mode (WGM02:0 = 2), the OCR0A Register is used to manipulate the counter resolution.
Und GENAU das ist der Trick bei der Geschichte: Manipulation der Zählerauflösung - der zweite Trick ist der Prescaler. Mal der Reihe nach - so Schritt für Schritt.
i) Mit dem Prescaler teilst Du die Controller Frequenz auf eine Frequenz, die Dir angenehm ist - kommt noch.
ii) Mit dem Preset (so nenne ich den Inhalt im OCRnx) - nehmen wir mal an, im OCR0A, also das OCRnx für den Timer/Counter0 - setzen wir nun einen Wert in das Register, bis zu dem NACH dem Prescale der Counter hochzählt - um danach wieder auf Null zu kommen. Das siehst Du ganz genau in diesem Bild. Da sind die Counterstände bei unterschiedlichen OCR0A-Werten gezeigt. Und wenn der Wert erreicht wird, gehts runter auf Null (mit Interruptmöglichkeit und allem). Und jetzt ist es doch klar: großer Presetwert - lange hochzählen, kleiner Presetwert - kurz hochzählen. Oder: kein Prescale - dann wird schnell hochgetackert - mit Prescale entsprechend langsamer.

. . . . . . . . http://oberallgeier.ob.funpic.de/14-5-CTC.jpg

Was hat das für Konsequenzen?

. . . . . . . . http://oberallgeier.ob.funpic.de/10kHz.jpg

Bei Deinem mega88 mit 8 MHz OHNE Prescaler wird der Counter mit 8 MHz hochgezählt. Wenn Du da 10 kHz erreichen willst, dann musst Du 10 000 mal bis 800 zählen - das geht aber nun nicht in den Timer0 hinein :(, denn das ist, siehe Seite 138, ein “8-bit Timer/Counter0 with PWM”. Bähhhh. Also teilen wir den Prozessortakt mit dem Prescaler 1/8 - und erhalten einen Takt von 1 MHz, mit dem der Counter hochgetackert wird. Für 10 kHz müssen wir wieder 10 000 mal, diesmal aber nur bis 100 zählen - das ist ein Wert der unter 255 liegt - also mit 8 bit definierbar. Und Du siehst auch gleich, was der Zweck des Presets im OCR ist! Steht auch hier, auf S 96: "The OCR0A defines the top value for the counter, hence also its resolution." Wenn Dieser Presetwert erreicht wird, gibt der Counter auf - wird auf Null gesetzt, setzt ein Interruptflag und kann auch den Pin OC0A toggeln (steht auch auf S 96), also Pin 12 bzw. PD6. Wir sind also im CTC-Output Mode A.

Das Excel-blatt für DEINEN Fall mit den 10 kHz habe ich Dir oben dazugegeben. Du kannst nun - wenn Du willst - diesen CTC-Modus (genauer gesagt: den Interrupt) ein- und ausschalten. Dazu wird im Timer/Counter0 Interrupt Mask Register = TIMSK0 das Bit OCIE0A - OC Interrupt Enable 0A - gesetzt oder gelöscht. Und wie oben beschrieben - mit dem Preset kannst Du die Frequenz verstellen. Für das Erreichen einer bestimmten Frequenz kann es erforderlich sein Prescale UND Preset zu ändern. Und manche Frequenzen bekommt man halt nicht genau hin.

Ist das so besser erklärt ? Versuch es mal - bau Dir eine ISR in der Du Deine 10 kHz von 10000 runterzählst und beim Nulldurchgang eine LED toggelst. Dann wird die eine Aktiv-Pausen-Zeit von 1s/1s haben.


wenn ich hier also jetzt keinen denkfehler drinne habe, ist die idee von oberallgeier für meine zwecke nicht geeignet.Vielleicht ist sie doch geeignet - die Idee?

kolisson
21.01.2008, 10:57
hallo oberallgeier,

schön, dass du dir soviel mühe machst.
jetzt habe ich deine letzte mitteilung nochmal mehrfach rauf und runter gelesen und denke ich verstehs nicht bzw. wir meinen vielleicht beide das gleiche ohne es zu merken.

um evt. missverständnisse zu beseitigen... hier nochmal meine erklärung:

1. was ich suche ist ein rechteckgenerator, den ich beginnend ab ca. 400khz in schritten von etwa 10khz erhöhen kann. die obergrenze kann bei etwa 600khz liegen.

2. im datenblatt gibt es eine formel die besagt:
http://farm3.static.flickr.com/2155/2209186106_21d0749efe_o.jpg

wenn ich diese formel nun anwende mit der zielsetzung 400khz zu erzeugen (bei einem cpu-takt von 8mhz) dann stelle ich fest, dass ich den prescaler auf 1 lassen muss und das, was du dann preset nennst, stelle ich auf 9 ein.

dadurch ergibt sich nach einsetzen der werte in die formel ein ausgangssignal FOCnx von 400khz (also eine teilung der 8mhz durch 20).

die nächst höhere frequenz ergäbe sich ja durch reduzieren des preset um 1. der preset wäre also bei 8. eingesetzt in die formel sehe ich hier eine ausgangsfrequenz von 8mhz / 18 = 444444hz.

mein ziel wäre aber 410000 (ungefähr) gewesen.
diese könnte ich meiner meinung nach nur erreichen, wenn der systemtakt bei 35,2 mhz liegen würde.

das problem liegt also daran, dass bei dem gewünschten frequenzbereich keinerlei spielraum für preset und prescaler bleibt.

was meinst du ? meinen wir das gleiche ?

gruss klaus

oberallgeier
21.01.2008, 13:38
Hallo kolisson,

Du hast natürlich völlig recht. Ich hatte in Deiner Eingangsfrage Deine Aufgabe unsauber gelesen, hatte einfach das
... variabler frequenz (im bereich 400khz bis 600khz) ... in 10khz (oder evt 5khz) schritten variieren ...überlesen.

Du hast bei dieser Vorgaben bei den 8 MHz nur wenige "Treffer" die unter 2 % Fehler bleiben. Selbst bei 10 % Abweichung wird das nicht ausreichen.

Ich hätte die Aufgabe besser lesen und diese einzelnen Frequenzen durchrechnen sollen. :(. Sorry.

kolisson
21.01.2008, 15:34
@oberallgeier

das ist ja eine gute und eine schlechte nachricht auf einmal:

die schlechte ist, dass ich deinen vorschlag für meine derzeitige sache nicht verwenden kann.

die gute ist, dass ich nicht unter vitaminmangel leide und meine bedenken doch einen sinn machten. ich hab wirklich gedacht, ich seh den wald vor lauter bäumen nicht.


davon ab kenne ich jetzt den ctc und werde diesen bestimmt mal spontan irgendwo einsetzen.

gruss klaus