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


von Gerald H. (gerald_h)


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:
1
timer0_overflow:      ; Timer 0 Overflow Handler
2
  rcall storeToStack
3
  
4
  ldi outpin, PIND7
5
  rcall toggle
6
  
7
  rcall restoreFromStack
8
  reti
9
10
toggle:
11
  sbic PIND, outpin
12
  rjmp Off
13
  sbis PIND, outpin
14
  rjmp On
15
toggle_end:
16
  ret
17
18
On:
19
  sbi PORTD, outpin
20
  rjmp toggle_end
21
22
Off:
23
  cbi PORTD, outpin
24
  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?

von spess53 (Gast)


Lesenswert?

Hi

Übergib dem Unterprogramm einfach die Bitmaske
1
  ldi r16,1<<Pin
2
  rcall toggle
3
4
5
toggle: in r17,PORTD
6
        eor r17,r16
7
        out PORD,r17
8
        ret

fertig.

MfG Spess

von Gerald H. (gerald_h)


Lesenswert?

Hi Spess,

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

Danke!

Gruß Gerald

von Gerald H. (gerald_h)


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:
1
ldi r18, PORTD
2
ldi r16,1<<Pin
3
rcall toggle
4
5
toggle: in r17,r18
6
        eor r17,r16
7
        out r18,r17
8
        ret

Hat jemand einen Tipp?

Gruß Gerald

von Ich (Gast)


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.

von Ich (Gast)


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.

von spess53 (Gast)


Lesenswert?

Hi

>Hat jemand einen Tipp?

Bei out und in kein Register zum Adressieren verwenden. Eine Möglichkeit 
wäre:
1
        ...
2
        ldi ZL, Low(PortD+$20)  ; Speicheradresse vom Port
3
        ldi ZH,High(PortD+$20)
4
        ldi r16,1<<1<<Pin
5
        rcall toggle
6
        ...
7
8
toggle: ld r17,Z
9
        eor r17,r16
10
        st Z,r17
11
        ret

Geht auch mit X und Y.

MfG Spess

von spess53 (Gast)


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

von Ich (Gast)


Lesenswert?

Als Code sähe das dann so aus:
1
toggle:
2
cpi r18, PORTA
3
brne toggle_1
4
in r17, PINA
5
rjmp toggle_5
6
toggle_1:
7
cpi r18, PORTB
8
brne toggle_2
9
in r17, PINB
10
rjmp toggle_5
11
toggle_2:
12
cpi r18, PORTC
13
brne toggle_3
14
in r17, PINC
15
rjmp toggle_5
16
toggle_4:
17
cpi r18, PORTD
18
brne toggle_error
19
in r17, PIND
20
rjmp toggle_5
21
22
toggle_5:
23
eor r17, r16
24
25
cpi r18, PORTA
26
brne toggle_6
27
out PORTA, r17
28
rjmp toggle_end
29
toggle_6:
30
cpi r18, PORTB
31
brne toggle_7
32
out PORTB, r17
33
rjmp toggle_end
34
toggle_7:
35
cpi r18, PORTC
36
brne toggle_8
37
out PORTC, r17
38
rjmp toggle_end
39
toggle_8:
40
cpi r18, PORTD
41
brne toggle_error
42
out PORTD, r17
43
rjmp toggle_end
44
45
toggle_error:
46
toggle_end:
47
ret

von Ich (Gast)


Lesenswert?

@spess53

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.