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.
stm32F1-Familie. Such dir etwas aus :-) Die Außenbeschaltung ist minimal und die Programmierung ist in 20 Minuten gemacht.
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_t upperMax = max>>16; // = 0x0003 |
2 | uint16_t lowerMax = 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_t upperCount = 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.
Oder du nimmst diesen hier für knapp 2 EUR und du hast es hochpräzise und einfach: http://de.mouser.com/ProductDetail/STMicroelectronics/STM32F102R4T6A/?qs=sGAEpiMZZMs7zYnFw9eWkoKmtctlryj0 AVR in allen Ehren, aber mittlerweile lohnt es sich echt auch mal über den Tellerrand zu schauen...
@ 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
Meiermann schrieb: > ATmegas > kommen erst so ab 5 Euro. Nö. ATmega48: 1,515 € http://de.rs-online.com/web/p/mikrocontroller/7193966P/ 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.
Ein CPLD ist teurer als ein kleiner uC und kann weniger. Wenn ein uC reicht, warum den nicht nehmen? (Und 16Bit Timer haben fast alle uCs)
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.