Bits aus Register laden

OP #1605005
Lesenswert?

Hallo,
ich möchte aus Datensegmenten (.dw 0b1101010), Stück für Stück die Bits 
auslesen, damit ich sie über >einen Pin< ausgeben kann.

Wie kann ich das machen in Assembler?
Das Tutorial hilft da nicht...
Und wenn es in der Datensammlung zu finden ist, wo finde ich diese?
#1605010
Lesenswert?

Sören Timm schrieb:
> Hallo,
> ich möchte aus Datensegmenten (.dw 0b1101010), Stück für Stück die Bits
> auslesen, damit ich sie über >einen Pin< ausgeben kann.
>
> Wie kann ich das machen in Assembler?
> Das Tutorial hilft da nicht...
> Und wenn es in der Datensammlung zu finden ist, wo finde ich diese?


Vielleicht einfach mal logisch schieben und jeweils das LSB nehmen?!? 
Solche Grundlagen werden im AVR-Tutorial behandelt...


Volker
Gast #1605033
Lesenswert?

Hi

>Aber wie könnte ich den jeden einzelnen Bit aus dem Datenbereich nach
>und nach in die T-Flag schieben?

Über Register.

LDS r16, Speicher
in r17,Portx
bst r16,n
bld r17,m
out r17,Portx

Wenn die Bits schon in der richtigen Reihenfolge vorliegen ist Schieben 
allerdings günstiger.

MfG Spess
#1605037
Lesenswert?

1
.equ    spi_port = portb
2
.equ    spi_dout = pb1
3
.equ    spi_ck = pb2
4

5
;input: r16 = byte
6
spi_out:
7
        sec                             ; r16 = 0 after 8 * shift
8
_spi1:
9
        cbi     spi_port, spi_dout
10
        sbrc    r16, 0                  ; LSB first
11
        sbi     spi_port, spi_dout
12
        cbi     spi_port, spi_ck
13
        sbi     spi_port, spi_ck
14
        lsr     r16
15
        brne    _spi1
16
        ret

Das nennt sich auch SPI.


Peter
Gast #1605049
Lesenswert?

im Beispiel wird das MSB (oberstes bit) überprüft:

(wert in r17 an PORTD4 rausschieben)

  ld  r17, 0b1101010   ;dein beispielwert
  ldi r16, 8           ;Zähler für durchläufe
naechstes_bit:
  sbrs r17, 7          ;falls MSB=1, überspringe
   cbi PORTD, 4            ;PD4 loeschen
  sbrc r17, 7          ;falls MSB=0, überspringe
   sbi PORTD, 4            ;PD4 setzen

  lsl r17              ;schieben für weiteren Durchlauf

  dec r16
  brne naechstes_bit

;weiter im programm
Gast #1605052
Lesenswert?

Hi

>Wie ist das denn mit dem schieben gemeint?

Dafür gibt es die Befehle z.B. 'lsl' - Linksschieben und 
'lsr'-Rechtsschieben.
1
      lds r16,Speicher
2
      in r17,PortX
3
      ldi r18,8
4
aaa:  cbi r17,n         ; Bit löschen
5
      sbrc r16,0        
6
      sbi r17,n         ; Wenn Bit=1         
7
      out PortX,r17     ; Ausgeben
8
      lsl r16           ; nächstes Bit
9
      dec r18           ; alle Bits?  
10
      brne aaa

MfG Spess
Gast #1605131
Lesenswert?

Hi

Ups. 'cbi' und sbi' sollten eigentlich 'cbr' und 'sbr' mit '1<<n' sein.

'cbi' und sbi' sind nur für IO-Adressen 0..31 anwendbar. 'in/out' im 
Bereich 0..63. Darüber statt 'in/out' 'lds/sts' benutzen.

>Warum wird erst ein Port eingelesen?

Um die anderen Portpins nicht zu beeinflussen.
1
      lds r16,Speicher
2
      in r17,PortX
3
      ldi r18,8
4
aaa:  cbr r17,1<<n      ; Bit löschen
5
      sbrc r16,0        
6
      sbr r17,1<<n      ; Wenn Bit=1         
7
      out PortX,r17     ; Ausgeben
8
      lsr r16           ; nächstes Bit
9
      dec r18           ; alle Bits?  
10
      brne aaa
11
      ....

Variante mit 'cbi/sbi':
1
      lds r16,Speicher
2
      ldi r18,8
3
aaa:  lsr r16           ; Bit0 von r16 ins Carry-Flag
4
      brcs bbb          ; wenn 1
5
      cbi PortX,n       ; wenn 0
6
      rjmp ccc
7
bbb:  sbi PortX,n
8
ccc:  dec r18           ; alle Bits?  
9
      brne aaa
10
      ....

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren