PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Brauche Hilfe bei Interrupts für die Taster(Assembler)



Gurkenmesser
17.06.2009, 14:23
Hi,
ich bin grade dabei für für ein projekt einen asuro zu programmieren...nun wollte ich gerne das er es schafft durch ein unbekanntes labyrinth zu kommen,hab auch schon eine idee wie das klappen sollte nur happert es bei einem punkt der umstezung

erstmal meine idee
Unser labyrinth soll nur einen weg haben,also keine sackgassen usw...meine idee war deshalb wenn er einmal aneckt dreht er sich nach rechts und versucht weiter zu fahren,wenn er hier gleich wieder aneckt dreht er sich um 180 grad,da das ja nun nurnoch der einzigste weg ist bei dem es weiter gehen kann

Nun happert es bei der umsetzung an folgendem:
Ich weiß nicht genau wie ich es anstelle das der kleine kerl erkennt das er 2mal ganz kurz hintereinander angeeckt ist und sich dann um 180 grad drehen muss.Ich würde das jetzt irgendwie über timer lösen weiß aber noch nicht so richtig wie :(

Hier ist mal mein code bis jetzt
Hier ist noch ein Fehler drinne,der asuro dreht sich beim 2. anecken immer 180 grad :(


EXT_INT1:

push r16 // alles auf Stack retten!
push R20
push r21
in r16, SREG
push r16

ldi r20, MOSP // Motorgeschwindigkeit einstellen
ldi r21, MOSP
rcall Motorspeed

cpi r25, 0 // 1. Interrupt Drehen 90 grad
breq Drehen

cpi r25, 1 // 2. Interrupt Drehen 180 grad
breq Drehen180



Drehen:

Motorschnelldrehenrechts
ldi r18, KUZeit
rcall wait
inc r25
rjmp Ende

Drehen180:

Motorschnelldrehenrechts
ldi r18, KUZeit
rcall wait
Motorschnelldrehenrechts
ldi r18, KUZeit
rcall wait
clr r25
rjmp Ende


Ende:

Motorvor
ldi r16, 0x80
out GIFR, R16
pop r16
out SREG, r16
pop r21
pop r20
pop r16
reti


hat jemand einen tipp wie ich das mit nem timer hinbekomme oder von mir aus auch ne andere lösung :)

mfg

Besserwessi
17.06.2009, 16:33
Das erste Problem solle sein, das die Taster eventuell prellen. Da müßte wahrscheinlich noch was ran um zu schnelle Folgen zu ignorieren.

Das 2 te Problem ist das, das wohl nicht alle Register in der ISR gerettet werden: Z.B. R18.

Für ein solches Problem wäre ein umsetzung in C wohl passender als ASM.

Gurkenmesser
17.06.2009, 17:47
wir müssen es aber leider in assembler programmieren :( ist vorgabe

Besserwessi
17.06.2009, 18:35
Hört sich also nach Hausaufgabe an.

Gerade in ASM hilft es wenig erst mal drauflos zu programieren. Da sollte man erst mal ein genaue Vorstellung davon haben wie das gehen. Also erst mal planen, ggf. auch noch mit Bleistift und papier. Ein Plan für den Programmablauf sollte man schon vorher Aufmalen, vor allem wenn da Problem zu schwer ist um es einfach so runterschreiben zu können.

Das erste Problem wäre die Tastenentprellung. Die einfachste Lösung ist es da die Taste nur alle etwa 2 - 10 ms abzufragen. Das könnte man z.B. per Timer ISR tun. Die Drehung selber sollteman natürlich nicht in der ISR ausführen, denn eine ISR sollte in der Regel kurz sein. Warten auf den Motor ist damit Tabu.

Das Verfahren könnte dann so gehen:
Bei einem Hindernis:
- Dehen um Winkel von 90 Grad oder mehr
- erhöhen des Winkels für die Nächste Drehung um 90 Grad
- nach der Drehung: Timer starten für z.B. 1-2 s (oder etwa 10 cm Weg)
- geradeaus fahren (bis zum nächsten Hinderniss)

Wenn Timer abläuft:
- Winkel für drehung wieder auf 90 Grad zurücksetzen

Skroete
17.06.2009, 18:55
Hallo,

endlich mal wieder Einer, der sich an den Asuro in Assembler herantraut.

@Besserwessi
Das eventuelle Prellen von Tasten spielt bei diesem Effekt keine Rolle
und dass r18 nicht auf den Stack gerettet wird, ist auch OK, solange r18
nur in der ISR benutzt wird. Das Gleiche gilt auch für r25.
Deshalb vergiss mal die ganze Tastenentprellung.

@Gurkenmesser
Dass der Asuro bei jedem 2. Anecken um 180Grad dreht ist völlig richtig.
Das hast du so programmiert! Beim 1. Aufruf der ISR setzt du am Label
Drehen: das Register r25 mit der Anweisung inc r25 auf 1.
Beim 2. Aufruf landet er dann durch cpi r25,1 immer auf Drehen180:
Dort wird dann mit clr r25 das Register wieder auf 0 gesetzt und das
Spiel kann von vorn beginnen.
Also du müsstest dafür sorgen, dass r25 nach Ablauf einer gewissen Zeit
wieder auf 0 gesetzt wird.
So weit, so schlecht.

Ein paar Bemerkungen nun zu deiner Implementierung.
Sehr schlecht ist es in einer ISR den AVR in Warteschleifen zu schicken
(rcall wait). Wenn der Asuro fährt und während dem rcall wait irgendwo
andonnert, dann kriegst du das nicht mit, da er ja noch in der ISR routine
verweilt. Alle ISR sind dann nämlich gesperrt.
Da er nur dreht, wird er wohl nicht anstossen können, ist aber dennoch
generell schlechter Programmstil und man sollte sich das gar nicht erst
angewöhnen.
Lösung : In der ISR nur ein Flag setzen, im Hauptprogramm das Flag prüfen und dort das Drehen abarbeiten.
Damit kannst du dann auch gleich dein 2. Problem

"Ich würde das jetzt irgendwie über timer lösen weiß aber noch nicht so richtig wie"

lösen.
Wenn du den Asuro nach dem Drehen wieder vorwärts fahren lässt, schickst du den AVR mit rcall wait_neu wieder in eine warteschleife. Falls er nun während dem Warten wieder irgendwo andonnert, landet er wieder in der ISR. Dort kannst du nun ein weiteres Flag setzen für die 180Grad Drehung. In der wait_neu kannst du dann das Flag prüfen und falls notwendig die 180Grad Drehung abarbeiten. Beim Verlassen
der wait_neu werden auf jedenfall die beiden Flags gelöscht.
Damit ist der AVR wieder scharf für das nächste Anstossen.
Das wäre eine Lösung von vielen, vielen Möglichkeiten.

Da in der ISR nun nur noch 2 Flags gesetzt werden, stellt sich mir die Frage, ob man das Ganze nicht auch im Hauptprogramm prüfen und abarbeiten kann.
Das ist aber Geschmackssache.

Falls du ein paar Assembler Beispiele sehen möchtest, dann schau mal hier im Forum nach "Asuro programmieren in Assembler".
Anbei noch ein kleines Fahrprogramm und die Sourcen für das AVR-Studio.


Und lass dich hier nicht von den C-Programmierern beirren. Nur wer beides beherrscht kann auch beides beurteilen.
Also kein Grund für das Wörtchen "leider".

Viel Spass
Skroete