www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Assemler PIN-Nummer an Subroutine übergeben


Autor: Gerald H. (gerald_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte genere in Assembler (Atmega16) in eine Subroutine die 
PIN-Nummer mittels eventuell eines Registers (oder habt ihr einen 
anderen Vorschlag) übergeben.
Also z.B. dachte ich mir sowas:
timer0_overflow:      ; Timer 0 Overflow Handler
  rcall storeToStack
  
  ldi outpin, PIND7
  rcall toggle
  
  rcall restoreFromStack
  reti

toggle:
  sbic PIND, outpin
  rjmp Off
  sbis PIND, outpin
  rjmp On
toggle_end:
  ret

On:
  sbi PORTD, outpin
  rjmp toggle_end

Off:
  cbi PORTD, outpin
  rjmp toggle_end

Jetzt meldet mir der Compiler aber in "toggle", "On" und "Off" bei 
verwendung von outpin jeweils "Invalid number": Dabei steht doch genauso 
eine 7 im Register (outpin) wie wenn ich PIND7 direkt anspreche.

Wie kann ich soetwas realisieren?
bzw. wie erweitere ich noch "toggle", sodass auch "PIND" außerhalb von 
"toggle" gesetzt werden kann, also so dass "toggle", etc. komplett 
generisch werden?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Übergib dem Unterprogramm einfach die Bitmaske
  ldi r16,1<<Pin
  rcall toggle


toggle: in r17,PORTD
        eor r17,r16
        out PORD,r17
        ret

fertig.

MfG Spess

Autor: Gerald H. (gerald_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Spess,

danke... irgendwie schon klar und logisch...
Die Lösung habe ich einfach nicht gesehen.

Danke!

Gruß Gerald

Autor: Gerald H. (gerald_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerald H. schrieb:
> Hi Spess,
>
> danke... irgendwie schon klar und logisch...
> Die Lösung habe ich einfach nicht gesehen.

Das bezog sich auf "PIND7"!

Doch eine Frage bleibt: Wie wie kann ich in dem Code von Spess denn noch 
PORTD ähnlich wie PIND7 ersetzen?

PORTD hat ja die Adresse 0x12 und wenn ich die in ein Register kopiere 
und dann das Register anstelle von PORTD verwende, sagt der Compiler 
schon eine "invalid number".

Also so ich möchte gerne sowas machen:
ldi r18, PORTD
ldi r16,1<<Pin
rcall toggle

toggle: in r17,r18
        eor r17,r16
        out r18,r17
        ret

Hat jemand einen Tipp?

Gruß Gerald

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine erste Lösung geht nicht, da der Pin bei sbi und cbi immer konstant 
sein muss.
Bei der zweiten Lösung ist das Problem, dass der Port bei in und out 
immer konstant sein muss.
Ich weiß was du machen willst, deine Funktion toggle soll auf alle Ports 
gehen. So eine Lösung ist mit den AVRs aber nicht möglich.

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest höchstens in "toggle" feste Befehle (in r16, PORTA; in r16, 
PORTB; ...) machen, von denen durch eine Fallunterscheidung zwischen den 
Ports immer nur einer ausgeführt wird.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Hat jemand einen Tipp?

Bei out und in kein Register zum Adressieren verwenden. Eine Möglichkeit 
wäre:
        ...
        ldi ZL, Low(PortD+$20)  ; Speicheradresse vom Port
        ldi ZH,High(PortD+$20)
        ldi r16,1<<1<<Pin
        rcall toggle
        ...

toggle: ld r17,Z
        eor r17,r16
        st Z,r17
        ret

Geht auch mit X und Y.

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Bei out und in kein Register zum Adressieren verwenden.

Entschuldige. Soll heissen:

'Bei out und in kann man kein Register zum Adressieren verwenden.'

MfG Spess

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Code sähe das dann so aus:
toggle:
cpi r18, PORTA
brne toggle_1
in r17, PINA
rjmp toggle_5
toggle_1:
cpi r18, PORTB
brne toggle_2
in r17, PINB
rjmp toggle_5
toggle_2:
cpi r18, PORTC
brne toggle_3
in r17, PINC
rjmp toggle_5
toggle_4:
cpi r18, PORTD
brne toggle_error
in r17, PIND
rjmp toggle_5

toggle_5:
eor r17, r16

cpi r18, PORTA
brne toggle_6
out PORTA, r17
rjmp toggle_end
toggle_6:
cpi r18, PORTB
brne toggle_7
out PORTB, r17
rjmp toggle_end
toggle_7:
cpi r18, PORTC
brne toggle_8
out PORTC, r17
rjmp toggle_end
toggle_8:
cpi r18, PORTD
brne toggle_error
out PORTD, r17
rjmp toggle_end

toggle_error:
toggle_end:
ret

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@spess53

Ok, das mit dem Z-Pointer war mir neu.
Ist natürlich besser.

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.