Forum: Compiler & IDEs Unterbrechung mit Taster


von Fynn (Gast)


Lesenswert?

Hallo,

Ich hab ein Programm, welches einige Funktionen ausführen soll. Die 
Funktionen werden je nach Eingabe aufgerufen und bearbeitet. Hier jetzt 
mein Frage. Wie kann ich durch einen Taster die Funktion unterbrechen 
und wieder bei 0 anfangen?? Mein Problem ist, dass der Controller 
(Atmega8)je nach Funktion mehrer Sekunden in der zu bearbeitenden 
Schleife festsitzt und sich nicht stoppen lässt. Erst wieder nach der 
Schleife wenn die Taster abgefragt werden.
Z.B. Led's sollen sollen 10s lang in unterschiedlichen Periodendauern 
blinken. Dazu hab ich einfach die _delay_ms() verwendet, aber wie könnt 
ich mit einem Taster nach z.B. 5s aus dem ganzen wieder aussteigen ohne 
die kompletten 10s daurchlaufen zu müssen??

Fynn

von Uwe S. (de0508)


Lesenswert?

Hallo,

so wie ich das verstehe, einen Tasten nach Reset legen.

Sonst keine Delays und ein komplett anderes Programmkonzept anlegen.

Kooperative Funktionen auf Basis einen Zeittaktes z.B. 1ms.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Fynn schrieb:

> und wieder bei 0 anfangen?? Mein Problem ist, dass der Controller
> (Atmega8)je nach Funktion mehrer Sekunden in der zu bearbeitenden
> Schleife festsitzt

Das ist schon der erste Fehler.

Teile die Funktion in mehrere kleinere Happen auf und mach eine 
Ablaufsteuerung dafür, die sich an einer Statemachine orientiert.


> Z.B. Led's sollen sollen 10s lang in unterschiedlichen Periodendauern
> blinken. Dazu hab ich einfach die _delay_ms() verwendet

Das ist der zweite Fehler.
Zeitsteuerungen werden mit einem Timer realisiert und nicht mit 
_delay_ms. _delay_ms ist selten die Lösung aber oft das Problem.
Genauso wie das Programmiererdenken in Zeitdauern anstelle von 
Zeitpunkten.


Wahrscheinlich wirst du dein Programm komplett überarbeiten müssen.


FAQ: Timer

: Bearbeitet durch User
von Fynn (Gast)


Lesenswert?

ok, vielen dank.
das mit dem kooperativen Funktion versteh ich nicht so ganz. Ich bin 
noch anfänger :-) Merkt man ja!!
Aber ich hab gedacht das ich den Timer nur einmal nehmen kann. Was ist 
dann wenn ich "delays mehrmals verwendet hab. Wie ersetzt ich die?

von Karl H. (kbuchegg)


Lesenswert?

Fynn schrieb:

> Aber ich hab gedacht das ich den Timer nur einmal nehmen kann.


reicht doch.
Der Timer liefert dir einen Basistakt.


Wenn ich dir jede halbe Sekunde in den Hintern trete und du mitzählst 
wie oft ich das mache und du beim Zählerstand von 6 jeweils auf den 
Lichtschalter drückst (und wieder bei 0 weiterzählst), was macht dann 
das Licht?
Richtig es geht alle 3 Sekunden an und 3 Sekunden später wieder aus.

Jetzt bist du aber schlau, du kannst dir nicht nur eine Zählvariable 
merken der für das Licht zuständig ist, sondern auch einen zweiten 
Zählvariable mit der du jeweils bis 8 zählst, und jedesmal wenn die 8 
erreicht ist, machst du das Fenster auf bzw. zu.

Was ist daher der Gesamteffekt?
Alle 3 Sekunden geht das Licht an und aus und gleichzeitig geht zeitlich 
darin verschränkt alle 4 Sekunden das Fenster auf bzw zu.
1
  Licht        ***   ***   ***   ***   ***...
2
           |----+----+----+----+----+---- ...
3
  Fenster       ****    ****    ****    **...

Und das alles basiert darauf, dass ich alleine dir alle halbe Sekunde in 
den Allerwertesten trete und du einfach nur für die Einzelaufgaben 
entsprechend oft mitzählst.

FAQ: Timer
Die ISR ist genau das Äquivalent zu meinen Handlungen an deinem 
Hinterteil.

