Hallo, habe mit einem Attiny25 einen Aufbau zur Verzögerung und Formung von Pulsen: - Das prellfreie Eingangssignal (20-200Hz) geht auf den als INT0 konfigurierten PB2, irq auf fallende Flanke. - In der INT0 Serviceroutine wird für den frei laufenden Zähler 1 das Output compare auf einen Wert von einigen us in der Zukunft vorgeladen und an PORT B1=1 gekoppelt. OC irq wird aktiviert. - In der OC Serviceroutine wird das Output compare auf einen Wert von 250us in der Zukunft geladen und auf PORT B1=0 gekoppelt. - beim 2. Sprung in die OC Routine wird der OC irq abgeschaltet, das Spiel kann von vorn beginnen. Es soll also auf das Eingangssignal zeitverzögert ein 250us langer Puls auf PORT B1 folgen. Zu 99% klappt das auch. Der Puls ist praktisch jitterfrei, aber selten fehlt er. Gemessen mit 50Hz als Eingangssignal und geeigneter Triggerbedingung auf PB1. Nach längerer Suche frage ich mich was einen Interrupt verhindern kann? Ein zufällig parallel aktiver wohl kaum (hab noch parallel Timer 0 mit TOV laufen) Der Timer 1 Überlauf sollte auch egal sein, addiere immer nur per add (ohne Carry) zum timer1 die Verzögerung hinzu und lade die ins Output compare Register. Kann da was schief gehen? Im Moment weiß ich noch nicht ob’s am INT0 oder dem OC liegt, hätte dieselbe Wirkung.
Der Fehler ist in Zeile 42...
Gast
#5865179
> Re: Attiny25 Interrupt wird (selten) ingnoriert
Das ist nicht richtig.
Gast
#5865184
Wäre es nicht effektiver gewesen, das (doch sicher gut) kommentierte Programm auf die betroffenen Funktionen zu reduzieren und hier vorzustellen? Und vielleicht fände sich dann sogar jemand, der das eben mal bei sich laufen lässt (wenn's nicht gerade eine Exotensprache ist).
a) Ich hab vom ATtiny25 keine Ahnung, nur von neueren. b) Source Code wäre hilfreich. c) Funktioniert ein Compare überhaupt, wenn Null im Compare-Register steht und der Zähler auf Null überläuft? Das kann bei dem gewählten Verfahren nach meinem Verständnis ja immer mal wieder vorkommen.
Gast
#5865210
Danke für die beiden letzten Kommentare. - wenns gar nicht anders geht, strippe ich das Assemblerprogramm auf den Rumpf ab und baue stubbs rein damits überhaupt läuft und stelle das hier rein. Aber vielleichts kommt noch die zündende Idee, weil - <Dieter R.>: Compare geht nicht bei Null??? Werde mal im Detail nachlesen, das wäre eine Erklärung.
Gast
#5865221
Im Datenblatt steht keine Ausschlußbedingung für bestimmte Werte. Das ist es nicht. Ich denke es liegt eher am INT0. Begründung: selbst wenn ein Compare warum auch immer verloren ginge, würde es bei der Zählerfrequenz von 62,5 kHz nach 4ms wieder zum Compare Match kommen. Passiert aber nicht. Erst nach 20ms, d.h. nächste fallende Flanke auf INT0 kommt wieder ein Puls.
Gast
#5865228
Wulf D. schrieb: > habe mit einem Attiny25 einen Aufbau zur Verzögerung und Formung von > Pulsen: [...] Das Konzept ist falsch. Es behandelt nicht die möglichen Glitch-Situationen. Daher vermutlich auch nicht dein Code... Du musst dir in allen Konsequenzen klarmachen, dass der Timer (samt seiner OC-Ausgänge) frei laufende Hardware ist, die sich einen feuchten Dreck darum schert, was du an Interrupts enabelst oder sperrst. > Nach längerer Suche frage ich mich was einen Interrupt verhindern kann? Irgendwelche verhinderten Interrupts sind hier sicher nicht das Problem. Das Problem ist mit an Sicherheit grenzender Wahrscheinlichkeit die Timer-Hardware bzw. genauer: die Tatsache dass diese mit dem INT0-Interrupt in keinster Weise synchronisiert ist und deine (nur versuchte) Synchronisation in der INT0-ISR eben offensichtlich nicht für alle möglichen Fälle korrekt ist. Man kann sowas lösen (auch auf Basis deines Konzeptes), aber das erfordert Assembler-ISRs. Aber selbst, wenn man sowieso in Assembler programmiert, versucht man derartig zeitkritische Konstrukte zu vermeiden, wann immer möglich. In deinem Fall ist das relativ einfach durch Änderung des Konzeptes der Timernutzung möglich (sprich: Start von 0 in der ISR von INT0). Die einzige Gegenanzeige wäre: der Timer steht dir nicht exklusiv zur Verfügung, sondern wird mit anderem Code geshared und muss deswegen immer durchlaufen. Dann ist der einzige Ausweg tatsächlich Assembler.
Gast
#5865252
Die Glitch-Situation würde ich gern erkennen. Sehe die leider nicht. Mir ist vollkommen klar, dass die Hardware nichts unterschlägt. Ich könnte den Timer tatsächlich im INT0 bei $00 starten, würde mich dabei aber ein wenig im knappen 8-Bit Wertebereich einschränken oder alternativ Jitter durch die SW-Steuerung des Timers auf die Pulslänge bringen. Ich hänge ja zwei OC hintereinander: erst die Verzögerung auf INT0, dann die konstante Pulslänge von 250us. Durch den völlig frei laufenden Zähler hatte ich bisher kein Jitter. Start bei Null wäre ein Versuch wert. Ach ja, den Winzling codiere ich in Assembler. Viel Code ist es nicht.
Wulf D. schrieb: > Danke für die beiden letzten Kommentare. > > - wenns gar nicht anders geht, strippe ich das Assemblerprogramm auf den > Rumpf ab und baue stubbs rein damits überhaupt läuft und stelle das hier > rein. Aber vielleichts kommt noch die zündende Idee, weil > > - <Dieter R.>: Compare geht nicht bei Null??? Werde mal im Detail > nachlesen, das wäre eine Erklärung. Naja, ich habe gerade einige bemerkenswerte Erfahrungen mit den neueren Series 1 Prozessoren hinter mir und dort insbesondere Timer B. Der macht genau das, was im Datenblatt steht, inklusive aller verschleiernd formulierten Einschränkungen. Im ATtiny25 Datenblatt steht: A compare match does only occur if Timer/Counter1 counts to the OCR1A value. Das kann man durchaus so interpretieren, dass ein Wrap-Around auf Zero keinen Match-Interrupt auslöst. Muss nicht so sein, aber die Formulierung hat mir zu denken gegeben.
Dieter R. schrieb: > Wulf D. schrieb: > > A compare match does only occur if Timer/Counter1 counts to the OCR1A > value. > > Das kann man durchaus so interpretieren, dass ein Wrap-Around auf Zero > keinen Match-Interrupt auslöst. Muss nicht so sein, aber die > Formulierung hat mir zu denken gegeben. Also im Abschnitt steht, dass nur das Zählen zum Compare Match führt und nicht das manuelle setzen des OCR1x und des TCNTx. Für den Nulldurchgang ist der OVFx INT vorgesehen.
Gast
#5865267
Ich bin mir auch sicher, dass ich irgend eine Kleinigkeit übersehen habe. Spitzfindigkeiten fielen mir bisher bei den kleinen AVRs bisher nicht auf. Dein Zitat aus dem Datenblatt bezog ich ausschließlich auf den nachfolgenden Satz: A software write that sets TCNT1 and OCR1A to the same value does not generate a compare match. Wie gesagt, ich schreibe überhaupt nicht in den Timer1 rein. Nutze aber den OCR1A in der Form OCR1A = TCNT1 add Verzögerungswert.
Gast
#5865292
> Viel Code ist es nicht.
Und das Bisschen lässt sich nicht einfach so vorstellen?
Stattdessen wird zwei Stunden lang über hier Irrelevantes diskutiert.
Mein lieber Wulf D., nehmen Sie es mir nicht übel, aber entweder wollen
Sie sich nur die Zeit vertreiben oder Sie haben in einem Aspekt ein
grundlegendes Defizit, nämlich was zielgerichtetes Arbeiten betrifft.
Wulf D. schrieb: > Ich bin mir auch sicher, dass ich irgend eine Kleinigkeit übersehen > habe. Spitzfindigkeiten fielen mir bisher bei den kleinen AVRs bisher > nicht auf. > Probier es aus und mach als Alternative eine Version, die bei Null den Compare-Wert immer auf 1 inkrementiert. Wenn es dann geht, weißt du, dass er Null nicht mag. Es hilft nichts, hier herumzuargumentieren. Ich habe auf die harte Tour jetzt mehrfach lernen müssen, dass die Dinger (Series 1) 1. nicht Bug-free sind, also neben den dokumentieren Errata noch weitere (Plural) besitzen und 2. die Dokumentation selbst durchaus interpretationsbedürftig ist, man könnte das sehr wohl als spitzfindig bezeichnen. Und dann gibt's da noch Sachen (spielt jetzt hier keine Rolle, nur anekdotisch), wo detailliert beschrieben wird, mit welchem Code man etwas initialisieren muss, und in den Errata steht, dass das gar nicht geht. Probieren ergibt, dass es wirklich nicht so geht, aber anders, da muss man aber selbst drauf kommen. Folge: wenn es das dann nicht war, ist es was anderes. Weitersuchen. @S. Landolt: wieso soll das irrelevant sein? Mich interessiert es, obwohl es gerade nicht mein Problem ist. Könnte aber beim nächsten Projekt mein Problem werden, deshalb kann ich hier durchaus was lernen.
Gast
#5865303
Danke euch allen für die Kommentare. Für heute ist Schluss. Kann eure Vorschläge gerade nicht umsetzen, da ich an einem anderen Rechner sitze. Deshalb die Gast-Anmeldung. Morgen nach der Arbeit, nicht vor 20 Uhr - werde ich den Timer immer bei $00 starten. - Den Code posten, falls es noch immer hängt.
Gast
#5865304
> @S. Landolt: wieso soll das irrelevant sein? Dies hier zum Beispiel: > Naja, ich habe gerade einige bemerkenswerte Erfahrungen > mit den neueren Series 1 Prozessoren hinter mir und > dort insbesondere Timer B. Der macht genau das, > was im Datenblatt steht ... Es geht hier um den ATtiny25.
Gast
#5865305
Wulf D. schrieb: > OC irq wird aktiviert. Würde der Code gezeigt, könnte man sehen, ob ein beliebter (Anfänger-) Fehler gemacht wurde, indem das OC-Flag vor Erlauben des Interrupts nicht gelöscht wird. In diesem Fall erfolgt der OC-ISR-Aufruf unmittelbar nach dem Erlauben und die ganze Mechanik geht in die Hose. Deswegen taugt Prosa statt Code auch nichts.
Gast
#5865307
> Deswegen taugt Prosa statt Code auch nichts.
Dem ist nichts hinzuzufügen.
S. Landolt schrieb: >> @S. Landolt: wieso soll das irrelevant sein? > > Dies hier zum Beispiel: > >> Naja, ich habe gerade einige bemerkenswerte Erfahrungen >> mit den neueren Series 1 Prozessoren hinter mir und >> dort insbesondere Timer B. Der macht genau das, >> was im Datenblatt steht ... > > Es geht hier um den ATtiny25. Danke für den Hinweis. Wäre mir sonst gar nicht aufgefallen. Zufälligerweise habe ich allerdings - im Gegensatz zu einem Herrn Landolt - aus dem ATtiny25-Manual zitiert und auf eine dortige Formulierung verwiesen, die einen Hinweis enthalten könnte, warum der Wert Null problematisch sein könnte. Der Rest war Erläuterung zu dem Satz mit "spitzfindig". Lesen bildet, Verstehen ist aber auch hilfreich.
Ich dachte auch ich kenn den Tiny25. Und habe mir gerade 1h um die Ohren geschlagen, um Timer1 als CTC zu benutzen. Sowas bescheuertes - CTC geht nur via OCR1C, bringt aber keinen Interrupt zustande... Warum löst der nicht den TOV1 aus? Muss man dann OCR1A oder B benutzen, was wiederum bedeutet, dass die für eine genaue CTC nicht anderweitig benutzbar sind. Somit die CTC-Funktion ziemlich nutzlos. Muss man nicht verstehen.
Die Register sind schon der Knaller. Deshalb nehme ich auch am liebsten den Tiny10 für kleine Dinge. Kann man alles auf einem Arduino testen und dann eben die Pins ändern, drauf braten und auflösen. Habe allerdings schon lange nichts mehr gemacht.
Gast
#5865347
Hallo, Ich kann mich nur auf das Datenblatt und meine eigenen Programme beziehen. Es steht geschrieben: "Bit 2 – TOV1: Timer/Counter1 Overflow FlagIn normal mode (PWM1A=0 and PWM1B=0) the bit TOV1 is set (one) when an overflow occurs in Timer/Counter1. The bit TOV1 is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively,TOV1 is cleared, after synchronization clock cycle, by writing a logical one to the flag. In PWM mode (either PWM1A=1 or PWM1B=1) the bit TOV1 is set (one) when compare match occurs betweenTimer/Counter1 and data value in OCR1C - Output Compare Register 1C. When the SREG I-bit, and TOIE1 (Timer/Counter1 Overflow Interrupt Enable), and TOV1 are set (one), theTimer/Counter1 Overflow interrupt is executed" Quelle: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf Das lässt vermuten, es wäre in deinem Programm evtl. möglich den PWM Modus zu wählen.
Gast
#5865435
H.Joachim S. schrieb: > Sowas bescheuertes - CTC geht nur via OCR1C, bringt aber keinen > Interrupt zustande... Warum löst der nicht den TOV1 aus? Tut es. Man muss nur das ganze DB lesen, dann kommt man etwa auf sowas:
1 | |
2 | |
Wulf D. schrieb: > Ich bin mir auch sicher, dass ich irgend eine Kleinigkeit > übersehen > habe. Spitzfindigkeiten fielen mir bisher bei den kleinen AVRs bisher > nicht auf. > > Dein Zitat aus dem Datenblatt bezog ich ausschließlich auf den > nachfolgenden Satz: > A software write that sets TCNT1 and OCR1A to the same value does not > generate a compare match. > > Wie gesagt, ich schreibe überhaupt nicht in den Timer1 rein. > Nutze aber den OCR1A in der Form OCR1A = TCNT1 add Verzögerungswert. Und was passiert, wenn OCR1A nach der Addition Null wird? Nachtrag: Das macht ja den Unterschied aus, wenn ich zu Fuß den Zählerwert ins TCNT1 lade und dann beim Nulldurchgang (Deine Verzögerung bzw. die 250 Mikrosekunden) den OV-Interrupt bekomme oder zyklisch beim erreichen des OCR1A-Wertes - wobei der Zähler munter weiterrennt.
Schon lustig, wie lange man um den heißen Brei reden kann, ohne den Brei jemals gesehen zu haben. Ich hab jedenfalls mit dem ATtiny25 immer das hingekriegt, was ich wollte. Bugs habe ich nicht feststellen können.
Uwe D. schrieb: > > Und was passiert, wenn OCR1A nach der Addition Null wird? > Und wo das Problem mit OCR1A=0? Fand im DB keines! Ok, der Brei wird heute Abend serviert. An Bugs im Tiny glaube ich auch nicht. Wird irgend eine Race condition sein.
c-hater schrieb: > Tut es. Man muss nur das ganze DB lesen, dann kommt man etwa auf sowas: Ok, hast Recht, so gehts. Warum man aber für die CTC-Funktion eines der PWM-Bits setzen muss, obwohl es extra ein CTC-Bit gibt, erschliesst sich mir nicht direkt und ist auch nicht besonders logisch. Egal, jetzt gehts, war sowieso eine Ausnahme, dass ich den "besseren" T1 als schnöde CTC missbraucht habe.
Gast
#5866260
H.Joachim S. schrieb: > Warum man aber für die CTC-Funktion eines der PWM-Bits setzen muss, > obwohl es extra ein CTC-Bit gibt, erschliesst sich mir nicht direkt und > ist auch nicht besonders logisch. Da gebe ich dir sowas von vollkommen Recht, das glaubst du garnicht. ;o) Aber unserer beiden Meinungen werden Atmel bzw. Microchip wohl nicht dazu bewegen, etwas an diesem Unsinn zu ändern, der sich bei genauerer Betrachtung zu einer simplen unglücklichen symbolischen Benamsung der Registerbits auflöst. Das PWM-Bit tut alleine nicht, was man bei diesem Symbolnamen erwarten würde, genausowenig, wie es das CTC-Bit tut. Beide sind jeweils nur für Teilaspekte der Sache zuständig, die bei den "richtigen" Timern durch die Timermodi abgebildet werden. Es ist wohl den Entwicklern einfach nur schwer gefallen, für die sich ergebenden vier Timer-Modi wirklich griffige Bezeichnungen zu finden.
Wulf D. schrieb: > Uwe D. schrieb: >> >> Und was passiert, wenn OCR1A nach der Addition Null wird? >> > Und wo das Problem mit OCR1A=0? > Fand im DB keines! > > Ok, der Brei wird heute Abend serviert. An Bugs im Tiny glaube ich auch > nicht. Wird irgend eine Race condition sein. Naja, ich wollte auf folgendes hinaus: Wenn der Timer im CTC Modus läuft, dann kann der Zähler (TCNTn) auf Null zurückgesetzt werden. Da ich den Quellcode nicht kenne, muss ich raten. Vielleicht lässt Du den Zähler ja durchlaufen. Und wenn jetzt OCRnA=0 ist, wird dann ein Interrupt ausgelöst? Lässt sich im Simulator sicher schnell testen.
So, ich habe das Problem stark eingekreist. Es war nicht nötig, den Timer1 im INT0 jedesmal neu zu starten. Das Problem tritt nur auf, wenn der Verzug=1 ist. Null ist ausgeschlossen.
1 | |
2 | |
3 | |
4 | |
Habe die Tabelle, aus der der Verzug entnommen wird, auf min 2 begrenzt und das Problem ist weg. Siehe Oszibild. Blau triggert INT0, violett ist der verzögerte Puls. Die vier Zeilen sind aus der INT0 ISR, siehe unten. Nehme an im Fehlerfall tritt der Compare noch während der INT0 Ausführung auf. Aber warum wird dann die OC ISR nicht sofort dannach aufgerufen? Irgend ein Flag fehlt wohl. Der gesamte Code. Ist zu wenig um zu reduzieren. Nur die tabelleA: fehlt. Läuft noch auf zu niedriger Frequenz, aber das ändert nichts am Grundproblem.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
Gast
#5866503
Ich bin mir unsicher, aber Folgendes fällt mir auf: In INT0_ISR vergehen zwischen 'in tempi,TCNT1' und 'out TCCR1,tempi' 6 Takte: wenn dazwischen TCNT1=OCR1A erreicht wird, wird OC1A nicht gesetzt. 6 Takte von 128, das ist natürlich eher selten. Hier erschließt sich mir der Sinn nicht:
1 | |
2 | |
3 | |
Wozu soll das OCF1A gelöscht werden? Es dürfte doch eigentlich gar nicht gesetzt sein. Abgesehen davon, dass das 'cbr' hier falsch verwendet wird und dass es in TIFR kein OCIE1A gibt, dies hat nur zufälligerweise den gleichen bit-Wert wie OCF1A.
Ja, da könnte was dran sein. Prüfe ich morgen nach. Und du hast natürlich Recht mit dem unsinnigen und auch noch falsch codierten Flag-löschen. War ein hilfloser Versuch, ist schon wieder entfernt. Hatte keinerlei Wirkung.
Gast
#5866578
Meine obige Vermutung war falsch, mit der vorgegebenen Struktur, d.h. durchlaufendem Timer1, klappt es einfach nicht. Aber Folgendes möchte ich vorschlagen, Timer1 ständig rücksetzen, sollte funktionieren: die ersten 5 Zeilen in INT0_ISR ersetzen durch:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Ja, da sind mehrere Sachen unsauber. Wenn TCNT1 schon weiterzählt, kann das Reload auf +1 nicht mehr einen Interrupt auslösen. Ich würde daher T1 anhalten. Oder man macht das Rücksetzen des Vorteilers davor. Und es muß sichergestellt werden, daß im CTC-Mode kein Reload >OCR1C erfolgt. Auch das Löschen von Interrupts ist beim AVR eine Pain, da ein OR sämtliche Flags in dem Register löscht, also auch die von T0. Es geht also nur so:
1 | |
2 | |
Gast
#5866654
Falls jemand mitraten möchte, hier ein reduziertes Programm für das Phänomen: bei Versatz=1 fehlen sporadisch Impulse - warum klappt das Umschalten des 'Comparator A Output Mode' hier nicht, bei Versatz>1 aber durchaus? Ich weiß erstmal nicht weiter.
Peter D. schrieb: > Auch das Löschen von Interrupts ist beim AVR eine Pain, da ein OR > sämtliche Flags in dem Register löscht, also auch die von T0. Die allermeisten haben single bit sbi/cbi, auch der ATiniy25. Einzelne Flags löschen ist also kein Problem. Oliver
Oliver S. schrieb: > Die allermeisten haben single bit sbi/cbi, auch der ATiniy25. Einzelne > Flags löschen ist also kein Problem. Zumindest beim ADC steht, daß das nicht geht: "Alternatively, ADIF is cleared by writing a logical one to the flag. Beware that if doing a Read-Modify-Write on ADCSRA, a pending interrupt can be disabled. This also applies if the SBI and CBI instructions are used."
Oliver S. schrieb: > Die allermeisten haben single bit sbi/cbi, auch der ATiniy25. Einzelne > Flags löschen ist also kein Problem. > Klappt bei den i/o Ports, aber die Timer liegen außerhalb der Reichweite.
S. Landolt schrieb: > Falls jemand mitraten möchte, ... Hey Klasse, läuft das im Simulator? Für mich geht erst Abends weiter, jetzt ist die Arbeit dran. Ich fand deine Erklärung von gestern Abend plausibel. Prüfe ich dann.
Gast
#5866690
> läuft das im Simulator?
Das weiß ich nicht, es läuft hier in "echt". Den Simulator vermeide ich,
wenn es irgendwie geht (und das ist fast immer).
Schau Dir mal: Figure 12-2. Timer/Counter 1 Synchronization Register Block Diagram an. Da der Timer auch mit der PLL laufen kann, sind da Zwischenregister drin. D.h. TCNT1 kann weiterzählen, nachdem Du ihn gelesen hast. Mache mal nach dem Prescalerreset noch 3 NOPs rein, bevor Du TCNT1 liest.
Gast
#5866714
Prima! Mit 2 nops wird es stabil, zumindest soweit ich es auf dem Analogoszilloskop sehen kann.
Gast
#5866731
Sehr schön, wieder was gelernt. Und falls also Wulf D. nicht wie weiter oben beschrieben den Timer1 in INT0_ISR ständig rücksetzen will, so könnte seine Lösung wie folgt aussehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Noch etwas optimiert:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Gast
#5866964
Peter Dannegger kann's nicht lassen:
> Noch etwas optimiert
Kommt der alte Assemblerprogrammierer doch wieder zum Vorschein.
Guten Abend, herzlichen Dank wegen der regen Beteiligung! Habe soeben beide Lösungsvorschläge ausprobiert. Sowohl das Neustarten des Timer1 weitgehend nach dem Codeschnipsel von S. Landolt als auch dem Prescaler-Reset nach der Optimierung von Peter D. Beides funktioniert fehlerfrei, das läßt sich mit dem Digital-Oszi sicher nachweisen. Interesanter Weise sind auch der minimale Abstand von INT0 zu Compare Match auf Port B1 bei beiden Methoden gleich. So ganz habe ich es aber noch nicht verstanden: was verhindert das Auslösen des Interrupts?
Auf Seite 84 des Manuals hast Du dieses Bild: Figure 12-2. Timer/Counter 1 Synchronization Register Block Diagram. Dort wird beschrieben, dass - wie Peter schon schrieb - neben dem Systemtakt auch der PLL als Taktquelle verwendet werden kann. Die Synchronisation kostet je nach Taktquelle Zeit. Die Anzahl der Takte ist dort angegeben. Deshalb solltest Du mit den eingeschobenen NOP warten bis die Register synchronisiert sind. Verständlich geworden?
Gast
#5867407
Es sind zwei Punkte: Bei Verzug=1 kann, in INT0_ISR, TCNT1 schon um ebendieses 1 weitergezählt haben, je nach momentanem Stand des Vorteilers, noch bevor
1 | |
durchlaufen wurde, folglich wird OC1A gar nicht gesetzt. Dies wird verhindert, indem man den Vorteiler zurücksetzt (auf 0), dann hat man 128 Takte Zeit. Bis dieses Zurücksetzen aber im Vorteiler ankommt, vergeht eine gewisse Zeit (2 oder 3 Takte), da beim Timer1 Synchronisationregister zwischengeschaltet sind.
Gast
#5867415
PS: Nochmal deutlicher: es wird kein "Auslösen des Interrupts", sondern das Setzen von OC1A verhindert, folglich kommt gar kein Impuls zustande.
Ja danke euch beiden, ich hab's jetzt! Schönen Abend noch.
Gast
#5867429
Danke, ebenfalls schönen Abend.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.

