Forum: Mikrocontroller und Digitale Elektronik Feedback zu ATtiny24-Prog. gewünscht


von Jan R. (janra)


Angehängte Dateien:

Lesenswert?

Hey!
Der Tiny24, den ich in der Mangel habe, raubt mir die Nerven. Er hat 
einen low-akiven Taster an einem Eingang. Der Port-Pin PB2 hat den 
internen Pull-up aktiviert.

Ich habe eine State Machine programmiert. Der Einfachheit halber habe 
ich zunächst auf zwei Zustände reduziert. Sobald der Taster Low-Pegel 
hat, zuckt INT0 und bringt seine ISR nach vorne und setzt u.a. das Flag 
entsprechend (hier auf 'l'). Wird dieser Zustand wieder verlassen, geht 
es zurück zu 'i'. In main() gibt es dann Fallunterscheidungen 
hinsichtlich des Zustands des Flags.

Ausgangsseitig sind LEDs im Spiel, die je nach Zustand bespielt werden 
sollen.

So weit, so einfach. Nun habe ich ersonnen, daß die LEDs einen 
Nachleuchttimer haben sollen. Der Taster wird kurz gedrückt, die LEDs 
leuchten daraufhin auf und noch'n paar Sek. nach und gehen dann aus, 
Zustand wird auch wieder geändert. Quasi ein Monoflop. Für diese 
Nachleuchtung habe ich den Timer1 ins Boot geholt, der im CTC läuft und 
der von der ISR des INT0 angeschubst wird.

In der Logik kann ich keinen Fehler mehr finden. Trotzdem läuft die 
Kiste kippelig. Nicht-deterministisch. Mal geht alles wie gewünscht. 
Dann wieder bleiben die LEDs am leuchten über den Timeout hinaus, als 
hätte der Timer was vergessen. Dann geht alles beim ersten Druck wie 
gewünscht incl. fristgerechter Dunkelheit, beim zweiten Durchlauf jedoch 
passiert nichts mehr. Und dann nie wieder (bis zum Reset). Ich hatte 
auch schon Timeouts mit 2T.

So, meine frühen Überlegungen gingen nat. in Richtung Entprellung des 
Tasters. Ohne E. müßte das ja alles schrecklich unvorhersehbar und so 
sein. Dann sagte ich mir, daß ich ja durch den INT0 und seine ISR mit 
der sofortigen Sperrung weiterer INT0s schon eine prima Entprellung 
habe. Daran habe ich dann noch etwas getestet, indem ich in die ISR ein 
_delay_ms(120); versuchsweise eingefügt habe (jaja, ich weiß :-). Im 
Ergebnis das gleiche. Prellen sollte nach meinem Ermessen keine negative 
Auswirkung haben.

Meine Bitte an euch: schaut doch mal in den Code. Ist mit dem 
Timer-Config was nicht koscher? Fällt euch an den ISRs und den ganzen 
Setups was auf? Die Register sind ja zahlreich.

Besten Dank und schöne Grüße, Jan.

von Karl H. (kbuchegg)


Lesenswert?

Jan R. schrieb:


> So, meine frühen Überlegungen gingen nat. in Richtung Entprellung des
> Tasters. Ohne E. müßte das ja alles schrecklich unvorhersehbar und so
> sein. Dann sagte ich mir, daß ich ja durch den INT0 und seine ISR mit
> der sofortigen Sperrung weiterer INT0s schon eine prima Entprellung
> habe.

Nö. Hast du nicht.

Nur weil Interrupts gesperrt sind, bedeutet das ja nicht, dass die Pulse 
am Eingang nicht trotzdem registriert werden. Die setzen 
selbstverständlich das entsprechende Flag im Interrupt 
Anforderungsregister und wenn die Interrupts das nächste mal frei 
gegeben werden, kommt der nächste Interrupt-


> Meine Bitte an euch: schaut doch mal in den Code. Ist mit dem
> Timer-Config was nicht koscher? Fällt euch an den ISRs und den ganzen
> Setups was auf? Die Register sind ja zahlreich.

Das kommt mir alles mächtig kompliziert vor.

von Jan R. (janra)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Jan R. schrieb:
>
>
>> So, meine frühen Überlegungen gingen nat. in Richtung Entprellung des
>> Tasters. Ohne E. müßte das ja alles schrecklich unvorhersehbar und so
>> sein. Dann sagte ich mir, daß ich ja durch den INT0 und seine ISR mit
>> der sofortigen Sperrung weiterer INT0s schon eine prima Entprellung
>> habe.
>
> Nö. Hast du nicht.
>
> Nur weil Interrupts gesperrt sind, bedeutet das ja nicht, dass die Pulse
> am Eingang nicht trotzdem registriert werden. Die setzen
> selbstverständlich das entsprechende Flag im Interrupt
> Anforderungsregister und wenn die Interrupts das nächste mal frei
> gegeben werden, kommt der nächste Interrupt-

