Ich müsste einen Atmega 8 Programieren , wenn ich auf einen Taster Drücke soll ein ausgang einschalten für 1 sec wenn ich noch mal auf den gleichen Taster Drücke soll wieder ein anderer eingang für 1 sec eingehen usw. Kann mir jemand helfen wie ich sowas Programiere? Danke schon im Voraus!
:
welche Programmiersprache hast du dir denn vorgestellt? Welche Entwicklungsumgebung (auch: Programmieradapter etc) ist vorhanden? welche Hardware verwendest du (fertiges board, LOchrasterplatine?) Die Anforderung selbst ist nicht allzu kompliziert. Zeig doch mal was du schon hast, dann kann man dir auch besser helfen wo es noch klemmt....
Entweder über einen Timer und einen externen Interrupt (was die schönere Variante ist) oder du Pollst die ganze Zeit deinen Taster-Pin und wenn sich der Zustand ändert, schaltest du den gewünschten Pin auf Hi, machst ein Delay von einer Sekunde und schaltest den Pin wieder auf Low.
Ja ich weiss es nicht ich kenn mich ein wenig mit bascome aus mehr nicht! Ja das Bord von Pollin Evolutions borad. Er kommt in einen Sockel der in Einer Lochrasterplatine Verlötet ist! Kannst du mir so einen Code geben den ich nur noch einwenig Verändern muss?
Ja ich will Richtig progrmieren Lerrnen aber ich Brauch sowas so schnell wie möglich und kann nicht Lange Darauf Warten. Kannst du mir damit weiter helfen? Bitte
Zu Basecom kann ich dir leider gar nichts sagen. Ich mache das immer in C. Wenn du noch ganz am Anfang stehst mit deiner Programmiererfahrung, würde ich dir auch eher zur 2. Variante mit dem Pollen raten, da brauchst du keine Timer konfigurieren und keine Interrupt-Routinen. Dann ist das auch von einem Anfänger ganz gut zu bewerkstelligen...
Kannst du mir so einen Code sagen? Bitte Das Problem ist das wegen so einen Teil einen Wichtige maschiene in einer Fleischerei Steht und somit der Halbe betrieb nicht Richtig Arbeiten kann.
Bitte sieh dir den Thread "Attiny mit Timer und Taster" an. Da geht es um genau die gleiche Aufgabenstellung und (im Moment) ganz unten hab ich ausgeführt, wie man das macht.
:
Bearbeitet durch User
Patrick Reichhold schrieb: > Bitte Helft mir Weiter es geht hierbei auch um Viel! > Bitte um Code? Ganz sicher nicht. Du willst das lernen? Dann programmier auch. Radfahren lernt man nicht, indem man andere bitte für einen zu fahren. Auf die Schnauze zu fallen gehört dazu. Dann muss man sich aufrappeln und es noch mal versuchen.
Tasterein: sbic PINA,0x00 rjmp Tasterein Tasteraus: sbis PINA,0x00 rjmp Tasteraus inc zähler (zähler++;)
Am besten in Basecome da kenn ich mich ein wenig damit aus! countdown = 0 timer starten interrupt enable do if( Taste gedrückt ) then Ausgang ein schalten countdown = 5 end if loop OnTimer if countdown > 0 then countdown = countdown - 1 if countdown = 0 then Ausgang aus schalten endif endif return In Was ist der countdown angegeben?
Patrick Reichhold schrieb: > Am besten in Basecome da kenn ich mich ein wenig damit aus! > > > countdown = 0 > timer starten > interrupt enable > > > do > > if( Taste gedrückt ) then > Ausgang ein schalten > countdown = 5 > end if > > loop > > OnTimer > if countdown > 0 then > countdown = countdown - 1 > if countdown = 0 then > Ausgang aus schalten > endif > endif > return > > In Was ist der countdown angegeben? countdown ist eine Variable. Die 'Einheit' hängt davon ab, wie der Timer eingestellt wurde - wie schnell der läuft. Stellt man den so ein, dass er alle 1 Millisekunde die OnTimer Interrupt Routine aufruft, dann sind das eben Millisekunden. Stell ich den so ein, dass OnTimer alle 1 Sekunden aufgerufen wird, dann sind das eben Sekunden. Stell ich den so ein, dass OnTimer alle 0.5 Sekunden aufgerufen wird, dann sind es eben halbe Sekunden. Das was ich dort gemacht habe, ist eine Programmskizze, die das prinzipielle Vorgehen zeigen soll und kein korrektes BASCOM Programm. Da du dich aber mit BASCOM 'ein wenig auskennst' sollte das dann auch kein Problem sein, die Skizze in korrekten BASCOM-Code umzusetzen. FAQ: Timer
:
Bearbeitet durch User
Hier auch noch was in der Männersprache: :-) #include <avr/io.h> #define KEY0 PC0 #define KEY1 PC1 #define KEYPIN PINC #define KEYPULLUP PORTC #define LED0 PD3 #define PORTLED PORTD #define DDRXLED DDRD int main(void) { KEYPULLUP |= (1<<KEY0); // PULL UP ON KEY'S LOW ACTIV KEYPULLUP |= (1<<KEY1); // PULL UP ON KEY'S LOW ACTIV DDRXLED |= (1<<LED0); // LED PORTPIN OUTPUT PORTLED |= (1<<LED0); // LED PORTPIN "1" LED LOW ACTIV for(;;) // do loop { if(!(KEYPIN & (1<<KEY0))) // KEY0 PRESSED? { PORTLED &= ~(1<<LED0); // LED AN } if(!(KEYPIN & (1<<KEY1))) { PORTLED |= (1<<LED0); // LED AUS } } }
Patrick Reichhold schrieb: > Countdown =5? Die 'Einheit' hängt davon ab, wie der Timer eingestellt wurde - wie schnell der läuft. Stellt man den so ein, dass er alle 1 Millisekunde die OnTimer Interrupt Routine aufruft, dann sind das eben Millisekunden. Stell ich den so ein, dass OnTimer alle 1 Sekunden aufgerufen wird, dann sind das eben Sekunden. Stell ich den so ein, dass OnTimer alle 0.5 Sekunden aufgerufen wird, dann sind es eben halbe Sekunden.
Patrick Reichhold schrieb: > Kannst du mir so einen Code sagen? > Bitte > Das Problem ist das wegen so einen Teil einen Wichtige maschiene in > einer Fleischerei Steht und somit der Halbe betrieb nicht Richtig > Arbeiten kann. Dann bezahl einen Profi, der das kann. Wenn du Wasserrohrbruch hast, aber keine Ahnung von Klempnerei hast, rufst du auch den Klempner und gehst nicht in den Baumarkt "BItte helft mir". Es gibt Leute, die die Dinge von der Pieke auf gelernt haben und ihre Brötchen damit verdienen, etwas zu können was andere nicht können. Sowas nennt man "Dienstleister".
:
Bearbeitet durch User
Was für eine Maschine wird denn da mit einem Atmega8 auf einem Pollin-Board gesteuert? Na ja, egal. Wenn du schon einmal ein Lauflicht erstellt hast, sollte das alles in allem ja kein großes Problem sein (zwar nicht mit Timern und Interrupts, aber es geht ja auch ohne). Ich kenne mich jetzt zwar nicht mit Basecom aus, aber eigentlich sollte das ja von den Abläufen so sein wie bei C auch. Als erstes musst du die Pins initialisieren. Taster auf Input und Ausgänge logischerweise auf Output. Wenn es immer die gleiche Abfolge ist, in der die Outputs geschaltet werden sollen, erstellst du ein Array mit den Ausgängen in der entsprechenden Reihenfolge. Dann brauchst du noch eine Zählervariable, die du beispielsweise 'z' nennst, die du mit 0 initialisiert. Nun baust du dir eine Funktion, die den Pin Array[z] auf Hi schaltet, einen Delay von einer Sekunde macht, den Pin Array[z] wieder auf Low shaltet, überprüft, ob 'z' der Anzahl der Elemente im Array -1 (!) entspricht und wenn das nicht der Fall ist, addiert sie zu 'z' eins hinzu. Sollte 'z' gleich der Anzahl der Elemente im Array -1 sein (-1, weil das erste Element im Array mit 0 und nicht mit 1 angesprochen wird), setzt sie 'z' wieder auf 0. Nun brauchst du noch eine Endlosschleife in der der Taster-Pin abgefragt wird. Wenn der Taster gedrückt wird, rufst du die eben erstellte Funktion auf. Fertig
Dominik R. schrieb: > Fertig Genau so macht man das nicht, wenn man sein Handwerk gelernt hat. Delay ist selten die Lösung. Aber oft das Problem.
:
Bearbeitet durch User
Karl Heinz schrieb: > Dominik R. schrieb: > >> Fertig > > > Genau so macht man das nicht, wenn man sein Handwerk gelernt hat. > > Delay ist selten die Lösung. Aber oft das Problem. Mir ist auch klar, dass ein Timer und ein Taster-Interrupt da die bessere Wahl wären, aber das ist für einen Anfänger schon ziemlich kniffelig. Deshalb von mir die Poll-Lösung mit Delay...
Dominik R. schrieb: > Karl Heinz schrieb: >> Dominik R. schrieb: >> >>> Fertig >> >> >> Genau so macht man das nicht, wenn man sein Handwerk gelernt hat. >> >> Delay ist selten die Lösung. Aber oft das Problem. > > Mir ist auch klar, dass ein Timer und ein Taster-Interrupt da die > bessere Wahl wären, aber das ist für einen Anfänger schon ziemlich > kniffelig. In BASCOM sind Timer recht einfach zu handhaben. Viele der klassischen Fallen in C gibt es dort nicht. Alles was er tun muss, ist sich einen Vorteiler zu wählen und davon ausgehend ausrechnen, in welchen Zeitabständen die zum Timer gehörende OnTimer Funktion aufgerufen wird. BASCOM hat hier zwar einen etwas höheren Overhead, aber von der Benutzbarkeit sind Timer um einiges leichter zu handhaben. Des ganze Gefummel mit Konfigurationsregistern und zu setzenden Bits fällt dort alles weg. Der Rest ist ein wenig Arbeit mit dem Taschenrechner und die Strategie. Die hat er ja schon.
:
Bearbeitet durch User
Karl Heinz schrieb: > In BASCOM sind Timer recht einfach zu handhaben. Viele der klassischen > Fallen in C gibt es dort nicht. Dann ist das mit dem Delay wirklich überflüssig. Wie gesagt, ich hab keinen Plan von Basecom...
Dominik R. schrieb: > Karl Heinz schrieb: >> In BASCOM sind Timer recht einfach zu handhaben. Viele der klassischen >> Fallen in C gibt es dort nicht. > > Dann ist das mit dem Delay wirklich überflüssig. Wie gesagt, ich hab > keinen Plan von Basecom... Ist schon ok. Sieh selbst In BASCOM sieht eine einfache Timer-Benutzung so aus
1 | ... |
2 | Config Timer0 = Timer , Prescale = 1024 |
3 | On Timer0 OnTimerOverflow |
4 | |
5 | Enable Timer0 |
6 | Enable Interrupts |
7 | |
8 | do |
9 | ..... |
10 | Loop |
11 | |
12 | |
13 | OnTimerOverflow: |
14 | ... |
15 | return |
und ich finde: noch weiter abstahieren kann man das schon fast nicht mehr. Weder muss er mit diversen Bits in Konfigurationsregistern rumfuhrwerken, noch muss er sich raussuchen, welche für einen bestimmten Vorteiler zu setzen sind, noch kann er sich im Namen der ISR vertun, weil er den selbst vergibt. Ok, wenn man im Config angeben könnte, in welchen Zeitabständen die OnTimerOverflow aufgerufen werden soll, dann wären sogar mathematische Analphabeten glücklich, der Rest muss eben ein wenig mit dem Taschenrechner rechnen. Aber so schwer sollte das dann auch nicht sein, die Taktfrequenz durch 1024 zu teilen und das was rauskommt noch mal durch 256 und davon dann den Kehrwert nehmen. Wenn man verstanden hat, wie Timer funktionieren, ist das recht naheliegend und schlüssig.
:
Bearbeitet durch User
Ich wette 50€, dass er mit dem sehr guten ausführlichen Post von Dominik nicht zurecht kommt und dass dieser Thread noch mindestens 100 Beiträge erreicht vor Anbruch des Wochenendes.
Karl Heinz schrieb: > Delay ist selten die Lösung. Aber oft das Problem. Wo siehst du in diesem Fall das Problem mit delay?
cybmorg schrieb: > Karl Heinz schrieb: >> Delay ist selten die Lösung. Aber oft das Problem. > > Wo siehst du in diesem Fall das Problem mit delay? Es ist im Grunde immer das gleiche Problem. Für einfache Sache, wie ein Blinklicht, ist delay eine Lösung. Es ist etwas, mit dem ein Neuling schnell eine Lösung hinkriegt. In dem Moment aber, in dem ein Programm mehrere Dinge "gleichzeitig" machen soll, wie zb Blinklicht UND zusätzlich noch einen Taster überwachen, werden die delay Lösungen schnell unbrauchbar. Klar, man kann das so hinkriegen. Aber der Aufwand dafür wächst auch sehr rasch. Nimm noch eine 3-te Aktion mit dazu, und es wird nicht mehr ohne massiven Aufwand beherrschbar. Delay-Lösungen skalieren in dieser Beziehung schlecht. Eine Umstellung der Denkweise, weg von Zeitdauern und hin zu Zeitpunkten, realisiert durch einen Timer, ist schon bei 2 Aktionen einfacher (Beispiel: 2 LED blinken in unterschiedlichen Frequenzen) ohne dass es dazu erheblichen Mehraufwand im Vergleich zu delay Lösungen kommt. Und der Aufwand wird dann auch nicht größer, die Methodik skaliert wesentlich besser mit der Anzahl der 'gleichzeitigen' Aufgaben. Daher ist es wichtig, diese Technik zu beherrschen. Sie ist nicht kompliziert und wir benutzen sie im realen Leben ja auch. Kein Mensch bleibt 2 Stunden beim Ofen stehen, um Schweinebraten zu machen. Wir stellen uns einen Wecker, der alle halbe Stunde klingelt und daran erinnert, den Braten zu übergiessen. Und in der Zwischenzeit macht man eben was anderes. Nichts anderes ist die Timerlösung: viele Wecker, deren Klingeln daran erinnern, dass es Zeit ist eine bestimmte Aktion zu machen. Nur das man halt die vielen Wecker durch lediglich ein einziges Uhrwerk realisiert. Aber das ist ja kein Problem.
Der TO hat ein konkretes Problem. Die Loesung mit delay ist einfach und deckt alle Anforderungen ab. Und sie ist fuer den TO leichter zu verstehen, als die Timer-Loesung. Deine Fachkenntnis in allen Ehren, aber manchmal heisst es einfach nur: Problem -> Loesung -> Fertig.
Karl Heinz schrieb: > Daher ist es wichtig, diese Technik zu beherrschen. Sie ist nicht > kompliziert Ganz konkret zb so 2 LED sollen blinken, wobei die eine LED alle 3 Sekunden umschalten soll, die andere LED alle 5 Sekunden. Klar das kann ich mit delays machen, indem ich mir eine Timeline mache, alle Blinker eintrag, und die Zeiten dazwischen als delay nehme
1 | 0000000000111111 |
2 | 0123456789012345 |
3 | |
4 | LED1 v v v v v v v v |
5 | |--------------------------- |
6 | LED2 ^ ^ ^ ^ |
7 | |
8 | | | |
9 | +--------------+ |
10 | Periode |
11 | nach der sich alles |
12 | wiederholt |
aus der Timeline kann man ablesen, das man nach 15 Sekunden wieder im Urzustand angelangt ist und sich ab da die Delay-Zeiten wiederholen werden. Die Delays an denen Aktionen notwendig sind, kann man aus der Timeline erhalten
1 | bei 0 beide umschalten |
2 | bei 3 LED1 umschalten |
3 | bei 5 LED2 umschalten |
4 | bei 6 LED1 umschalten |
5 | bei 9 LED1 umschalten |
6 | bei 10 LED2 umschalten |
7 | bei 12 LED1 umschalten |
8 | bei 15 beide umschalten - weiter gehts wie nach 0 |
daraus ergeben sich die delays zwischen den Aktionen, indem man die Differenzen zwischen den Zeitpunkten nimmt:
1 | do |
2 | beide umschalten |
3 | delay 3 |
4 | Led1 umschalten |
5 | delay 2 |
6 | Led2 umschalten |
7 | delay 1 |
8 | Led1 umschalten |
9 | delay 3 |
10 | Led1 umschalten |
11 | delay 1 |
12 | Led2 umschalten |
13 | delay 2 |
14 | Led1 umschalten |
15 | delay 3 |
16 | loop |
das ist eine Delay-Lösung, die genau das geforderte macht. Die LED blinken mit den vorgegebenen Zeiten Aber der Aufwand, musst du selbst zugeben, war schon enorm. Ändere die 5 auf 7 und der Aufwand geht wieder von vorne los. Die andere Annahme war, dass die Aktionen vergleichsweise wenig Zeit benötigen. Das Umschalten von Led fällt da zweifellos darunter. Aber nimm einfach nur mal an, dass die Umschaltung der Led2 aus irgendeinem Grund selbst 0.1 Sekunden brauchen würde. Spätestens jetzt wird das ganze ekelhaft. Wie macht man das mit einer Timerlösung? So: Das ist das Grundgerüst
1 | Config Timer0 = Timer , Prescale = 8 |
2 | On Timer0 OnTimerOverflow |
3 | |
4 | Enable Timer0 |
5 | Enable Interrupts |
6 | |
7 | do |
8 | ..... |
9 | Loop |
10 | |
11 | |
12 | OnTimerOverflow: |
13 | ... |
14 | return |
Ich geh mal von 1Mhz Taktfrequenz aus. Den Vorteiler hab ich auf 8 gesetzt, damit wird die OnTimerOverflow Funktion über den Daumen gepeilt alle 2 Millisekunden aufgerufen. (1 / ( 1000000/8/256 ) = 0.002048). Das soll für meine Zwecke genau genug sein. (und lässt sich mit einfachen Mitteln auch verbessern - Stichwort CTC Modus, aber lass mich das mal ignorieren und einfach mal die 2 Millisekunden als gegeben annehmen) Für jede LED führe ich einen 'Wecker' ein. Das ist einfach nur ein Zähler, der von einer Start-'Zeit' runterzählt und wenn er bei 0 ist, dann 'klingelt' er und stellt die LED um. Bei 2 Millisekunden Basisticken bedeutet das, das der Wecker für Led1 von 1500 auf 0 zählen muss, der für Led2 macht dasselbe mit einem Startwert von 2500 d.h. für Led1 gibt es eine Variable
1 | DIM TimeLed1 as Integer |
und in meinem 'Uhrwerk', zählt der (diesmal in Richtung 0, also Countdown)
1 | OnTimerOverflow: |
2 | |
3 | TimeLed1 = TimeLed1 - 1 |
4 | |
5 | ... |
6 | return |
und wenn der 'Wecker abgelaufen ist', schaltet er die Led
1 | OnTimerOverflow: |
2 | |
3 | TimeLed1 = TimeLed1 - 1 |
4 | if TimeLed1 = 0 then |
5 | toggle LED1 |
6 | TimeLed1 = 1500 |
7 | endif |
8 | ... |
9 | return |
dasselbe nochmal für Led2 und 2500 statt der 1500. d.h. das Programm sieht so aus
1 | DIM TimeLed1 as Integer |
2 | DIM TimeLed2 as Integer |
3 | |
4 | Config Timer0 = Timer , Prescale = 8 |
5 | On Timer0 OnTimerOverflow |
6 | |
7 | Enable Timer0 |
8 | Enable Interrupts |
9 | |
10 | TimeLed1 = 1500 - 1 |
11 | TimeLed2 = 2500 - 1 |
12 | |
13 | do |
14 | ..... |
15 | Loop |
16 | |
17 | |
18 | OnTimerOverflow: |
19 | |
20 | TimeLed1 = TimeLed1 - 1 |
21 | if TimeLed1 = 0 then |
22 | toggle LED1 |
23 | TimeLed1 = 1500 |
24 | endif |
25 | |
26 | TimeLed2 = TimeLed2 - 1 |
27 | if TimeLed2 = 0 then |
28 | toggle LED2 |
29 | TimeLed2 = 2500 |
30 | endif |
31 | |
32 | return |
Ist das komplizierter? Auf den ersten Blick: Ja, das ist komplizierter. Aber: Ich kann die 5 Sekunden der LED2 ändern, ohne die komplette Sequenz für Led1 durcheinander zu bringen. Anstalle der 2500 schreibe ich einfach 3500 rein (für 7 Sekunden). Sonst ändert sich nichts. Des weiteren: nimm eine 3.Led mit dazu, die alle 8.4 Sekunden umschalten soll. Mit der delay-Lösung artet das jetzt schon aus. Denn erst mal musst du die Zeitachse so lange weiter verfolgen, bis du irgendwo den Zustand entdeckst, an dem die Umschaltvorgänge aller 3 LED wieder auf 1 Zeitpunkt zusammenfallen. Bei 3, 5 und 8.4 dürfte das nicht so schnell der Fall sein. Dementscprechend viele einzelne Umschaltvorgänge und delays dazwischen gibt es dann auch. Wie ist das bei der Timer Lösung? Da ist das trivial. Für die 3. Led kommt ein weiterer Wecker dazu (1 Variable mehr), in die ISR kommt ein weiterer Fall für die 3.te LED rein, ich rechne mir noch aus, dass 8.4 Sekunden 4200 Aufrufen der ISR entsprechen, und fertig bin ich: eine 3 Aktion ist ins Programm mit reingekommen, ohne dass ich einen Haufen delays habe überarbeiten müssen oder sonst irgendwie grossartig viel Aufwand hatte. Das ist gemeint mit 'skaliert besser'. Kommen zusätzliche Anforderungen hinzu, dann ist es einfach die mit dazuzunehmen, ohne dass alles auseinander fällt oder überarbeitet werden muss. Und Hand aufs Herz: sooooo aufwändig ist der Timer-Ansatz dann auch wieder nicht. Ja, er ist erst mal mehr Aufwand. Aber nicht so viel mehr.
:
Bearbeitet durch User
cybmorg schrieb: > Der TO hat ein konkretes Problem. Die Loesung mit delay ist einfach und > deckt alle Anforderungen ab. Dann würde ich vorschlagen du liest dir seine Aufgabenstellung noch einmal aufmerksam durch. An keiner Stelle sagt er, dass die Brennzeit einer LED bereits abgelaufen sein soll, wenn ein weiterer Tastendruck die nächste LED einschaltet.
:
Bearbeitet durch User
Patrick Reichhold schrieb: > wie möglich und kann nicht Lange Darauf Warten. Bei dem Wissensstand würde ich mal die Hoffnung nach einer schnellen Lösung zumindest infrage stellen. So was kann man machen wenn man zumindest etwas Erfahrung in der Materie hat. Klingt zwar nicht sonderlich optimistisch, dafür ist es eher realistisch.
Wie schauts aus? Läuft die fleischproduktion wieder? :) Bin auch soeben stundenlang vorm Pc gesesen um mir einen Timer zurech zu bauen. Meiner läuft! :) Wie schauts bei dir aus?
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.