Komisches Verhalten meines Programms

Gast #2830917
Lesenswert?

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?
Angehängte Dateien:
#2830970
Lesenswert?

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?
#2831112
Lesenswert?

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.
Gast #2831274
Lesenswert?

> 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?
Gast #2831312
Lesenswert?

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.
Gast #2831459
Lesenswert?

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!
#2831501
Lesenswert?

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.
Gast #2831552
Lesenswert?

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 ;).
#2831583
Lesenswert?

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.
#2831678
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren