Hallo, mal eine dumme Frage: ich bastle gerade an einem programmierbaren Recheckgenerator mit Mega8, LCD 16x2 und drei Tasten, womit die Pulsdauer/Pausendauer in drei Bereichen(usec, msec, sec) mit 000 bis 999 eingegeben werden kann. Die Interface (LCD, Tasten, Puls-/Pausedauer-Eingabe) funktioniert bereits. Würde gerne so ca. 1usec Mindestpulsdauer anstreben (und max. 999sec). Die Zeitbasis wird durch Timer0 mit Prescaler=8 angegeben, Quarz=8Mhz, d.h. jede 1usec habe ich einen Timer0_ovf_interrupt. In der Interruptroutine möchte ich dann die Pulsdauer (und auch die Pause zwischen den Pulsen) mittels Variable hochzahlen und den Puls auf einen Port ausgeben (in der main-Schleife geht das leider nicht, da dort auf andere Ereignisse unbestimmt lang gewartet wird). Nun meine Frage: Ich möchte grob abschätzen, wie viele Instruktionen in der Interruptroutine Platz haben (bzw haben dürfen)? Meiner Meinung nach sind das nicht mehr als 8, weil der Clock ja 8Mhz ist und der Interrupt jede 1usec kommt, ist das korrekt, hm..? Und wie ich das sehe, werde ich wohl kaum innerhalb 1usec alles erzeugen und ausgeben können (Pulsdauer und Pausendauer berechnen, Portausgabe...?) Also ein Impuls mit 1usec Dauer und 1usec Pause werde ich unter diesen Ümständen vielleicht ziemlich ungenau erzeugen, und für 999usec Pulsdauer und 999usec Pause (geschweige denn 999sec!!!) reicht die Bearbeitungszeit von 1usec in der Interruptroutine gar nicht aus??? Wie seht Ihr das, bin für Eure Meinung dankbar, da ich plötzlich Lücken in mein Wissen erkannt habe :))) PS: Unter "usec" meine ich natürlich Mikrosekunde :)) MfG, Emil
Hi! Warum nimmst du nicht OC1A und 16MHz Takt ungeteilt. Das sind min.16 Takte. Die sollten eigentlich reichen um einen neuen Wert einzuschreiben und nebenher ein wenig zu rechnen. Knapp wird es jedenfalls. MFG Uwe
hi uwe: ja, wäre eine mögliche lösung, jedoch ist die bearbeitungszeit, wie du sagst, immer noch knapp; ursprünglich hatte ich vor auch die sec-Zeiten durch 1usec Timebase und Variable erzeugen (weil ich 2 unabhängige ausgänge haben will, der eine gibt z.b. im usec-bereich aus und der andere gleichzeitig im sec-bereich...); d.h im schlimmsten fall wird die Variable bis 999 000 000 (dec) hochgezählt, das sind dann 4 bytes (long int); bin mir nicht sicher, ob so ein long-int-addieren (samt einige "if"s+ausgangsportpin setzen/löschen) auch in 16 takten passt...:(((
Dumme Zwischenfrage, ein CCP-Modul hat der Mega 8 nicht zufällig? Beim PIC funktioniert das dann ungefähr so: - TMR1 (16Bit) läuft frei mit internem Takt oder mit Vorteiler - das Compare-Register (auch 16-Bit) wird mit einem bestimmten Wert geladen - Stimmen jetzt TMR1 und der Inhalt des CCP-Registers überein, dann wird ein Event ausgelöst. Das kann ein Interupt und oder das setzen bzw. Rücksetzen eines Pins sein. Gleichzeitig wird TMR1 zurückgesetzt. Damit könnte man die Timebase immer an die aktuelle Zeit anpassen. 1µs wird so oder so nichts werden, da ja nebenbei auch noch etwas angezeigt werden soll. Der Einsprung in die ISR und der Rücksprung dauert ja auch ein paar Takte (sind beim PIC schon 5..6). Steffen
@Steffen: Doch, so etwas gibt's bei den AVR auch, heißt nur anders. Aber das löst das Problem doch nicht. Wenn Emil in jedem Aufruf der Interrupt-Routine mehr als die zur Verfügung stehenden 1us benötigt, dann hilft das nichts. Gruß, Frank
Doch, helfen könnte es evtl. Beim PIC lässt sich zwar der Pin nicht negieren sonder nur Setzen oder Rücksetzen. Hätte ja sein können, dass der Atmega das kann. Andere Variante währe ein PWM-Modul zu nutzen wenn die minnimale Periode das zulässt. Beim PIC würde sich das mit 1µs realisieren lassen. Dann hätte ich überhaupt kein Problem mehr. Aber warum muss eigentlich unbedingt ein Interupt die Erzeugung übernehmen? Ich würde einfach nur eine Zeitschleife laufen lassen. Das sollte sich doch bis zu 8 Takten realisieren lassen. Der Frequenzgenerator macht ja sowieso die meiste Zeit nichts anderes als die Frequenz zu erzeugen und auf einen Eingabe zu reagieren. Die Eingabe kann dann ja Interuptgesteuert sein. Also Eingabe --> Zeitkonstanten ändern und anzeigen --> in Main-loop Frequenz erzeugen. ... nur mal so als Idee. Steffen
@steffen: deine idee mit der zeitschleife ist übrigens gar nicht schlecht; habe soeben gegoogelt und festgestellt, dass jede menge DDS generatoren mit mikrocontrollern genauso funktionieren-sie erzeugen stets die ausgangspulse in der mein-schleife und lieben überhaupt keine interrupts; ein interrupt bedeutet für sie immer "halt, jetzt kommen die daten, danach geht's wieder los..." also, offensichtlich ist das die richtige methode, schade, dass ich mein ganzes interface umgekehrt (also interruptgesteuert) strukturiert und schon geschrieben habe :((( werde es wohl umschreiben müssen. danke für die hilfe, jungs! emil
Das Signal ist doch periodisch, somit kannst Du bequem die PWM benutzen. Für minimal 1µs Schrittweite muß Dein Quarz 2MHz oder höher sein. Die PWM geht bis 16 Bit. Für größere Zeiten schaltest Du dann den Vorteiler mit ein oder machst es mit Interrupts. Im 999s Bereich muß die Schrittweite ja nicht mehr auf 1µs genau sein. Peter
danke, peter, dies könnte auch die rettung meiner bissherigen arbeit sein, werd' es mir genauer überlegen. mfg, emil
Hi! 16 Takte hast du doch nur bei der kleinsten Zeiteinstellung 1us! bei 2us hast du schon 32 Takte. Mit Vorteiler 8 kommst du ohne zu zucken auf 65535/2 us. Für den Rest kannste ja OC1A abschalten und mit SW takten. Nur mit 1us high und 999s low ist es nicht so einfach. MFG Uwe
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.