Forum: Mikrocontroller und Digitale Elektronik AVR: zwei ISR's blockieren sich


von Holger (Gast)


Lesenswert?

Hallo,

ich möchte mit einem ATtiny13 eine Frequenzmessung über den Pin INT0 für 
externe Interrupts durchführen. Über diesen Pin zähle ich in der 
zugehörigen ISR durch Inkrementieren einer Variable jede positive 
Taktflanke, was auch gut funktioniert. Um gleichzeitig die eigentliche 
Frequenz aus diesen Zählwerten zu bestimmen, nutze ich noch zusätzlich 
Timer0 für Overflow-Interrupts um nach jeder Sekunde die Frequenz zu 
überprüfen, da diese sich in Abhängigkeit eines Sensors ändert.
Nun ist es dummerweise so, dass sich beide Interrupts gegenseitig 
blockieren. Die ISR für den Overflow-Interrupt wird nämlich nicht 
aufgerufen, wenn gleichzeitig im GIMSK-Register der externe Interrupt 
freigeschaltet wurde. Wenn ich das Bit INT0 in diesem Register wieder 
lösche, klappt es mit dem Overflow-Interrupt aber und die zugehörige ISR 
wird aufgerufen.
Weiß vielleicht jemand, wie ich beide ISRs störungsfrei nutzen kann?
Ich habe zwar gesehen, dass in der Interruptvektortabelle, der 
Interruptvektor für externe Interrupts eine höhere Priorität hat, als 
jener für Overflow-Interrupts, aber ich weiß nicht, ob das vielleicht 
die Ursache meines Problems darstellt!

: Bearbeitet durch Admin
von MWS (Gast)


Lesenswert?

Wahrscheinlich hast Du den externen Interrupt als LowLevel, statt als 
Change/Rising/Falling konfiguriert, der löst dann solange aus, wie 
Low-Pegel anliegt, alles andere wird blockiert.

von Thomas E. (thomase)


Lesenswert?

Holger schrieb:
> Weiß vielleicht jemand, wie ich beide ISRs störungsfrei nutzen kann?

In meinem Kaffeesatz kann ich sehen, dass der INT0 nicht auf Flanken- 
sondern auf Low-Level-Trigger steht. Wenn mein Kaffee sich also nicht 
irrt, sollte das mit einer Umstellung im MCUCR-Register funktionieren.

mfg.

von Holger (Gast)


Lesenswert?

Leider ist eure Vermutung falsch. Ich habe sowohl ISC00 als auch ISC01 
in MCUCR gesetzt, also Triggerung auf positive Taktflanken.

von Walter (Gast)


Lesenswert?

die übliche Vorgehensweise bei der Fehlersuche ist die:
man reduziert das Programm so lange bis entweder der Fehler verschwindet 
oder bis nur noch ein Rumpfprogramm übrig bleibt dass den Fehler noch 
hat.

Dann schaut man erneut ins Datenblatt ob man alles richtig gemacht hat 
und dann endlich öffnet man einen Thread bei dem man den Fehler genau 
beschreibt UND das Rumpfprogramm im ORIGINAL beifügt.

von MWS (Gast)


Lesenswert?

Holger schrieb:
> Leider ist eure Vermutung falsch. Ich habe sowohl ISC00 als auch ISC01
> in MCUCR gesetzt, also Triggerung auf positive Taktflanken.

Wir mussten nur deshalb vermuten, weil Du Code in Prosa beschreibst, 
anstatt Deinen Teil zu tun und den fehlerhaften Code hier einzustellen. 
Das Einzige, was aus Deiner Beschreibung schlüssig hervorgeht ist, dass 
Dein Code fehlerhaft ist.

von m.n. (Gast)


Lesenswert?

Besser wäre schon gewesen, Dein Programm zu Gesicht zu bekommen!

Die Interrupts kann man eigentlich ganz entspannt nebeneinander 
betreiben, ohne daß etwas blockiert wird. Als Beispiel habe ich ein 
Programm für den ATtiny45 in der 'Schublade', bei dem allerdings PCINT0 
anstatt INT0 verwendet wird: 
http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm#lcd2

Beachte bitte, daß bei ISR (TIMER0_OVF_vect), die nur fürs Ansteuern des 
LCD verwendet wird, und ISR (TIMER1_OVF_vect) das sei() möglichst am 
Anfang der ISR steht. Dadurch wird der globale Interrupt wieder 
zugelassen.
Ich habe es mir abgewöhnt, mit festen Torzeiten zu arbeiten, sondern 
nutze nur noch Programme mit reziproker Messung.

von Thomas (kosmos)


Lesenswert?

besser als innerhalb einer Sekunde alle Flanken zu zählen ist es doch 
einfach die Impulsdauer zu messen und dann die Frequenz zu errechnen.

Timer mit steigender Flanke starten und bei fallender Timerwert 
abspeichern und Frequenz berechnen.

von Holger (Gast)


Angehängte Dateien:

Lesenswert?

Ja, es wäre wahrscheinlich besser gewesen, sofort das Programm 
mitzuschicken.
Anbei nun das auf's Wesentliche reduzierte Programm!
Ich habe meinen eigenen Fehler durch Zufall gerade behoben. Und zwar 
hatte ich die Variable incr vorher als 64-Bit Variable definiert, weil 
ich bis zu sehr großen Werten zählen wollte. Damit ging es 
komischerweise nicht, aber nach einer Änderung auf 32 Bit ging es dann 
plötzlich, sprich die ISR für den Overflow-Interrupt wurde aufgerufen. 
Kann mir vielleicht jemand erklären, warum das mit einer 64 
Bit-Variablen nicht funktioniert?
Dann noch eine allgemeine Frage an m.n. :Was macht es eigentlich für 
einen Sinn in einer ISR das sei() zu setzen. Man muss doch eigentlich 
immer in der main-Funktion das sei() setzen, damit man überhaupt in 
einer ISR eintreten kann, oder?

von MWS (Gast)


Lesenswert?

Thomas O. schrieb:
> besser als innerhalb einer Sekunde alle Flanken zu zählen ist es doch
> einfach die Impulsdauer zu messen und dann die Frequenz zu errechnen.

Kann man so nicht pauschal sagen, für niedrige Frequenzen ist die 
Messung der Periode genauer, für hohe ist der Weg über Torzeit/Zähler 
sinnvoll.

von Walter (Gast)


Lesenswert?

Holger schrieb:
> Kann mir vielleicht jemand erklären, warum das mit einer 64
> Bit-Variablen nicht funktioniert?

evtl. weil die 64-Bit Operationen zu viel Zeit brauchen

> Dann noch eine allgemeine Frage an m.n. :Was macht es eigentlich für
> einen Sinn in einer ISR das sei() zu setzen. Man muss doch eigentlich
> immer in der main-Funktion das sei() setzen, damit man überhaupt in
> einer ISR eintreten kann, oder?

damit wird ein neuer IRQ sofort erlaubt, ansonsten erst nach der 
Rückkehr aus der Interruptroutine

von m.n. (Gast)


Lesenswert?

Holger schrieb:
> Dann noch eine allgemeine Frage an m.n. :Was macht es eigentlich für
> einen Sinn in einer ISR das sei() zu setzen.

Mit Aufruf einer ISR werden automatisch alle Interrupts gesperrt, als ob 
man den Befehl cli() in den Code schreiben würde.
Das sei() gibt nun alle Interrupts wieder frei, sodaß diese nicht 
blockiert werden.
In meinem Beispiel wird ISR (TIMER0_OVF_vect) mit 122 Hz (ca. alle 8 ms) 
aufgerufen und braucht dann einige Zeit, bis sie fertig ist. Nehmen wir 
an, diese ISR würde 0,5 ms brauchen.
Ohne sei() könnten in dieser Zeit keine weiteren Eingangsimpulse gezählt 
werden; als max. Eingangsfrequenz wäre nur < 2 kHz möglich: für einen 
Frequenzzähler völlig daneben!
Mit sei() wird die Impulszählung zugelassen, und die ISR 
(TIMER0_OVF_vect) dafür kurz unterbrochen.

Vor dieser Form der Reduzierung der INT-Priorität haben viele Leute 
panische Angst, da ein neuer Aufruf der selben ISR stattfinden könnte, 
obwohl der alte noch nicht abgeschlossen ist. Betrachtet man aber die 
Zeiten - alle 8 ms werden 0,5 ms benötigt -, so sieht man, daß das nicht 
passieren kann. Wenn ein neuer TIMER0_OVF-Interrupt kommt, ist der alte 
zuverläsig abgeschlossen.

