Moin
Ich arbeite gerade das AVR-Tutorial hier von Mikrocontroller.net durch
(hab von null angefangen und ja, das soll so ne Art Entschuldigung sein
;D) und bin grad beim Thema Vergleiche (also breq, cp, brlo, bla blubber
und so weiter) und wollte einfach mal einen davon ausprobieren. Also hab
ich an mein myAVR-Board light mit nem Atmega8A Controller einfach mal
einen Taster und eine LED angeklemmt. Die LED ist an PORTB5 dran und der
Taster an PORTD7.
Jetzt soll in einer Dauerschleife immer wieder das Signal an PIND mit
der Konstanten 0b10000000 verglichen werden, die nur dann vorliegt, wenn
amn den Taster loslässt. Glaube ich jedenfalls. =D
Bei meinem Programm leuchtet diese LED aber einfach durchgehend. Wie ich
auf den Taster hämmer ist der rotzegal. Wenn ich den Taster an PORTD5
anschließe und einfach in einer Dauerschleife das Signal an PIND in
PORTB (wo ja die LED rumoxidiert) schiebe, geht die LED beim drücken des
Tasters aus. Also müsste die Verkabelung doch korrekt sein.
in r16, PIND ;PIND einlesen (hier klemmt der Taster dran)
2
cpi r16, 0b10000000 ;Diesen Wert mit dem vergleichern, der ohne Drücken vorliegt
gehst du davon aus, das alle anderen Pins des Ports low sind. Hast du
dafür durch externe Beschaltung gesorgt? Deine Pullups sind high, also
wenn du die anderen Pins nicht beschaltet hast, ließt der AVR immer
0bX1111111 wo X für deinen Button steht.
Entweder du machst noch ein AND rein, zB:
1
in r16, PIND ;PIND einlesen (hier klemmt der Taster dran)
2
andi r16, 0b10000000 ;andere Bits entfernen
3
cpi r16, 0b10000000 ;Diesen Wert mit dem vergleichern, der ohne Drücken vorliegt
oder du schaust dir mal andere Instructions an, wie zB: SBRC, SBRS,
SBIC, SBIS
Nein, da fehlt kein RJUMP. Sofern man nichts besonderes angibt, fängt
das Programm an Adresse 0 an, und das ist bereits der Reset Vektor.
Erst wenn er Interrupts verwendet, wird ein Sprung nötig, weil sich
sonst das Programm mit dem Interrupt-Vektoren überlappt.
Stefan Frings schrieb:> Erst wenn er Interrupts verwendet, wird ein Sprung nötig, weil sich> sonst das Programm mit dem Interrupt-Vektoren überlappt.
Er hat ja .org INT_VECTORS_SIZE angegeben und eine Sprungmarke Reset ist
auch vorhanden, da würde ich dann schon einen rjmp an Pos. 0 spendieren.
Nötig ist es wohl nicht, der Prozessor arbeitet halt die leere Tabelle
ab (NOP oder was da auch drin liegt) bevor er anfängt.
Eigentlich ist in dem Beispiel sehr viel in die Hose gegangen:
1. Die Interrupttabelle ist falsch.
Zugegeben, wenn diese nicht genutzt wird steht in der ganzen Tabelle
0x00 oder 0xFF (FLASH=Leer) - dem nach je.
0x00 wird, so glaube ich als NOP interpretiert
0xFF - keine Ahnung
Solltest du aber den einmal angefangenen Quellcode erweitern wollen,
so wirst Du aber bald darüber stolpern, dass die ganze Folge von orgs
keine Funktion hat, solange Du nichts einfügst (Code oder Konstanten).
Nur die Zeile: ".org INT_VECTORS_SIZE" hat zur Folge das die
Stackinitialisierung
an der angegebenen Stelle erfolgt.
Also unbedingt:
org 0x0
jmp reset ; bei kurzen Strecken auch rjmp
Solltest Du nämlich einmal die Strungtabelle nutzen, so wird die CPU bei
ihrem "Durchmarsch" durch die Tabelle mit ihren Vektoren, diese als
Befehle interpretieren.
Das Ergebnis dürfte recht interessant, aber kaum verhersagbar, sein.
Übrigends: Solange Du nur herum'jumptst', kannst Du dir auch die
Initialisierung des Stacks sparen. Der wird meist bei call oder echten
Unterbrechungen benötigt.
Die Problematik der Bit-Behandlung bzw. Maskierung mit UND wurde ja
schon von anderer Seite angesprochen.
'nen Amateur
Moin
Also erstmal danke für die vielen Antworten.
In der Interrupttabelle stand mal nach jeder Marke rjmp RESET, im
Tutorial stand aber, dass man das bei angabe von allen .org auch
weglassen kann.
Den Stack bereite ich jedes mal vor. Ich vergesse es sonst nämlich immer
und wunder mich dann wieso rcall nett läuft. Passiert mir öfter. Und
sind ja nur ein paar Takte.
Und zu guter letzt vielen dank Maik. Ich hab die Zustände der anderen
Pins voll verpeilt. Man. Echt peinlich.
Vielen Dank Leute
Joschua