Liebe Gemeinde,
stehe Gerade vor folgendem Problem:
Ich werte mit 2 Tiny2313 bei 20 MHz jeweils ein Signal aus. Bei
positiver Auswertung setzt der Tiny einen Ausgangspin High. Nun möchte
ich die Laufzeit von einem High Signal zum nächsten messen. minimale
Laufzeit beträgt ca. 6 us, maximale über eine us. Natürlich will ich das
ganze so genau wie möglich machen ;)
Bis jetzt hab ich das ganze folgendermaßen gelöst: 2 Tinys sind für das
detektieren meiner 2 Signale zuständig und lösen jeweils eine High
Flanke aus, wenn sie das entsprechende Signal detektiert haben. Die
beiden Ausgänge der Tinys hab ich an nen 3ten Tiny gehängt, auf int0 und
int1. In den ISR start ich beim ersten interrupt (0) den 16Bit Timer
ohne Prescaler (1) und stoppe ihn beim zweiten interrupt (1) wieder. nun
lese ich die beiden register aus und schiebe sie einmal nach rechts
(divison durch2, damit hab ich 100ns schritte bei 20 MHz takt). zu guter
letzt gebe ich das ganze auf einem LCD aus.
Nun zu meinem Problem: Das starten und Stoppen des Timers funktioniert,
nur bin ich mir nicht ganz sicher wann ich die ausgabe ans LCD
eingliedern soll. während der ausgabe sollen keine neuen messungen
gemacht werden, also interrupst disabled. Dewegen hab ich die komplette
Umrechnung und Ausgabe in meine ISR von INT1 gelegt. Hierbei komm ich
aber in teufels Küche und krieg nicht das Ergebnis angezeigt das kommen
müsste. Wie kann ich das Teilen durch 2 und das Ausgeben aufs Display so
legen, dass es in der Main Schleife passiert und dabei gleichzeitig die
Interrupts abgeschalten werden, danach aber wieder an? Ich verwende die
im tutorial angegebene Routine zur Ausgabe von 16 bit zahlen. Ich hab in
der ISR nen ganz schönen Hund drinnen, nur ich find ihn nicht.
Danke für die Hilfe,
Max
natürlich ist der längste zu messende Abstand nicht 1 us sondern über
eine ms.
des weiteren sind die variablen in der ausgaberoutine angepasst an
ergebnisL, ergebnisH.
MfG Max
so, nun habe ich das programm ein wenig umgeschrieben.
jetzt werden die interrupts gegenseiteig gesperrt, sprich, es wird
zuerst nur der erste aktiviert, gewartet bis der auslöst, dann in der
isr der erste abgeschaltet und der 2te zugeschaltet, gewartet bis der
auslöst, beide gesperrt und dann den wert auf dem lcd ausgegeben. nach
ausgabe auf dem lcd wieder int0 freigegeben. int0 kommt immer zuerst und
ist meine referenz, der nullzeitpunkt. leider krieg ich immer das
gleiche ergebnis auf dem display und langsam verzweifel ich.
auf der anzeige erscheint immer 6 oder 7, was 12 oder 14 takten
entspricht. diese braucht er genau, um von einer isr in die andere zu
springen. das würde aber bedeuten, dass der 2te interrupt direkt nach
dem ersten ausgelöst wird, und das kann nicht sein. auf dem oszi sind
die beiden signale sauber und mit 20 us verzögerung dargestellt.
hier nochmal der neue code. langsam verzweifel ich und weiß nicht mehr
weiter.
Irgendwo mache ich einen großen Denkfehler nur find ich den nicht. Kann
mir irgendjemand helfen?
swedisch wrote:
> auf der anzeige erscheint immer 6 oder 7, was 12 oder 14 takten> entspricht. diese braucht er genau, um von einer isr in die andere zu> springen. das würde aber bedeuten, dass der 2te interrupt direkt nach> dem ersten ausgelöst wird, und das kann nicht sein.
Doch, genau das wird es sein.
Wer sagt denn, daß das auslösende Ereignis erst nach der Freigabe des
Interrupts erfolgen darf?
Atmels Datenblatt jedenfalls nicht.
Sonst könnte man ja auf Ereignisse nicht pollen.
Daher immer erst das Ereignisflag löschen direkt vor der
Interruptfreigabe, wenn man nicht auf uralte Ereignisse triggern will.
Peter
Danke, das hab ich jetzt mal ausprobiert. In der Tat steht der Interrupt
schon an, während der erste abgearbeitet wird. wenn ich aber am ende der
ersten ISR die Flags lösche, so passiert trotzdem das gleiche. hab
sowohl vor der freigabe vor der hauptschleife das EIFR gelöscht als auch
nochmal am ende der ISR0 routine. klappt beides mal nicht. die flanken
kommen aber definitiv mit 20 us laufzeitunterschied. das sagt mir mein
oszi. irgendwo ist trotzdem der wurm drinnen...
Hallo,
kann mir vielleicht jemand einen Tipp geben, wie ich mit externen
Interrupts debuggen kann? wenn ich das ganze im Simulator durchspiel
läuft es einwandfrei. Da setz ich manuell die Interrupts und das
Programm tut genau das was ich will. sobald ich aber über den Dragen
meinen Tiny im Laufenden Betrieb debug ist es logisch, dass beide
interrupts sofort anliegen, da ich ja nie in dieser kurzen zeit meine
Steps abarbeiten kann. gibts da ne möglichkeit das doch irgendwie
realitätsnah hinzukriegen? wie gesagt im simulator mit manuellem
auslösen der Interrupts geht das einwandfrei. nur nicht aufm tiny. da
springt er immer sofort in die 2te isr. wie der ausgelöst wird ist mir
noch sehr unklar, da da kein signal drauf liegt.
MfG, Max
swedisch wrote:
> Danke, das hab ich jetzt mal ausprobiert. In der Tat steht der Interrupt> schon an, während der erste abgearbeitet wird. wenn ich aber am ende der> ersten ISR die Flags lösche
Ne, nur direkt vor der Freigabe.
Und zum Löschen mußt Du setzen !!!
Das hat irgendein Atmel Witzbold so festgelegt.
Peter
Tausend Dank Peter
genau das war es. Vielen Dank für die schnelle und tolle Hilfe hier. 1a!
Ich war schon kurz vor in die Tonne treten, aber es klappt!
Schönen Mittwoch nachmittag, meiner ist gerettet ,)
Gruß,
Max
ein komisches phänomen hab ich noch:
sobald ich über 1 wirde debugge, die verbindung zum dragon abzieh und
den tiny resete, läuft das programm genau so wie es soll. Wenn ich jetzt
aber übers avr studio den Tiny wieder freigeb für ISP, dann läuft das
Programm nicht mehr.
zeigt nur noch lauter 0en an. Gibts hierfür eine erklärung? Die Zeit die
ich im Debug modus ohne debug messe ist exakt die die rauskommen soll,
bis auf 100 ns genau.
Notfalls lass ich den Tiny einfach im debug modus. nicht schön, aber
geht.
MfG,
Max