Wenn das Timing enger wird, könnte der neue Aufruf allerdings doch zu 
früh kommen. In diesem Fall schaltet man in der ISR zunächst das IE-Bit 
ab, damit dieser spezielle Interrupt momentan nicht stattfinden kann und 
setzt dann sei(). Ganz am Ende wird dann das IE-Bit zur ISR wieder 
gesetzt.

von Wolfgang (Gast)


Lesenswert?

Holger schrieb:
> Code.txt (779 Bytes, 10 Downloads)

> Ja, es wäre wahrscheinlich besser gewesen, sofort das Programm
> mitzuschicken.

Einen Compiler für die Sprache TXT, bzw. einen, der diese Extension 
verwendet, kennen hier die wenigsten.

Warum verheimlichst du die von dir verwendete Programmiersprache?

von Bastler (Gast)


Lesenswert?

Quizfrage: Und woran erkennt man, was innerhalb des Tiny13 passiert? Und 
wenn man da rein schaut, wieviele Takte nach 255 kommt der nächste 
Overflow?

von MWS (Gast)


Lesenswert?

Walter schrieb:
> evtl. weil die 64-Bit Operationen zu viel Zeit brauchen

Nein, die ISR benötigt mit unsigned 64Bit insgesamt 148 Takte, der 
Abstand zwischen den Aufrufen der T0-OVF beträgt 2048 Takte.

Ein Fehler unter Verwendung eines uint64_t ist im übrigen nicht 
feststellbar.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Moin!

Ich bin mir jetzt nicht sicher, ob ich alles richtig verstanden habe, 
aber warum verwendest du eine ISR um zu zählen? Das kann der ATtiny13A 
(oder ist es wirklich der alte ATtiny13?) doch ganz alleine: Pin T0.

Per ISR könnte man dann sinnvollerweise die Zählerüberläufe zählen. Das 
heißt, die ISR wird nur noch 1/256 mal so oft aufgerufen, was dann kein 
Problem mehr darstellen sollte.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

MWS schrieb:
> Nein, die ISR benötigt mit unsigned 64Bit insgesamt 148 Takte, der

Ist ja Horror. In Assembler kriegt man das locker mit ungefähr 20 Takten 
hin...

von MWS (Gast)


Lesenswert?

Markus Weber schrieb:
> Ist ja Horror. In Assembler kriegt man das locker mit ungefähr 20 Takten
> hin...

Zu spät aufgestanden? Träum' weiter. LOL
Ein LDS/STS kostet 4 Takte pro Byte, mal 8 sind bereits 32 Takte, da ist 
noch nichts inkrementiert, Ein-/Aussprung in die ISR fehlt und Register 
sind auch keine gesichert.

von m.n. (Gast)


Lesenswert?

Markus Weber schrieb:
> Ich bin mir jetzt nicht sicher, ob ich alles richtig verstanden habe,
> aber warum verwendest du eine ISR um zu zählen? Das kann der ATtiny13A
> (oder ist es wirklich der alte ATtiny13?) doch ganz alleine: Pin T0.

Du weißt, wieviele Zähler ein ATtiny13 hat?

MWS schrieb:
> Ein LDS/STS kostet 4 Takte pro Byte, mal 8 sind bereits 32 Takte, da ist
> noch nichts inkrementiert, Ein-/Aussprung in die ISR fehlt und Register
> sind auch keine gesichert.

In Assembler kann man rücksichtslos acht Register (R8 - R15) als 64-Bit 
Variable reservieren. Da muß man dann nichts sichern oder speichern und 
ein Inkrement geht ganz schnell.
64 Bit scheinen mir allerdings angesichts des bald bevorstehenden 
Weltunterganges doch etwas viel zu sein ;-)

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

MWS schrieb:
> Markus Weber schrieb:
>> Ist ja Horror. In Assembler kriegt man das locker mit ungefähr 20 Takten
>> hin...
>
> Zu spät aufgestanden? Träum' weiter. LOL
> Ein LDS/STS kostet 4 Takte pro Byte, mal 8 sind bereits 32 Takte, da ist
> noch nichts inkrementiert, Ein-/Aussprung in die ISR fehlt und Register
> sind auch keine gesichert.

