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