mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik avr asm rollen einsteigerhilfe


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich bin gerade dabei mir assembler für avrs anzueignen. dazu wollte ich 
ein wenig mit den leds des stk500 spielen.
Ich würde die leds gerne von aussen nach innen rotieren lassen, aber von 
beiden seite, ungefähr so:

x------x         x = led an
-x----x-         - = led aus
--x--x--
---xx---
---xx---
--x--x--
-x----x-
x------x

dabei bin ich auf folgende zwei probleme gestossen:
1. Wie rotiere ich nur ein bit durch ein register? (wenn ich rol oder 
ror aufrufe, gehen alle leds nacheinander an)
2. Wie lasse ich nur die unteren bzw oberen 4 Bit des registers 
rotieren(ich muss ja unten nach links schieben und die oberen rechts)

hier meine interrupt routine:
schieben_leds:
  push   temp;temp speichern

  clr  mili ;milisekunden zähler zurücksetzen

  mov   temp, leds;register leds in temp laden
  ror   temp;temp nach recht schieben
  mov   leds, temp;geschobenes temp zurück in leds laden
  out   PORTB, leds;ausgabe des led registers

  pop   temp;temp laden

Autor: Sigint 112 (sigint)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Markus,
  sowas machst du am einfachsten mit Tabellen in denen du die Bitmuster 
ablegst. Schiebeoperationen sind dafür zu umständlich.

Gruß,
  SIGINT

Autor: Steven () (ovular) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/AVR-Tutori...

Nur noch ein Zähler, der von 0-7 oder 8 zählen kann und fertig

Ach ja in den Zweigen schreibst du einfach was wie:
zweig_3:    ldi temp2, 0b001000100  rjmp ende_vergleich
zweig_4:    ldi temp2, 0b.....

MfG Steven

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das funktioniert nicht...

ich denke mal ich mach auch irgendwas falsch

.include "m16def.inc"

.def leds = r16
.def temp = r17
.def mili = r18
.def sek  = r19
.def status = r20
.def temp2 = r21
.equ minimum = 3
.equ maximum = 7

.org 0x00
  rjmp main
.org OVF0addr
  rjmp schieben

main:
  ldi     temp, LOW(RAMEND)  ; Stackpointer initialisieren
  out     SPL, temp
  ldi     temp, HIGH(RAMEND)
  out     SPH, temp
  ldi   leds, 0xFF       ; lade Arbeitsregister r16 mit der Konstanten 
0xFF
  out   DDRB, leds       ; Inhalt von r16 ins IO-Register DDRB ausgeben
  ldi   leds, 0xfe ; 0b11111100 in r16 laden
  out   PORTB, leds      ; r16 ins IO-Register PORTB ausgeben
  ldi     temp, 1 << CS02
    out     TCCR0, temp
  ldi     temp, 1 << TOIE0
    out     TIMSK, temp
  sei
  rjmp   loop
schieben:
   push    temp               ; temp 1 sichern

    in      temp,sreg          ; SREG sichern
    push    temp
  inc   mili
  ldi   temp, 0x0F
  cp    mili, temp

  breq   schieben_leds

  rjmp  end_tim_ovf0
schieben_leds:
  push   temp

  clr    mili
  subi    temp,minimum                 ; Nullpunkt verschieben
    cpi     temp,(maximum-minimum+1)     ; Index auf Maximum prüfen
    brsh    end_tim_ovf0                ; Index zu gross -> Fehler
    ldi     ZL,low(Mustertabelle)       ; Tabellenzeiger laden, 16 Bit
    ldi     ZH,high(Mustertabelle)
    add     ZL,temp                      ; Index addieren, 16 Bit
    ldi     temp,0
    adc     ZH,temp
    ijmp

  out   PORTB, leds     ; aktualisieren

  pop   temp
end_tim_ovf0:
  pop     temp
    out     sreg,temp         ; sreg wieder herstellen
    pop     temp
  reti