Hast du es mal probiert? Die AVR haben wunderbar viele Register, vor 
allem die nicht so universell nutzbaren Register R0 bis R15 kann man 
recht schön für solche Zwecke verwenden – ohne nennenswerte Nachteile 
für die übrige Funktionalität.

Mal überschlagsmäßig gerechnet:
- Einsprung in die ISR: ca. 5 Takte (ohne RJMP, wenn man die ISR direkt 
an die ISR-Vektor-Position legt),
- SR sichern: 1 Takt,
- Inkrementieren des ersten Bytes per ADD: 1 Takt,
- Addieren für die folgenden 7 Bytes per ADC: 7 Takte,
- Wiederherstellen des SR: 1 Takt,
- Rücksprung per RETI: 4 Takte.

Sind sogar nur 19 Takte, wenn ich mich jetzt nicht verzählt habe.
Falls du die ISR nicht an die Vektor-Position legen willst oder kannst, 
sind es auch nur 21 Takte.

von Thomas E. (thomase)


Angehängte Dateien:

Lesenswert?

Wolfgang schrieb:
> Warum verheimlichst du die von dir verwendete Programmiersprache?

Ich vermute, dass es Wischuell Bräsig ist. Ich hoffe, dir damit geholfen 
zu haben.

mfg.

von Thomas E. (thomase)


Lesenswert?

1
//ISR für Overflow-Interrupt
2
ISR (TIM0_OVF_vect)
3
{
4
  OCR0A = 255;  
5
}
Was soll das?

1
  TCCR0B=(1<<CS01);// Prescaler=8 
2
  TCCR0A=(1<<WGM00)|(1<<WGM01)|(1<<COM0A1);
Der PWM-Ausgang ist nicht eingestellt.

mfg.

von Walter (Gast)


Lesenswert?

Markus Weber schrieb:
> Ist ja Horror. In Assembler kriegt man das locker mit ungefähr 20 Takten
> hin...

vertrittst Du wohl moby?

von MWS (Gast)


Lesenswert?

Markus Weber schrieb:
> MWS schrieb:
>> Markus Weber schrieb:
> Mal überschlagsmäßig gerechnet:
> - Einsprung in die ISR: ca. 5 Takte (ohne RJMP, wenn man die ISR direkt
> an die ISR-Vektor-Position legt),
> ...
> sind es auch nur 21 Takte.

Damit vergleichst Du Äpfel mit Birnen, da diese Aktionen die weitere 
Programmgestaltung einschränkten, welche so nicht entstehen, wenn der 
Zähler im SRam gehalten und die IVT nicht mit Programmcode zugeschrieben 
wird. Bei einem kleinen AVR ist das jedoch machbar und auch 
überschaubar.

Das lenkt aber davon ab, dass es den Fehler, so wie ihn der TE 
festgestellt zu haben glaubt, nicht gibt.

Denn ob nun 150 oder 20 Takte verbraten werden, ist völlig egal, wenn 
2048 Takte als Pause zur Verfügung stehen.

Genauso irrelevant ist's, ob's mit Assembler schneller geht, der TE wird 
einen Grund haben, warum er C nutzt.

Der Antwort, die also von Dir urprünglich kam, entspricht der auf die 
Frage eines Autobesitzers, "was an seinem Wagen defekt ist", die Du mit: 
"Nimm 'nen Roller, damit bist Du schneller" beantwortest.
Du erkennst die Unsinnigkeit dessen?

von MWS (Gast)


Lesenswert?

MWS schrieb:
> Der Antwort, ...

Sowas entsteht dann beim Überarbeiten des Posts vor dem Absenden.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

MWS schrieb:
> Genauso irrelevant ist's, ob's mit Assembler schneller geht, der TE wird
> einen Grund haben, warum er C nutzt.

Du hast Recht. Wenn es so rüberkam, als wollte ich damit sagen, dass 
Assembler für alle Zwecke besser ist als C, bitte ich um Entschuldigung, 
das wäre natürlich Blödsinn.
Ich bin nur erschrocken, was die große Anzahl an Takten dieser ISR 
betrifft. Die Optimierungen, die ich für eine Alternative mit Assembler 
angedeutet habe, lassen sich zu größten Teil auch in C durch 
entsprechende Compiler-Direktiven realisieren. Möglicherweise wäre das 
hier angebracht...