Ah, verstehe. Dann half natürlich auch das versuchsweise eingesetzte 
Delay() nichts. Der INT kam dann nur später.

>> Meine Bitte an euch: schaut doch mal in den Code. Ist mit dem
>> Timer-Config was nicht koscher? Fällt euch an den ISRs und den ganzen
>> Setups was auf? Die Register sind ja zahlreich.
>
> Das kommt mir alles mächtig kompliziert vor.

Hmja, ich finde die ganze Registerklaviatur des t24 im Vergleich zu 
früheren auch kompliziert. Besonders beim Timer/Counter.

Viele Grüße,
      Jan.

von Karl H. (kbuchegg)


Lesenswert?

> Für diese Nachleuchtung habe ich den Timer1 ins Boot geholt,
> der im CTC läuft und der von der ISR des INT0 angeschubst wird.

Würd ich gar nicht machen.
Ich würde den Timer ständig durchlaufen lassen, der zb alle 100ms seine 
ISR ausführt.

Dazu noch eine globale Variable, die als Countdown-Uhr fungiert.

volatile uint8_t ledAus;

In der ISR dann

ISR( ... )
{
  if( ledAus > 0 ) {
    ledAus--;

    if( ledAus == 0 )
      Led abschalten
  }
}


bei Tastendruck wird einfach ledAus auf 30 gesetzt und 3 Sekunden später 
dreht dann die ISR tatsächlich die LED ab.

(Ich verstehe, dass du deine Taste auf einen INterrupt legst, weil du 
später irgendwann mal einen Sleep-Modus aktivieren willst und der Taster 
den da rausholen soll)

ISR( INT0 )
{
  Led einschalten
  ledAus = 30;
}

Das Prellen ist in dem Fall relativ egal. Ob die Zeit mit dem ersten 
Niederdrücken oder mit dem 3. Preller losläuft, ist auch schon wurscht.

von Peter D. (peda)


Lesenswert?

Jan R. schrieb:
> So, meine frühen Überlegungen gingen nat. in Richtung Entprellung des
> Tasters.

Das wäre der einzig richtige Ansatz gewesen.
Warum hast Du ihn aber nicht weiter verfolgt?

Jan R. schrieb:
> Ohne E. müßte das ja alles schrecklich unvorhersehbar und so
> sein.

Das hast Du nun ja eindrucksvoll bewiesen.


Hier mal ein Beispiel mit Entprellung:

Beitrag "AVR Sleep Mode / Knight Rider"


Peter

von Jan R. (janra)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> Für diese Nachleuchtung habe ich den Timer1 ins Boot geholt,
>> der im CTC läuft und der von der ISR des INT0 angeschubst wird.
>
> Würd ich gar nicht machen.
> Ich würde den Timer ständig durchlaufen lassen, der zb alle 100ms seine
> ISR ausführt.
>
> Dazu noch eine globale Variable, die als Countdown-Uhr fungiert.
[...]
> bei Tastendruck wird einfach ledAus auf 30 gesetzt und 3 Sekunden später
> dreht dann die ISR tatsächlich die LED ab.

Hallo Karl Heinz,
ah, gute Idee. Die hat ggü. meinem on-demand-Timer noch den Vorteil, daß 
der immerlaufende 100 ms-Timer auch ggf. für andere Timeout-Bedarfe 
genutzt werden könnte (mit dann eigenen Variablen, nat.).

> (Ich verstehe, dass du deine Taste auf einen INterrupt legst, weil du
> später irgendwann mal einen Sleep-Modus aktivieren willst und der Taster
> den da rausholen soll)

Genau.

[...]

> Das Prellen ist in dem Fall relativ egal. Ob die Zeit mit dem ersten
> Niederdrücken oder mit dem 3. Preller losläuft, ist auch schon wurscht.

Stimmt. So hatte ich mir das ja auch mit dem INT0 und dem Sperren 
weiterer INTs gedacht, aber nicht berücksichtigt, daß auf jeden Fall ein 
Nachtritt vom während der Sperre gesetzten I-Flag kommt.

Sehr gut, das setze ich mal so um. Dir vielen Dank für Rat und Tat! 
Viele Grüße, Jan.