Mustertabelle:
    rjmp    m0
    rjmp    m1
    rjmp    m2
    rjmp    m3
m0:
  ldi  leds, 0b10000001
  ret
m1:
  ldi  leds, 0b01000010
  ret
m2:
  ldi  leds, 0b00100100
  ret
m3:
  ldi  leds, 0b00011000
  ret
loop:
  rjmp   loop           ; Sprung zur Marke "ende" -> Endlosschleife

Autor: Steven () (ovular) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja man veröffentlicht sowas als Anhang!

Wo ist da jetzt der Unterschied?

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie meinen unterschied?
es passiert rein garnichts...

Autor: Steven () (ovular) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja nur 2,3 Befehle reichen halt auch nicht. Das ist mir schon klar.
Aber du hast das doch ganz gut hinbekommen. So in der Art meinte ich es.

Ich hab meine Sammlung leider nicht da, aber ich kann dir ja morgen früh 
mal ein Beispiel von mir geben, wenn du willst.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja aber es passiert gar nichts...

das mit dem beispiel wäre nett.
in c würde ich mir jetzt einen char array anlegen und den durchgehen. 
ist sowas auch in assembler möglich?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also... das mit der sprungtabelle funktioniert jetzt so weit.
aber das programm springt immer nur in m2. warum?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>in c würde ich mir jetzt einen char array anlegen und den durchgehen.

In Assembler(und binär):

Leds:   .db 0b10000001,0b01000010
        .db 0b00100100,0b00011000
        .db 0b00011000,0b00100100
        .db 0b01000010,0b10000001

Zugriff mit:
        ldi ZL,Low(leds<<1)
        ldi ZH,High(leds<<1)
        add ZL,Offset  ;Offset: in Register rxy
        adc ZH,NULL    ;NULL: Register mit 0 geladen
        lpm ry,Z

Das Register Offset musst du in deinem Programm errechnen.

Wenn du Z nicht weiter brauchst:
        ldi ZL,Low(leds<<1)
        ldi ZH,High(leds<<1)
        lpm tyx,Z+
    Jetzt sollte Enderkennung kommen

MfG Spess


PS@ Falk: Das ist aber nur die halbe Wahrheit.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke

Autor: Herr Mueller (herrmueller)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht auch ohne Tabelle:

M2:
  ldi Hilf,$01
  ldi Hilf2,$80
  ldi temp,8      ; 8mal

M1:  ldi Muster,$00
  or Muster,Hilf
  or Muster,Hilf2
  com Muster      ; für STK500 invertieren
  out PortB, Muster
  rcall delay05s
  lsr Hilf2
  lsl Hilf
  dec temp
  brne M1
  rjmp M2


Hilf2 wird nach rechts geschoben und Hilf nach links und die Bits 
jeweils mit "oder" in Muster gesetzt.

Autor: Steven () (ovular) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
>ja aber es passiert gar nichts
geh mir nicht auf dem Keks!!! Das ginge, wenn du wüsstest was ich meine!

Im Anhang ein Programm mit einer Tabelle, das 2 LEDs zeigt, die in einen 
dunklen Raum gehen, dann aber Angst bekommen und zurückrennen.

MfG Steven

Autor: Kachel - Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cool, aber echt umständlich...

IJMP und ICALL sind verdammt starke und auch sehr nützliche Befehle, 
aber für diesen Zweck einfach Unfug (zuviel Overhead).

Es ist je nach Zählerstand ein anderes Bitmuster an den Port auszugeben. 
Dies erreicht man am einfachsten mittels LPM über den Z-Pointer. Das 
Verfahren wurde bereits von Spess53 beschrieben, weshalb ich mir jetzt 
ein weiteres Beispiel spare.

KH

Autor: Steven () (ovular) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok scheint einfacher zu sein. Werd ich beim nächsten Mal 
berücksichtigen.
Danke!

MfG Steven

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.