Hallo allerseits,
ich möchte einen Rechteckgenerator bauen, welcher in 0.1 µs Schritten
einstellbar sein soll. Also Pulsdauer minimal 2µs in 0.1µs Schritten
verlängerbar, den Rest der Periode ebenfalls in 0.1µs-Schritten
einstellbar.
Die niedrigste Frequenz soll bis unter 1 Hz reichen können, daher
reichen 16-Bit-Timer von µC leider nicht aus.
Ich habe bisher 2 Möglichkeiten versucht, welche beide nicht das
gewünschte Ergebnis brachten:
1. Ein AVR, mit 10MHz getaktet, nutzt seinen 16Bit-Timer für die
Pulserzeugung. Wenn die Periode größer als 16 Bit wird, wir Genauigkeit
geopfert, die Zählwerte werden dann durch die Größe der Vorteiler
geteilt. Klappt ganz gut, leider wird das ganze etwas hakelig, wenn man
bei wechselnden Werten durch verschieden große Vorteiler geht.
2. 6 Schieberegister 595 verbunden mit 6 Zählbausteinen 40103. Die
Verdrahtung ist ätzend und dauert mehrere Stunden. Da jeweils 3 40103er
kaskadiert sind (Zerodetect schaltet gleichzeitig Clock und Enable beim
nächsten Baustein) kommt beim dritten Baustein kein verwertbares Signal
mehr heraus (das active-low Signal kommt nur bis auf 2.5V runter).
Überlegt habe ich mir, auf einen kleinen ARM aufzurüsten, der hat laut
Datenblatt 32Bit Timer und taktet auch schneller als 10MHz. Oder aber
FPGA, wobei die mit sowas ja doch eher unterfordert sind und ich sonst
keinen Einsatzzweck für den Einarbeitungsaufwand sehe.
So ein Rechteck mit der Auflösung muss man doch irgendwie auch ohne
großen Aufwand hinbekommen können.
Kann man mir einen Tipp geben, wie man das Problem am besten löst?
PS: Bei der Beitragserstellung bin ich hier im Forum auf so Bauteile wie
AD9833 gestoßen, die ja eigentlich genau das geforderte machen, nur ließ
sich weder in den Beiträgen noch im Datenblatt klar ersehen, ob die
Pulsbreite separat einstellbar ist.
Bei Werten >65536 nimmst Du einfach noch einen Interrupthandler, der
dann in Software weiterzählt.
Und solange dieser Softwarezähler nicht den gewünschten Wert hat, wird
die Flanke für das nächste Compare nicht geändert.
Du mußt nur darauf achten, daß zwischen Interrupt und Compare genügend
CPU-Takte liegen, damit das Compare nicht vor dem Umschalten der
Flankenrichtung erfolgt. Dazu muß man eventuell etwas rechnen.
Peter
Beispiel für einen 16-bit Zähler auf einem µC:
Ein wenig pseudocode nenne ich es mal ;)
Für deine Zahl, nehmen wir mal 200.000.
uint32_t max = 200000;
jetzt teilen wir die Zahl auf und setzen das Compare-Register des Timers
auf uint16_MAX:
1
uint16_tupperMax=max>>16;// = 0x0003
2
uint16_tlowerMax=max;// = 0x0D40
3
if(upperMax)
4
compareRegister=0xffff;
5
else
6
compareRegister=lowerMax;
7
counterRegister=0;
8
STARTE_TIMER();
Deine ISR könnte jetzt so aussehen:
1
uint16_tupperCount=0;//Hilfsregister
2
ISR(Timer-Overflow){
3
if(upperCount<upperMax){//Solange Hilfsregister kleiner als Zielwert ist, inkrementiere dieses
4
upperCount++;
5
}
6
else{
7
if(compareRegister!=lowerMax){//Wenn das Hilfregister den Zeilwert erreicht hat, muss nun noch der Hauptzähler bis zu sienem Zielwert zählen
8
compareRegister=lowerMax;
9
}
10
else//Haupt- und Hilfszähler stimmen überein, spucke irgendwas aus und fange von vorn an
11
OUTPUT_SIGNAL();
12
upperCount=0;
13
compareRegister=0xffff;
14
}
15
}
Nur als kleine Gedächtnisübung, vielleicht hilft es ja ;)
Beache: Je größer die Datentypen sind, mit denen in der ISR gerechnet
wird, desto länger braucht diese!
Somit sollte man bei kleinen Werten von lowerMax eventuell ein paar
anpassungen vornehmen.
@ Stefan:
Recht hast du. Ich bin kurz davor mir mal ein ARM Eval-Kit besorgen.
Aber wenn man es gerade nicht da hat, dann fällt man doch auf
bestehendes zurück, wenn man "mal eben" was probieren will.
Kann ich mich nicht gegen wehren ;)
Als Eval-Kit kann ich den hier empfehlen:
http://www.watterott.com/de/STM32F4Discovery
Günstig und Gut. Programmer inkl.
Viel Spaß mit d. Cortex! Seit ich die Dinger testweise mal programmiert
habe, will ich kaum noch etwas mit AVRs machen. :-)
Ein CLPD wäre natürlich auch fein, grade wenn man sowas als einzelnes
Bauteil aufstecken kann und muß sich dann nicht weiter kümmern, dass
wäre ja toll.
Ich habe auch erst über ARM nachgedacht, als ich letztens den
günstigsten schon bei einem Euro rum bei RS gesehen habe und ATmegas
kommen erst so ab 5 Euro.
Bleibt dann noch der Einarbeitungsaufwand. Bei dem CLPD wird vermutlich
eine größere Investition fällig, bei ARM zumindest neue
Programmier-Hardware und ein bischen mehr Datenblattlesen.
[http://www.embeddedartists.com/products/lpcxpresso/lpc1769_xpr.php]
hatte ich vor ein paar Wochen schon gebookmarked. Da ist dann zumindest
schon mal die Beschaltung erschlagen.
Stefan schrieb:> Oder du nimmst diesen hier für knapp 2 EUR und du hast es hochpräzise> und einfach:>> http://de.mouser.com/ProductDetail/STMicroelectron...
Der hat zwar mehr Muckies (MIPS) aber die Timer sind auch nur 16Bit.
Das Problem ist damit also nicht einfacher. Er muß immer noch die
restlichen Bits in Software zählen.
Peter
Meiermann schrieb:> hatte ich vor ein paar Wochen schon gebookmarked. Da ist dann zumindest> schon mal die Beschaltung erschlagen.
Ja, die Boliden brauchen immer deutlich mehr, als nur 5V anzulegen und
nen 100nF parallel.
Also erst prüfen, ob sie wirklich das benötigte Feature haben oder ob
man dann nur auf höherem Niveau klagt.
Peter
Nen CPLD und nene Selbstbauprogramer kommt dich unter 10€. Als
Zusatzbeschaltung sind auch nur paar 100nF und ne Spamnnungsversorgung
nötig.
Software ist umsost und wenn du jetzt nicht VHDL lernen willst kannst du
sowas auch Zeichnen als Schematic und direkt flashen.
Peter Dannegger schrieb:> Der hat zwar mehr Muckies (MIPS) aber die Timer sind auch nur 16Bit.> Das Problem ist damit also nicht einfacher. Er muß immer noch die> restlichen Bits in Software zählen.
Hallo Peter,
schau dir das Datenblatt bei st mal etwas genauer an, die Timer bieten
beim Cortex deutlich mehr Funktionalitär als die einfachen Counter beim
AVR :-)
es geht auch mit kleineren Prozessoren:
z.B. lassen sich beim PIC24FV32KA302 2 Stück 16 Bit-Timer zu einem 32
Bit Timer kaskadieren.
PWM kann dann über die kaskadierte CCP-Unit realisiert werden.
Da es getrennte Register für steigende und fallende Flanke gibt lassen
sich auch kleine Tastverhältnisse darstellen wenn die Periodendauer
ausreichend groß für den Interrupt ist.
Gruß Anja
Stefan schrieb:> schau dir das Datenblatt bei st mal etwas genauer an, die Timer bieten> beim Cortex deutlich mehr Funktionalitär als die einfachen Counter beim> AVR :-)
Im Datenblatt steht nur, daß es 16Bit-Timer sind, mehr nicht.
Du meinst vermutlich das Referenzmanual.
Kannst Du mal sagen, wo darin steht, wie man einen Puls mit 32Bit
Auflösung in Hardware erzeugt?
Ich sehe da keine Chance, in den 1096 Seiten auch nur irgendwas zu
finden.
Ich müßte mir wohl die 181 Seiten Timerbeschreibung ausdrucken und
mindestens eine Woche gründlich studieren.
Da bin ich doch deutlich schneller, wenn ich ein bischen Mathematik
betreibe, um die zusätzlichen 16Bit beim AVR in Software zu machen.
Wenn ich sowas sehe, bin ich schon ganz froh, keine 32Bitter
programmieren zu müssen. Das ist in meinem Alter wohl nicht mehr zu
wuppen.
Peter
Pico Oschi schrieb:> Ein kleines CPLD, wie ein Max3064 kann das.
Ja. Beifall meinerseits.
Mich wundert es sowieso schon lange, daß die Schreiber hier in diesem
Forum einen so großen Bogen um programmierbare Logik machen. Von Xilinx
gibt es auch billige CPLD's und dazu noch kostenlose Entwurfssoftware,
mittlerweile haben Altera und Lattice nachgezogen, d.h. man bekommt von
denen ein kostenloses Keyfile für 1 Jahr.
Was treibt die Fummelfriede also immer noch dazu, solche nach Hardware
schreienden Aufgaben wie einen in 100 ns Schritten einstellbaren
Pulsgenerator partout mit einem dafür nicht geeigneten Microcontroller
basteln zu wollen?
Einen ähnlichen Nonsense kann man sehen bei den Leuten, die sich mit nem
Atmel AVR unbedingt ein DDS basteln wollen, mit nur 8 Bit
Amplitudenauflösung, wo es doch einen billigen DDS von AD gibt, der mit
25 MHz Takt Sinus, Dreieck und Rechteck mit 10 Bit Auflösung und 24 Bit
Phasenakku gibt? Bastelfieber? Verblendung? AVR-Scheuklappen? Ignoranz
oder Beschränktheit?
Es gibt ja hier auch immer wieder Leute, die partout zum
Temperaturmessen per PT100 als erstes eine Konstantstromquelle und dann
eine umfängliche Analogelektronik mit Brücken, OpV's usw. bauen wollen,
anstatt ihr Geld in einen billigen SigmaDelta-ADC und einen
Metallfilm-Widerstand zu investieren. Wozu schreiben sich die
ApplikationsIng's bei Microchip & Co. die Finger wund, wenn ihre guten
Ideen so gänzlich von unseren höchst selbstbewußten Jungingenieuren
ignoriert werden? Sind die Elektroniker in Deutschland so sehr verblödet
oder sind sie auf ihren Hasenschulen nicht gebildet, sondern nur
dressiert worden? Ich denke da an Leute, die sich unendlich scheuen,
in ihrem Programm ne Marke zu setzen und dann ein goto hinzuschreiben?
Stattdessen wird dann while(1){ .... } geschrieben, bloß weil ein
verkalkter Professor seinen Studenten mal eingetrichtert hat, daß man
'goto' nicht benutzen soll.
ach... bähhhhhh.. ich nehm zum Trost auf den Abend noch nen Schluck "El
Dorado" 15 jährig aus Guayana.
W.S.
Peter Dannegger schrieb:> Kannst Du mal sagen, wo darin steht, wie man einen Puls mit 32Bit> Auflösung in Hardware erzeugt?
Naja, man kann das Eventsystem benutzen, um einen 2.ten Timer vom ersten
zu triggern, geht auch bei den XMegas. Aber mit ein bisschen Software
lässt sich auch ein 8 oder 16 bit Timer auf beliebige Länge dehen. Mehr
Probleme sehe ich beim Jitter, da der Interrupt oft mal nen Zyklus
später kommt, wenn der AVR gerade einen 2-cycle Befehl abackert.
Und ich schlage auch vor, statt 10Mhz einfach 20Mhz Takt zu nehmen,
vorausgesetzt, der AVR läuft mit 5 Volt. Dann hats einfach ein bisschen
mehr Luft. Reload sehr früh im IRQ machen, dann sollte es klappen.
W.S. schrieb:> while(1){ .... } geschrieben, bloß weil ein> verkalkter Professor seinen Studenten mal eingetrichtert hat, daß man> 'goto' nicht benutzen soll.
Zugegeben, 'goto' nehme ich nicht oft, aber ein schönes 'break' in einer
unendlichen Schleife hat schon was, hehe.
Matthias Sch. schrieb:> Mehr> Probleme sehe ich beim Jitter, da der Interrupt oft mal nen Zyklus> später kommt, wenn der AVR gerade einen 2-cycle Befehl abackert.
Es gibt keinen Jitter. Der Interrupt zählt eine Variable und schaltet
dann zwischen Set-on-compare und Clear-on-compare um. Und dazu hat er
bis zum nächsten Compare Zeit, wo dann der Pin auf den Zyklus exakt
umschaltet.
Ein ganz kleines bischen tricky ist es nur, wenn man kleine Pulse mit
großem Abstand erzeugen will, z.B. 2µs alle 200000,1µs.
Dann muß man die 2µs im Interrupt bleiben, da 20 CPU-Zyklen zu wenig
sind, um den Interrupt zu verlassen und wieder zu betreten.
Und bis zu 65536 Zyklen Periodendauer braucht man erstmal garkeinen
Interrupt, das macht dann die Fast-PWM alleine.
Als AVR wäre der ATtiny2313 geeignet, die beiden Zahlen kann man z.B.
per UART eingeben.
Peter
W.S. schrieb:> Was treibt die Fummelfriede also immer noch dazu, solche nach Hardware> schreienden Aufgaben wie einen in 100 ns Schritten einstellbaren> Pulsgenerator partout mit einem dafür nicht geeigneten Microcontroller> basteln zu wollen?
Du hast ja so recht.
Kurz mal 3 Gehirnwindungen auf Betriebstemperatur bringen, ist ja total
uncool. Wer will denn heutzutage schon nachdenken. Dann verpaßt man
vielleich noch ne blödmachende Gerichtsshow im TV.
Nein, man nimmt das größte Device, was man finden kann, und sucht dann
nach ner passenden Lib im Web.
Peter
Nach mehr als 40 Jahren sollte man nicht mehr ohne größte Not goto
nutzen ([http://en.wikipedia.org/wiki/Considered_harmful]).
Also ich bin bereit FPGAs zu nutzen, nur fehlt mir die konkrete
Anwendung und ein 24Bit-Timer, ggf. mit Schieberegister zu Befüllung,
ist keine Indikation für FPGAs. Die suche nach der richtigen Familie und
dem passenden Eval-Board waren schon schwer genug und Informationen im
Netz, wie man später mal Anwendungen ohne das Board hin bekommt sind
praktisch nicht zu finden.
Ich sehe mich heute mal nach der Entwicklungsumgebung von Xillinx um und
lege mir dann einen CPLD zu. Das entspricht eigentlich meinen
Vorstellungen am ehesten, einfach ein Bauteil das macht was es soll.
Welche Hardware brauche ich dann noch zum Programmieren?
>Ich sehe mich heute mal nach der Entwicklungsumgebung von Xillinx um und>lege mir dann einen CPLD zu.
Mit nem FPGA oder CPLD (oder diskrete TTL, Counter usw) könnte man bis
zu 2,5 ns (!) Auflösung hinkriegen.
Da du aber nur 100ns willst, reicht dafür locker ein uC aus.
Was ist denn mit einem AVR Xmega? der Kann z.B. 2 16-Bit Timer
hardwareseitig zu einem 32 Bit Timer/counter zusammenschalten. Und die
Auflösung ist auch kein Problem
Stimmt, den xmega hatte ich komplett übersehen. Ich dachte immer, nach
AVR kommt ganz von selbst ARM...
Diese Event-Geschichte ist ganz interessant, ich habe mir jetzt mal 5
xmega bestellt (und auch 5 CPLDs). Sehr interessant, dass die 32MHz
takten können, offanbar ganz von selbst und man die Timer an 10MHz
Quarzoszi anhängen kann. Das sollte die Latenz beim Schalten doch
deutlich senken können.
Ich melde die Tage dann nochmal den Fortschritt.
Meiermann schrieb:> Welche Hardware brauche ich dann noch zum Programmieren?
Such mal im Netz nach Xilinx Parallelkabel #2 oder #3. Das Ganze besteht
nur aus zwei simplen TTL-Bustreibern am Parallelport (sofern man den an
seinem PC noch hat). Siehe Anhang. Für CPLD's brauchst du auch nicht die
allerneueste Webpack-Version. Bei mir reicht die 8.xx unter WinXP völlig
aus.
W.S.
Meiermann schrieb:> Das sollte die Latenz beim Schalten doch> deutlich senken können.
Welche Latenz?
Es gibt keine Latenz, das ist ja der Witz an der Compare Match Output
Unit.
Bei 10MHz ist das Signal auf 100ns genau, bei 32MHz eben auf 31,25ns.
Peter
Mit Latenz meine ich die Schaltung des Ports in Software, je nachdem wie
schnell ich in den Interrupt komme und wie viel ich da noch zu
entscheiden habe. Dass der xmega viel direkt in Hardware macht habe ich
schon gelesen, das ist ja auch begrüßenswert.
Parallelport habe ich nicht mehr, auch das Notebook nicht...
"Platform Cable USB" ist das offizielle Gerät? Gibt es eine günstigere
Alternative?
Meiermann schrieb:> Dass der xmega viel direkt in Hardware macht habe ich> schon gelesen, das ist ja auch begrüßenswert.
Alle AVRs haben die Compare Match Output Unit, nicht nur die xmega.
Wenn Du sie nicht nutzen willst, ist das Deine Sache.
Dann bist Du aber ganz weit weg von 100ns.
Es kann ja gerade ein anderer Interrupt bearbeitet werden.
Ein Interrupthandler braucht etwa 50..100 Zyklen.
Also bist Du bei 5..10µs anstatt 100ns.
Peter
Da ich bisher nur zwei Interrupts genutzt habe (einer schaltet aus, der
zweite setzt die neuen Timerwerte und schaltet an) und SPI für den
Eingang an neuen Zählwerten ohne Interrupt im Hauptprogramm betrieben
habe, ist meine 'Latenz' tatsächlich im Rahmen der 100ns.
Die Probleme fangen erst an, wenn ich bei einem Timerwert-Wechsel am
Ende einer Periode Vorteiler dazunehme oder ab-/umschalte. Dann ist
aufgrund der niedrigen Frequenzen (< 153 Hz) auf die Genauigkeit <100ns
nicht mehr so wichtig.
Meiermann schrieb:> Da ich bisher nur zwei Interrupts genutzt habe (einer schaltet aus, der> zweite setzt die neuen Timerwerte und schaltet an)
Warum so umständlich?
Schau Dir mal die Fast-PWM (Mode 14 beim ATtiny2313) an:
ICR1 = Periodendauer
OCR1A = Pulsdauer
Peter
Ok, das sieht elegant aus.
Ich habe im ersten Post wohl nicht so deutlich geschrieben, dass ich
gerne nach jedem Puls neue Pulswerte (Pulsdauer, Periodendauer)
nachlegen können möchte.
Wenn schon ein Pulswert läuft, wie ändere ich denn dann den ganzen Satz
auf einmal ohne Glitch? Wenn ich den Timer dazu anhalte (was ich im
COM1B-Interupt tue), dann könnte ich ja die Einschaltzeit des Puls
erwischen und würde die unnötig in die Länge ziehen.
Olaf
Meiermann schrieb:> Ich habe im ersten Post wohl nicht so deutlich geschrieben, dass ich> gerne nach jedem Puls neue Pulswerte (Pulsdauer, Periodendauer)> nachlegen können möchte.
In dem Fall kann man OCR1A als Periodendauer und OCR1B als Pulsdauer
nehmen.
Diese Register sind gepuffert, d.h man kann sie voreinstellen und der
neue Wert wird erst bei Erreichen von Top wirksam.
D.h. auch da hat man keine Latenz, der Interrupt muß nur irgendwann bis
zum nächsten Top ausgeführt worden sein.
Peter
Meiermann schrieb:> Mit Latenz meine ich die Schaltung des Ports in Software, je nachdem wie> schnell ich in den Interrupt komme und wie viel ich da noch zu> entscheiden habe
DAS MACHT DER TIMER VON SICH AUS.
Deine Entscheidungen kannst du ganz in Ruhe im Interrupt fällen. Du mußt
nur den Timer richtig programmieren.
Peter Dannegger schrieb:> Es gibt keine Latenz, das ist ja der Witz an der Compare Match Output> Unit.
>>> Hallo allerseits,>>> ich möchte einen Rechteckgenerator bauen, welcher in 0.1 µs Schritten>>> einstellbar sein soll. Also Pulsdauer minimal 2µs in 0.1µs Schritten>>> verlängerbar, den Rest der Periode ebenfalls in 0.1µs-Schritten>>> einstellbar.>>> Die niedrigste Frequenz soll bis unter 1 Hz reichen können, daher>>> reichen 16-Bit-Timer von µC leider nicht aus.
Nun gibt es so ein Ding im Dip40 Prozessormodul plug&play:
Trial-Version https://www.dropbox.com/s/tdj4tvq0ytftn58/PGen_demo_d.pdf
für Propeller Chip