> Der Antwort, die also von Dir urprünglich kam, entspricht der auf die
> Frage eines Autobesitzers, "was an seinem Wagen defekt ist", die Du mit:
> "Nimm 'nen Roller, damit bist Du schneller" beantwortest.
> Du erkennst die Unsinnigkeit dessen?

Dein Vergleich ist gut. :-) Ich greif ihn gleich mal auf und schlage 
vor, statt dem ATtiny13 einen ATtny85 zu verwenden. Der ist weitgehend 
pinkompatibel und hat einen Timer/Zähler mehr.

von m.n. (Gast)


Lesenswert?

Markus Weber schrieb:
> Dein Vergleich ist gut. :-) Ich greif ihn gleich mal auf und schlage
> vor, statt dem ATtiny13 einen ATtny85 zu verwenden. Der ist weitgehend
> pinkompatibel und hat einen Timer/Zähler mehr.

Den hatte ich oben schon im Angebot ;-)
Eine weitere Steigerungsmöglichkeit wäre dann ATtiny44/84 oder 
ATtiny4313 oder ATmega48 oder, oder ...

von c-hater (Gast)


Lesenswert?

MWS schrieb:
> Markus Weber schrieb:
>> Ist ja Horror. In Assembler kriegt man das locker mit ungefähr 20 Takten
>> hin...
>
> Zu spät aufgestanden? Träum' weiter. LOL

DAs solltest du dir selber erzählen...

> Ein LDS/STS kostet 4 Takte pro Byte, mal 8 sind bereits 32 Takte

Ja, das stimmt: Nur in Assembler brauche ich "frequently" genutzte 
Variablen nicht im Speicher zu halten, sondern kann Register dafür 
reservieren, natürlich unter Inkaufnahme der Tatsache, daß der Rest des 
Codes dadurch möglicherweise ineffizienter wird, weil ich sie dann 
dort nicht mehr (universell) verwenden kann.

Ist eine reine Frage des Ergebnisses der Laufzeitanalyse, ob es Vorteile 
bringt und ich habe in Assembler die freie Wahl, meinen Code 
entsprechend dem Analyseergebnis zu organisieren.

Wenn ich also mit einer Aufruffrequenz von, sagen wir mal, 100kHz 
rechnen muß, dann lohnt es nahezu garantiert, dem Zähler acht Register 
zur exclusiven Nutzung zu spendieren, denn das spart 
100.000*32=3,2Millionen Takte in jeder Sekunde oder anders ausgedrückt: 
das Äquivalent eines um 3,2MHz höheren Systemtaktes.

Naja, solange es (ohne signifikante Nachteile) möglich ist, den 
Systemtakt um eben diese 3,2MHz zu erhöhen, muß ich diese Optimierung 
nicht machen. Aber was, wenn doch...

In Asm habe ich die Wahl, in Dummlall-C mußt du tendenziell in Richtung 
GHz-Monster gehen, selbst um so eine triviale Aufgabe zu lösen. Mit 
allen Nachteilen bezüglich Stromverbrauch usw.

Das ist der Hauptvorteil von Assembler: optimal dem Problem angepaßte 
Nutzung der Resourcen der Hardware.

von Peter D. (peda)


Lesenswert?

Holger schrieb:
> Und zwar
> hatte ich die Variable incr vorher als 64-Bit Variable definiert, weil
> ich bis zu sehr großen Werten zählen wollte. Damit ging es
> komischerweise nicht

Welche Compilerversion?
Ältere benötigen für die 64Bit Lib 264Byte SRAM und ~5KB Flash.
Das ist zuviel für den ATtiny13.

Holger schrieb:
> Was macht es eigentlich für
> einen Sinn in einer ISR das sei() zu setzen.

In der Regel keinen, aber es macht oft Probleme.
Nur in sehr seltenen Fällen kann es einen Interrupt minimal 
beschleunigen.

von Bastler (Gast)


Lesenswert?

Wenn man mit einer Interruptrate von 100khz rechnen muß, dann sollte man 
sein Konzept überdenken.

von FelixW (Gast)


Lesenswert?

c-hater schrieb:
> Ist eine reine Frage des Ergebnisses der Laufzeitanalyse, ob es Vorteile
> bringt und ich habe in Assembler die freie Wahl, meinen Code
> entsprechend dem Analyseergebnis zu organisieren.

