Hallo, ich steuere gerade eine Rundumleuchte per Mikrocontroller (Attiny2313) an. Je nach dem ob Pin D2, Pin D3 oder Pin D4 auf LOW gesetzt ist, befindet sich die Leuchte in einem anderen Modus und erzeugt ein anderes Blink-Muster. Das funktioniert soweit auch ganz gut. int main (void) { DDRB = 0xFF; DDRD = 0x00; PORTD = (1<<PD2) | (1<<PD3) | (1<<PD4); while(1) { if (!(PIND & (1<<PD2))) { blink(); } if (!(PIND & (1<<PD3))) { rotate(); } if (!(PIND & (1<<PD4))) { strobe(); } } return 0; } Wenn ich nun aber 2 Pins gleichzeitig auf LOW setze, dann verhällt sich die Leuchte bzw. der Controller meines Erachtens ein wenig merkwürdig. Bei dem gleichzeitigen LOW setzen von bspw. Pin D2 und D3 müsste doch normalerweise erst blink() ausgeführt werden und danach dann rotate() und danach ginge es von vorn los. Aber in meinem Fall wird nur blink() aufgerufen und danach wieder blink() und wieder blink() usw. Wie als würde der Controller den Zustand von PD3 ignorieren bzw. nach dem aufrufen der ersten Funktion die Schleife neu beginnen. Bei anderen Kombinationen hat man übrigens das gleiche Problem. Es wird immer die Funktion aufgerufen, die im Quellcode als erstes genannt wird und danach geht es (in der Schleife) irgendwie wieder von vorne los. Woran liegt das?
Vielleicht Layer-8-error? Möglicherweise drückst du nicht lange genug.... Beispiel: Du drückst PD2 und PD3 für blink() und rotate(). Dann wird erst PD2 getestet und daraufhin blink() aufgerufen. Erst nach blink() wird PD3 getestet, vielleicht hast du bis dahin schon losgelassen?
Klaus Wachtler schrieb: > Möglicherweise drückst du nicht lange genug.... Das wird es wohl sein. Wenn du eine Taste drückst, muß das Programm das immer mitkriegen und sich das merken. Egal wann und wie lang das ist. Das tut es aber nicht, wenn es ewig in den Delays auf der Stelle trampelt. Du bist jetzt an dem Punkt angekommen, wo du dich mit Timern und Interrupts befassen solltest. mfg.
Deine Routinen zerstören den Returnstack und damit fängst Du immmer von vorne an. Peter
Klaus Wachtler schrieb: > Wo denn? War nur ne Vermutung. Vielleicht falsches Target eingestellt und der Stack zeigt dadurch in den Wald. Peter
> Möglicherweise drückst du nicht lange genug.... Das kann es eigentlich nicht sein. Ich lege die besagten Pins per Schalter auf Masse. Das ich irgendeinen Druckknopf nicht lang genug drücke kann demnach eigentlich nicht sein. Die Pins sind nach dem Schalten fest und dauerhaft mit Masse verbunden. Dass es dort noch irgendwelche Wechselwirkungen durch Wackelkontakte o.ä. gibt sehe ich eigentlich als relativ unwahrscheinlich an. > Deine Routinen zerstören den Returnstack und damit fängst Du immmer von > vorne an. Das klingt auf jeden Fall schon plausibler. Kannst du das weiter erläutern? Was bedeutet falsches Target und wo stellt man das ein?
jaynis schrieb: > Das klingt auf jeden Fall schon plausibler. Kannst du das weiter > erläutern? Was bedeutet falsches Target und wo stellt man das ein? Schau mal im AVR-Studio in den Projekt-Optionen nach, welcher Prozessor-Type eingestellt ist.
Ich benutze kein AVR-Studio. Ich mach alles "per Hand". avr-gcc -std=c99 -Wall -Os -mmcu=attiny2313 -o main.elf main.c avr-objcopy -O ihex main.elf main.hex avrdude -p t2313 -c usbasp -U flash:w:main.hex -B 10 :D Das bietet natürlich einiges an Raum für Flüchtigkeitsfehler. Es kann natürlich durchaus angehen, dass ich hier aus Versehen mal nen anderen Prozessortyp gewählt habe, weil ich Zeitgleich mehrere Projekte mit unterschiedlichen AVRs am laufen habe. Ich werde das gleich/nachher mal checken.
jaynis schrieb: > Das bietet natürlich einiges an Raum für Flüchtigkeitsfehler. Das bietet maximalen Raum für richtige Fehler. Erzeuge dir doch mal ein makefile mit MFile, und nutze das. Oliver
jaynis schrieb: > Ich mach alles "per Hand". Und mit welchem avr-gcc auf welchem System? Vielleicht unter Linux mit einem avr-gcc aus einem Distributions-Package?
Oliver schrieb: > Erzeuge dir doch mal ein makefile mit MFile, und nutze das. Ja, ich wollte mir schon lange endlich mal ein Makefile gemacht haben, war bisher aber irgendwie zu faul dafür... Stefan Ernst: > Und mit welchem avr-gcc auf welchem System? > Vielleicht unter Linux mit einem avr-gcc aus einem > Distributions-Package? Ja genau so. Ist das schlecht? Jedenfalls habe ich die Einstellungen nun nochmal sorgfältig geprüft und den Controller nochmal geflashed. Nun funktioniert er auch so wie er soll. Ich war bei der Problemlösung irgendwie zu sehr auf meinen Quelltext fixiert und habe das ganze drumherum dabei vollkommen vernachlässigt. Vielen Dank für eure Hilfen!
jaynis schrieb: > Stefan Ernst: >> Und mit welchem avr-gcc auf welchem System? >> Vielleicht unter Linux mit einem avr-gcc aus einem >> Distributions-Package? > Ja genau so. Ist das schlecht? http://www.mikrocontroller.net/articles/AVR_und_Linux#Toolchain_beschaffen
jaynis schrieb: > Oliver schrieb: >> Erzeuge dir doch mal ein makefile mit MFile, und nutze das. > Ja, ich wollte mir schon lange endlich mal ein Makefile gemacht haben, > war bisher aber irgendwie zu faul dafür... Dann mach dir doch wenigstens ein Shell Skript, in das du die 3 Befehle hineinkopierst. Ist dir das denn nicht zu blöd, die wieder und immer wieder einzutippen? Makefile ist natürlich besser und im einfachsten Fall auch nicht aufwändiger als deine 3 Befehle. So ein Makefile hat eine ganz einfache Syntax Ziel : Quelle <Tabulator> Kommando Das 'Ziel' ist von der 'Quelle' abhängig und um das 'Ziel' zu erstellen, wird das 'Kommando' (oder die Kommandos) ausgeführt. Fertig. Mehr ist das im einfachsten Fall nicht. Dein Ziel ist das Hex-File. Um es zu kriegen, muss es ein elf File geben und es ist ein Kommando auszuführen (und das 2te Kommando nehmen wir auch gleich mit)
1 | main.hex: main.elf |
2 | avr-objcopy -O ihex main.elf main.hex |
3 | avrdude -p t2313 -c usbasp -U flash:w:main.hex -B 10 |
Wo kommt das elf File her? Das ensteht aus dem c-File. Also 2. Regel
1 | main.hex: main.elf |
2 | avr-objcopy -O ihex main.elf main.hex |
3 | avrdude -p t2313 -c usbasp -U flash:w:main.hex -B 10 |
4 | |
5 | min.elf: main.c |
6 | avr-gcc -std=c99 -Wall -Os -mmcu=attiny2313 -o main.elf main.c |
und das wars auch schon für dein erstes Makefile. (Aufpassen: die Zeilen mit dem Kommando MÜSSEN mit einem Tabulator anfangen und nicht mit Leerzeichen). Im Grunde sind das also die Kommandos, die du sowieso schon eintippst und das ganze noch ergänzt um die Angabe der Abhängigkeiten. Bei 'Faulheit' geht es also nur darum, den Editor zu öffnen, die Kommandos einzutippen (was du sowieso in der Command Line schon tust), noch 2 Zeilen dazu und alles wieder abspeichern. Eine Sache auf 2 Minuten. Ich würde das daher eher umgekehrt sehen: Die Faulen machen sich ein Makefile. Die Hyperaktiven tippen jedesmal neu. Das ganze nennst du 'makefile' und wenn du das Kommando 'make' gibts wird dein Projekt gebaut (und geflasht). Und du musst dir nie wieder Gedanken darüber machen, ob du für das jeweilige Projekt in der Command Line auch alle Compiler Optionen richtig eingestellt hast. Und ja: Ich weiß. Generierte Makfiles sehen etwas anders aus. Das liegt aber daran, dass man da ins Makefile mehr Komfort eingebaut hat. Im einfachsten Fall tuts auch dieser 5 Zeiler.
Danke für diese ausführliche Zusammenfassung, aber ich weis, was ein Makefile ist und auch wie dieses aufgebaut ist bzw. wie man eins baut ;). In meinem Fall lag es schlicht und einfach an der puren Faulheit ;). Ich musste die Befehle nämlich nicht immer komplett neu eintippen, da sie in der Shell-History gespeichert waren und ich "nur" 3x mit der Pfeiltaste nach oben drücken musste um zum gewollten Befehl zu kommen (dies dann 3x für die 3 Befehle). Ich hab mir immer gesagt, so lange ich nur an sonem Kleinkram rumfummel mach ich das mal eben so und wenn ich irgendwann mit einem größeren Projekt anfange baue ich mir ein richtiges Makefile. Und ehe man sich versieht wird der Kleinkram immer mehr zu was größerem ;).
jaynis schrieb: > Ich musste die Befehle nämlich nicht immer komplett neu eintippen, da > sie in der Shell-History gespeichert waren und ich "nur" 3x mit der > Pfeiltaste nach oben drücken musste um zum gewollten Befehl zu kommen > (dies dann 3x für die 3 Befehle). Das war mir schon klar. Aber jede Entwicklungsmaschine wird auch mal abgeschaltet oder man unterbricht seine Arbeit. Oder lässt du deine Shells wochenlang durchlaufen, nur damit du die Command History nicht verlierst? :-) > Projekt anfange baue ich mir ein richtiges Makefile. Und ehe man sich > versieht wird der Kleinkram immer mehr zu was größerem ;). Ist immer so.
Karl Heinz Buchegger schrieb: > Oder lässt du deine Shells wochenlang > durchlaufen, nur damit du die Command History nicht verlierst? Die History wird doch gespeichert, zumindest von meiner bash :-)
Klaus Wachtler schrieb: > Karl Heinz Buchegger schrieb: >> Oder lässt du deine Shells wochenlang >> durchlaufen, nur damit du die Command History nicht verlierst? > > Die History wird doch gespeichert, zumindest von meiner bash :-) Oops. Sag schon nichts mehr. Also "makfile ist böse, kaka, pfui. Nicht nutzen!" :-)
Karl Heinz Buchegger schrieb: > Und ja: Ich weiß. Generierte Makfiles sehen etwas anders aus. Oder das im Sample-Ordner des WINAVR, nur schlappe 617 Zeilen lang, 17kB groß. Da wird natürlich jeder Einsteiger abgeschreckt und macht fürderhin einen großen Bogen ums Make. Ich benutze eine Batch. In jedem Projektordner eine eigene, da kann also nicht versehentlich das falsche Target compiliert werden. Und am Schluß wird per STK500.EXE geflasht. Ein Doppelklick auf die Batch und das neue Programm läuft. Es kann allerdings passieren, wenn man mehrere Projekte gleichzeitig macht, daß man den Projektordner wechselt, aber vergißt, den ISP auf die andere Schaltung zu stecken. Die STK500.EXE prüft leider nicht das Target. Peter
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.