In der Zwischenzeit (zwischcen meinen Attacken :-) hast du genügend Zeit 
auch noch nach der Hausklingel zu sehen und wenn der Postmann 3 mal 
klingelt, setzt du deine Zählvariablen wieder auf 0 zurück. :-)



(Nimm das Posting nicht zu wörtlich. Es soll nur das Prinzip 
veranschaulichen. Zugegeben, es ist etwas drastisch, aber recht 
einprägsam)

: Bearbeitet durch User
von Fynn (Gast)


Lesenswert?

kann es aber passieren, dass ich den Timer verpasse? Also ich hab ein 
großes Programm und vielleicht doch mal ein "delay" verbaut z.B. beim LC 
Display ansteuern. Was ist dann? Muss ich da dann mit Interupts 
arbeiten?

von Karl H. (kbuchegg)


Lesenswert?

Fynn schrieb:
> kann es aber passieren, dass ich den Timer verpasse?

Theoretisch ja.
Du darfst halt nicht zu lange brauchen um die jeweilige Zählvariable zu 
erhöhen und das Licht bzw. das Fenster zu schalten.

> Also ich hab ein
> großes Programm und vielleicht doch mal ein "delay" verbaut
ist wurscht.
Denn der Tritt kommt ja trotzdem durch. Sobald ich dir eine verpasse, 
lässt du kurzfristig alles stehen und liegen und arbeitest deine Zähler 
durch bzw. schaltest das Licht/Fenster. Und erst danach nimmst du deine 
vorhergehende Tätigkeit genau wieder an der Stelle auf, an der du alles 
stehen und liegen gelassen hast.

> Display ansteuern. Was ist dann? Muss ich da dann mit Interupts
> arbeiten?

Ähm.
Genau davon rede ich die ganze Zeit. Hast du dir denn den Link nicht 
angesehen, den ich dir jetzt schon zum 2-ten mal gepostet habe?

FAQ: Timer

die ISR ist die Interrupt Funktion, die laufend in regelmässigen 
Zeitabständen aufgerufen wird. Du solltest wirklich den Link studieren, 
den stell ich da nicht zum Spass rein.

Zum Thema LCD.
Normalerweise brauchst du da keine Interrupts verbauen. Denn die 
Zeitsteuerungen in der LCD Ansteuerung sind insofern nicht kritisch, als 
man zwar eine gewissen Mindestzeit warten muss bis man zb irgendwelche 
Steuersignale am Bus ausgeben kann, man allerdings die Wartezeit auch 
länger machen darf. Wenn also der Hersteller vorschreibt, dass die Write 
Leitung erst 10µs nach Anlegen der Daten auf die Datenleitungen auf 1 
gehen darf, dann ist das eine Untergrenze. Du darfst Write nicht früher 
als 10µs nach Anlegen der Daten ziehen, du darfst dir ruhig aber 2 
Stunden Zeit lassen dafür. D.h. es ist überhaupt kein Problem, wenn an 
dieser Stelle irgendwelche Delays mal ein bischen länger dauern, weil 
zwischendurch von der Timer-ISR dazwischen gefunkt wird und die ein paar 
Taktzyklen verbrutzelt und ein delay mit 10µs dann auch mal 10.1 µs 
dauert.

: Bearbeitet durch User
von Fynn (Gast)


Lesenswert?

Natürlich hab ich mir den Link angeschaut, aber das muss ich ja auch 
erst mal aufnehemen und verstehen. Das mit dem Displa hab ich gefragt, 
weil ich mir schon ein Programm dazu gemacht hab. Ich hab nur nicht 
verstanden, dass der Timer immer ein Interrupt auslöst. Ich hab ihn bis 
jetzt nur so benutzt

if(TCNT1==15625)
{
Anweisung
}
aber ich werd mich die nächsten Tage damit beschäftigen.
Vielen Dank für deine Hilfe

Fynn

von Peter D. (peda)


Lesenswert?

Fynn schrieb:
> Mein Problem ist

Fynn schrieb:
> Dazu hab ich einfach die _delay_ms() verwendet

Problemvermeidung: Delay nicht nehmen.

Lange Abläufe steuert man über Statemaschinen oder Tabellen, z.B.:

Beitrag "AVR Sleep Mode / Knight Rider"

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.