Ich machs kurz: 
https://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars

Keine Programmiersprache ersetzt die nötigen Kenntnisse dieser.
(sonst gehts wie im Thread "irgendwas mit C++" -_- )

von m.n. (Gast)


Lesenswert?

Bastler schrieb:
> Wenn man mit einer Interruptrate von 100khz rechnen muß, dann sollte man
> sein Konzept überdenken.

Ach nee.
Allein ein Inkrementalgeber kann mit einigen kHz auskommen, in Spitzen 
aber auch einige 100 kHz benötigen. Damit man keine Schritte verliert, 
muß die Routine entsprechend schnell sein.
Mit passendem Konzept geht das auch mit einem AVR.

von m.n. (Gast)


Lesenswert?

FelixW schrieb:
> Ich machs kurz:

Und welche Register sind bei AVR verfügbar?

von Peter D. (peda)


Lesenswert?

Bastler schrieb:
> Wenn man mit einer Interruptrate von 100khz rechnen muß

Über die Anforderungen schweigt er sich ja komplett aus.

Mit dem ATtiny85 könnte man problemlos bis 10MHz messen.

von MWS (Gast)


Lesenswert?

c-hater schrieb:
> DAs solltest du dir selber erzählen...
>
>> Ein LDS/STS kostet 4 Takte pro Byte, mal 8 sind bereits 32 Takte
> ...
> Das ist der Hauptvorteil von Assembler: optimal dem Problem angepaßte
> Nutzung der Resourcen der Hardware.

Du hast jetzt zwar viel geschrieben und es war wie üblich Dein 
Lieblingsthema, also auf den Compiler Deiner Wahl einzuhacken, aber 
tatsächlich war's komplett am Thema vorbei, welches da war, warum eine 
ISR die andere blockieren kann. Es ist in diesem Zusammenhang dann 
unwichtig, ob eine ISR in 20 Takten gelöst werden kann, solange man 
deutlich unter 2048 bleibt, was der Fall war.

Und ob Du dann denkst, da wieder missionarisch tätig sein zu müssen, ist 
auch unwichtig. Denkst Du denn, Du hättest einen Sendungsauftrag, bzw. 
der Gott des ASM hat gerade Dich auserkoren, seine Lehren unter's 
gemeine Volk zu bringen, egal, ob's gerade passt oder nicht?

Und wenn wir schon OT sind: Es gibt genügend Aufgaben, wo Du mit ASM 
scheitern wirst, nämlich dann wenn's um Strukturen und Werkzeuge geht, 
welche Dir ein Compiler bereitstellt. Dafür hat der Compiler dann eben 
bestimmte Trade-Offs, welche man mit ASM umgehenden kann, das dann eben 
die direktere Hardwarekontrolle erlaubt.

Was ich allerdings finde, ist dass Deine ständigen Missionierversuche 
niemandem (außer vielleicht Dir eine gewisse Befriedigung) etwas 
bringen. Schau' doch mal über Deinen Topfdeckel hinaus, damit Du 
erkennst, dass alles nur Werkzeuge sind. Diese Werkzeuge haben je nach 
zu bearbeitendem (Soft)Werkstück ihre Vorzüge und Nachteile. Indem Du 
Dich vor dieser Erkenntnis verschließt, tust Du Dir selbst keinen 
Gefallen und bleibst unter Deinen eigenen Möglichkeiten zurück.

von Bastler (Gast)


Lesenswert?

>> Bastler schrieb:
>> Wenn man mit einer Interruptrate von 100khz rechnen muß
>
>Über die Anforderungen schweigt er sich ja komplett aus.
>
>Mit dem ATtiny85 könnte man problemlos bis 10MHz messen.

Ich bezog mich auf den Hater, der Interrupts mit 100khz erwartet. Die 
10MHz willst Du sicher nicht in einem Interrupt hochzähler, oder? Und 
mit mit Konzept überdenken meinte ich z.b. in einem solchen Fall die 
Hardware machen zu lassen, was der Hardware ist.

von Peter D. (peda)


Lesenswert?

Bastler schrieb:
> Die
> 10MHz willst Du sicher nicht in einem Interrupt hochzähler

Nein, dazu hat der ATtiny25 ja den Timer0 Eingang.
Damit ergeben sich minimal 512 Zyklen zwischen 2 Überlaufinterrupts. Das 
ist selbst in C reichlich Zeit für die Behandlung.

