Hallo
So ich wollte mal anfangen mit den Atmel Mega 8 was zu machen.
Natürlich fange ich da mit den Grundlagen an!!( nicht gleich meckern)
Wollte nur 2 Bit´s miteinander undverknüpfen. In der Hilfe auf der Seite
steht auch was dazu drin aber irgentwie geht das nicht.
Erleuchtet mich bitte der Quode:
Sam700 schrieb:> cbi DDRB,0 ;Port B.0 Input (cbi = setze bit 0,0)> sbi PORTB,0 ;Port B.0 PullUp (SBI = setze bit 0, 1)> cbi DDRB,1 ;Port B.1 Input (cbi = setze bit 0,0)> sbi PORTB,1 ;Port B.1 PullUp (SBI = setze bit 0, 1)
Pins auf Eingang und Pullup.
Daher gehe ich davon aus, dass deine Taster gegen Masse schalten.
Also müsstest du hier invertiert abfragen.
:-)
Sam700 schrieb:> ldi r16 , 0 ;lade Register R16 mit 0 damit die> ....> out PORTB , r16
Tja.
Und damit sind dann wohl deine Pullup-Widerstände zur Geschichte
geworden :-)
Beim ausgeben auf einen Port IMMER darauf auchten, dass mittels OUT alle
8 Bit geschrieben werden!
Wenn du Bits hast, die so bleiben müssen (wie zb die Bits zuständig für
Pullup Widerstände) dann musst du das berücksichtigen!
Hallo
Hm.. Was müsste ich dan ändern?
Einen Fehler habe ich noch gefunden und zwar wen man versucht den
eingagnstaster zu beschreiben und nicht die LED na ja ...
Falsch
A1: ldi r16, 0b0000011
Richtig
A1: ldi r16, 0b000100
Jetzt geht auch eine LED an aber das ist jetzt eine Oder verknüpfung.
Das kan doch nach
1
andi r16,0b1010 ; prüfe Bit #1 und #3 in r16
2
cpi r16,0b1010
3
breq alle_bits_sind_gesetzt
garnicht sein. Wen jetzt wieder nichts gehen würde dan ok aber eine Oder
obwohl ich das so gemacht habe?
Danke
Sam
p.s. Aller Anfang ist schwer :)
Sam700 schrieb:> Wen jetzt wieder nichts gehen würde dan ok aber eine Oder> obwohl ich das so gemacht habe?
Stichwort De-Morgan.
Dein Sprung wird jetzt ausgeführt, sobald EINER der beiden Taster nicht
eins ist, also wenn einer der beiden gesrückt wurde (-> oder).
Denke daran, dass die Eingabe invertiert ist, wenn die Taster nach Masse
schalten.
Gedrückt -> Pin ist 0
nicht gedrückt -> Pin ist 1
Also musst du eine Wahrheitstabelle ausfüllen, die passt:
keiner gedrückt ...11
einer gedrückt ...10
...01
beide gedrückt ...00
auf was genau willst du reagieren? Das entsprechede musst du dann
abfragen.
:-)
Hallo nochmal
So ich hbe meinen Fehler gefunden.
Wie es scheint habe ich einen Fehler ind en Sprungmarken gemacht.
So geht das :
1
mainloop: wdr
2
ldi r16 , 0x0 ;lade Register R16 mit 0 damit die LED auch aus geht
3
in r17 , PINB ;Lese PINB ein
4
andi r17, 0x3 ; prüfe Bit #0 und #1 in r17
5
breq A1 ;Wenn bedingung gegeben dann Springen auf A1
6
ldi r16, 0b000100 ; Wenn der taster nicht geshaltet ist überspringe nächsten schritt
7
A1: out PORTB , r16 ;Ausgabe PortB
8
rjmp mainloop
Na ja manchmal steht man einfach auf der Leitung.
BEim nächstenmal einfach einen schritt zurück und dan nochmal schauen :)
THX erstmal (Ich komme bestimmt wieder :) )
Sam
Hi
Auch wenn du "nur" Anfänger bist, werde ich dir mal ein kleines
Geheimnis verraten: "Module"...
Grad wenn u in Assembler deine Gehversuche startest, dann solltest du
folgendes beherzigen.
Verwende kleine Unterprogramme. Z. B. Initialisiere zuerst den Stack, da
kmmst du oft nicht drum herum. Danach setze die IO, den Timer, den UART.
Anschließend setze deine Variablen und Register auf Defaultwerte. Für
jede Aufgabe eine eigene Routine. Mußt du später mal etwas ändern, hast
du nur einen kleinen Programmblock zu bearbeiten.
In deiner Hauptschleife beginne mit einem Unterprogramm, um die Eingänge
zu lesen. Diese Werte legst du in einer Variablen ab und veränderst
diese in der gesamten Programmschleife nicht mehr. Auch hier der
Vorteil: ändern sich deine IO, dann brauchst du nur diese Routine ändern
und du kannst die Eingangspins schön in einer Variablen auf ein oder
zwei Byte legen, egal, wie gemischt du sie einsammeln mußt.
Wenn du deine Eingänge nach GND schaltest, macht es Sinn, die Bits vor
der Weiterverarbeitung zu drehen. Das ist einfach mit einer EOR
(Exclusiv-Oder) und einer konstanten "1" durchzuführen.
Bsp.
In Reg_A, PortB ; ich lese mal ein ganzes Byte ein
LDI Reg_B,0b11111111 ; alle Bits auf "1", EOR geht nur unter Registern
EOR Reg_A, Reg_B ; EOR geht nur unter Registern
STS New_In, Reg_A ; nun ist ein betätigter Schalter auch "1"
; und in einer Variablen abgelegt.
Natürlich kann man auch erst verschiedene Bits "einsammeln" und einer
Variablen zuorden. Anschließend wird der Inhalt der Variable wie im
Beispiel "gedreht".
Mit diesen Bits machst du nun in deiner Programmschleife die
Bearbeitung. Dabei ist auch hier auf kleine Programmblöcke zu achten,
die mit RCALL aufgerufen werden. Gib unterwegs nicht mal hier und mal da
etwas aus, sondern sammle auch hier erst Bits in einer Variablen, die
dun dann am Ende der Programmschleife in einem eigenen Block den
Ausgangsbits zuweist. Auch dies ist später bei Änderungen übersichtlich.
Grad wenn man Anfänger ist, sind meiner Meinung nach grad diese Hinweise
auf kleine Programmblöcke und ausgiebige Nutzung von Unterprogrammen
wichtig.
Gruß oldmax