von Jan R. (janra)


Lesenswert?

Peter Dannegger schrieb:
> Jan R. schrieb:
>> So, meine frühen Überlegungen gingen nat. in Richtung Entprellung des
>> Tasters.
>
> Das wäre der einzig richtige Ansatz gewesen.
> Warum hast Du ihn aber nicht weiter verfolgt?

Hallo Peter,
das hatte zwei Gründe: ich wollte keinen weiteren Timer für die 
Entprellung einbinden, um möglichst wenig im t24 am rennen zu haben 
(Perspektive Strom sparen). Das ist/war aber eher eine 
Bauchentscheidung, berechnet in mW bzw. µW hatte ich das noch nicht. Und 
dann eben die Annahme, mit dem ersten LOW des Pins in der ISR zu sein, 
die weiteres Zappeln des Tasters verpuffen lassen würde.

> Jan R. schrieb:
>> Ohne E. müßte das ja alles schrecklich unvorhersehbar und so sein.
>
> Das hast Du nun ja eindrucksvoll bewiesen.

:-)  Hier mußte ich mehr als grinsen.

> Hier mal ein Beispiel mit Entprellung:
> Beitrag "AVR Sleep Mode / Knight Rider"
> Peter

Den Thread werde ich mir mal ansehen. Besten Dank für den Tip, denn den 
kannte ich noch nicht. Wohl aber andere und vor allem auch die vielen 
sehr guten Artikel, ohne die µC.net nur halb so wertvoll wäre.

Viele Grüße,
    Jan.

von Karl H. (kbuchegg)


Lesenswert?

Jan R. schrieb:

> das hatte zwei Gründe: ich wollte keinen weiteren Timer für die
> Entprellung einbinden, um möglichst wenig im t24 am rennen zu haben

Viele Programme haben einen Timer ausschliesslich dafür abgestellt, im 
Programm eine Zeitbasis zu haben, wobei der tatsächliche Zeitschritt 
(millisekunden) gar nicht mal so wichtig ist, sondern viel wichtiger ist 
es, eine definierte 'Uhr' im System zu haben

So auch beim Entprellen.
Beim PeDa Entrprellen ist es nicht so wichtig, ob der ISR Aufruf 
tatsächlich alle 5 Millisekunden kommt oder nicht. Du hast da viel 
Spielraum, d.h. man könnte die Entprellung und diese Timeout Counter 
ruhig in eine ISR zusammenlegen, die vom selben Timer gespeist wird. Ob 
der Timeout Counter alle 5 oder 10 oder 50 Millisekunden aufgerufen 
wird, ist ja wiederrum nur ein Zahlenwert, der bei der Vorbelegung zum 
Runterzählen interessant ist.
Und wenn dann noch was dazu kommt (systeminterne Uhr oder so was), dann 
kommt das dann eben auch da mit dazu.

Wie gesagt: Einen Timer als interne Zeitbasis, das ist etwas, was sich 
sehr bewährt hat. Wohingegen das ständige Timer-ein, Timer-aus, und wenn 
dieses oder jenes der Fall ist, dann wird der Timer auf 0 gesetzt, etc. 
etc.  ... das wird alles schnell unübersichtlich.

von Jan R. (janra)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Viele Programme haben einen Timer ausschliesslich dafür abgestellt, im
> Programm eine Zeitbasis zu haben, wobei der tatsächliche Zeitschritt
> (millisekunden) gar nicht mal so wichtig ist, sondern viel wichtiger ist
> es, eine definierte 'Uhr' im System zu haben

[...]

> Wie gesagt: Einen Timer als interne Zeitbasis, das ist etwas, was sich
> sehr bewährt hat. Wohingegen das ständige Timer-ein, Timer-aus, und wenn
> dieses oder jenes der Fall ist, dann wird der Timer auf 0 gesetzt, etc.
> etc.  ... das wird alles schnell unübersichtlich.

Ja, das stimmt. Ich habe den Timer mittlerweile auf Dauerlauf gestellt 
und meine Kausalkette etwas entschlackt. Und ich habe auch gleich eine 
weitere Verwendung für den Puls im Hintergrund gefunden. Der Tip war für 
mich hilfreich.

Am Wochenende komme ich dann hoffentlich zu Peters Link mit dem 
sinnvollen Umsetzen des Sleep Modes. Zuvor muß ich aber noch ein, zwei 
Routinen fertigbekommen, sonst scheppert da wieder was.

Viele Grüße,
      Jan.

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.