www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bit Verknüpfung


Autor: Sam700 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
; Start, Power ON, Reset
main:    ldi     r16, lo8(RAMEND)
         out     SPL, r16
         ldi     r16, hi8(RAMEND)
         out     SPH, r16
         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)
         sbi  DDRB,2          ;Port B.1 Aus ausgang einestellt
         ; Hier Init-Code eintragen.
;---------------------------------------------------------------------------
mainloop: wdr
          ldi  r16 , 0         ;lade Register R16 mit 0 damit die LED auch aus geht 
          in  r17 , PINB         ;Lese PINB ein 
          andi    r17,0b11        ; prüfe Bit #0 und #1 in r17
          cpi     r17,0b11        
         breq    A1          ;Wenn bedingung gegeben dann Springen auf A1 
         
          out   PORTB , r16  
          rjmp mainloop
 A1:      ldi  r16, 0b0000011      ; Wenn der taster nicht geshaltet ist überspringe nächsten schritt
          out   PORTB , r16        ;Ausgabe PortB
          rjmp mainloop
;---------------------------------------------------------------------------

Ich danke schon mal....

Sam

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
:-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Sam700 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16
    cpi     r16,0b1010
    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 :)

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
:-)

Autor: Sam700 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal

So ich hbe meinen Fehler gefunden.
Wie es scheint habe ich einen Fehler ind en Sprungmarken gemacht.
So geht das :
mainloop: wdr
          ldi  r16 , 0x0         ;lade Register R16 mit 0 damit die LED auch aus geht 
          in  r17 , PINB         ;Lese PINB ein 
          andi    r17, 0x3              ; prüfe Bit #0 und #1 in r17
         breq    A1          ;Wenn bedingung gegeben dann Springen auf A1 
          ldi  r16, 0b000100      ; Wenn der taster nicht geshaltet ist überspringe nächsten schritt
  A1:     out   PORTB , r16        ;Ausgabe PortB
          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

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.