Und wenns unbedingt der ATtiny13 sein soll, dann kann man ja den ADC als 
2. Timer für die Zeitbasis nehmen.

: Bearbeitet durch User
von Bastler (Gast)


Lesenswert?

> ... die Hardware machen zu lassen, was der Hardware ist.
 Das meinte ich mit dem besseren Konzept ;-)

von FelixW (Gast)


Lesenswert?

m.n. schrieb:
> FelixW schrieb:
>> Ich machs kurz:
>
> Und welche Register sind bei AVR verfügbar?

Google, dein Helfer (mit dem 'Freund' bin ich vorsichtig):
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind

Auszug:
1
register unsigned char counter asm("r3");
R2-R7 sind gute Kandidaten.

Im Zweifel müssen alle aufgerufenen (auch avr-libc!) Routinen neu 
übersetzt werden!

von FelixW (Gast)


Lesenswert?

m.n. schrieb:
> FelixW schrieb:
>> Ich machs kurz:
>
> Und welche Register sind bei AVR verfügbar?

Google, dein Helfer (mit dem 'Freund' bin ich vorsichtig):
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind

Auszug:
R2-R7 sind gute Kandidaten.

Im Zweifel müssen alle aufgerufenen (auch avr-libc!) Routinen neu 
übersetzt werden!
1
register unsigned char counter asm("r3");

von m.n. (Gast)


Lesenswert?

FelixW schrieb:
> Auszug:
> R2-R7 sind gute Kandidaten.

Danke für Deine Suche, ich hatte erst heute Deine Antwort gesehen.
Wer ihn hat, ist mit einem IAR-Compiler wohl glücklicher. Dort können 
R4-R15 reserviert werden, wobei die Bibliotheken dies schon 
berücksichtigen.

Bastler schrieb:
>> ... die Hardware machen zu lassen, was der Hardware ist.
>  Das meinte ich mit dem besseren Konzept ;-)

Bei ca. 1 Hz Eingangsfrequenz und 1 s Torzeit ergeben sich die 
einstelligen Ergebnisse "0", "1" oder "2". Ob das dann das bessere 
Konzept ist?
Dann doch eher einen internen 8-Bit Timer als Vorteiler arbeiten lassen 
und für die reziproke Messung bei Bedarf dazuschalten.
Mit festen Torzeiten zu messen ist entbehrlich.

von Peter D. (peda)


Lesenswert?

m.n. schrieb:
> Bei ca. 1 Hz Eingangsfrequenz und 1 s Torzeit ergeben sich die
> einstelligen Ergebnisse "0", "1" oder "2". Ob das dann das bessere
> Konzept ist?

Du weißt aber schon, daß man einen MC auch rechnen lassen darf:
f_in = f_cpu * count_in / count_cpu

Damit man für die gewünschte Auflösung auch genügend hohe Counts 
erreicht, läßt man die CPU z.B. 500ms zählen und dann bis zur nächsten 
Flanke des Eingangssignals.

von c-hater (Gast)


Lesenswert?

FelixW schrieb:

> Ich machs kurz:
> https://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars

Hmm... DAS kannte ich noch nicht. Ich wußte, das IAR sowas kann, aber 
ich wußte nicht, daß das auch der gcc kann.

> Keine Programmiersprache ersetzt die nötigen Kenntnisse dieser.

Nunja... Das kann man ja wohl nicht unter "C-Kenntnisse" verbuchen. Das 
sind hochspezialisierte Kenntnisse von konkreten 
C-Compiler-Implementierungen. Das, was entweder garnicht oder erst auf 
Seite 1142 der Doku unter "Sonstiges" dokumentiert ist.

Dazu kommt:

1) gegenüber pure Assembler in den Möglichkeiten massiv eingeschränkt
2) nutzt man die gebotene Möglichkeit, landet man trotzdem oft bei der 
Notwendigkeit, die ISR in Asm schreiben zu müssen
3) die hochgelobte "Portabilität" ist damit mindestens genauso am Arsch, 
als wenn man den Kram gleich in Asm schreibt

Angesichts dessen: Warum sollte ich mir da C antun, wenn ich nicht muß?

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
Noch kein Account? Hier anmelden.