Forum: Compiler & IDEs _SFR_IO_ADDR() ATMEGA2560


von Christoph (Gast)


Lesenswert?

Hallo

ich möchte gern dies tun

set_loop:
sbic _SFR_IO_ADDR(PORTH),PH2
rjmp set_loop
out  _SFR_IO_ADDR(PORTA), 24
ret

es lässt sich aber nur so
set_loop:
sbic _SFR_IO_ADDR(PORTA - PORTG),PH2
rjmp set_loop
out  _SFR_IO_ADDR(PORTA - PORTG), 24
ret

kompilieren. PORTH und für PORTS aufwärts funktioniert es nicht

es kommt die meldung

switch.S:13: Error: number must be less than 32

Wo liegt mein Problem??? Schonmal Danke !!!!




von Johannes M. (johnny-m)


Lesenswert?

Dein Problem liegt darin, dass der sbic-Befehl nur für die unteren 32 
I/O-Register funktioniert (Register-Adressen bis 0x1F bzw. RAM-Adressen 
bis 0x3F). in/out gehen mit den unteren 64 I/O-Registern. Darüberhinaus 
(extended I/O-Space, Register mit RAM-Adressen ab 0x60) nur mit lds/sts. 
Schau Dir bitte im Instruction Set Manual die Bereiche für die Parameter 
der einzelnen Befehle an.

von Christoph (Gast)


Lesenswert?

Danke für die Schnelle Antwort


Also muss ich erst aus dem I/O Register die Werte auslesen und dananch 
ein Compare machen. Sehe ich das richtig.

von Johannes M. (johnny-m)


Lesenswert?

Christoph wrote:
> Danke für die Schnelle Antwort
>
>
> Also muss ich erst aus dem I/O Register die Werte auslesen und dananch
> ein Compare machen. Sehe ich das richtig.
Genau. Die Portregister für Port A-G liegen alle bei Adressen kleiner 
als 0x1F, weshalb mit denen alle Bitoperationen direkt (also über die 
Assembler-Befehle wie z.B. sbic) durchführbar sind. Die Register von 
Port H-L liegen allesamt im extended I/O Space und müssen erst mit lds 
in ein Rechenregister geholt werden, bevor irgendwelche Vergleiche oder 
Änderungen vorgenommen werden können.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, du kannst danach auch sbrs/sbrc benutzen, das sind die
Äquivalente zu sbis/sbic.  Aber das Prinzip bleibt, du musst
die Werte erst einmal vom Port in Register lesen.

von Christoph (Gast)


Lesenswert?

Ok danke für Eure Hilfe !!!

von Christoph (Gast)


Lesenswert?

Kurze Frage noch wieso geht das nicht ?

workreg = 16
.global set_fast_j4
.func set_fast_j4
set_fast_j4:
          lds workreg,_SFR_IO_ADDR(PINH)
    sbrc workreg,PH2
    rjmp set_fast_j4
    out _SFR_IO_ADDR(PORTG), 24
    ret
.endfunc

Danke

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

out _SFR_IO_ADDR(PORTG), 24

ist ein Synonym für

out _SFR_IO_ADDR(PORTG), r24

und damit vermutlich nicht das, was du willst.

Folgendes Stück C-Code:
1
#include <avr/io.h>
2
3
void set_fast_j4(void)
4
{
5
        while (PINH & _BV(PH2))
6
                ;
7
        PORTG = 24;
8
}

übersetzt der Compiler zu:
1
.global set_fast_j4
2
        .type   set_fast_j4, @function
3
set_fast_j4:
4
/* prologue: frame size=0 */
5
/* prologue end (size=0) */
6
.L3:
7
        lds r24,256
8
        sbrc r24,2
9
        rjmp .L3
10
        ldi r24,lo8(24)
11
        out 52-0x20,r24
12
/* epilogue: frame size=0 */
13
        ret
14
/* epilogue end (size=1) */

Ich verstehe gar nicht, warum du das unbedingt zu Fuss in Assembler
hacken willst...

von Christoph (Gast)


Lesenswert?

Hallo Jörg,

ich möchte es nicht unbedingt zu Fuß machen ich muss mir aber sicher 
sein wie lange der Controller benötigt um zu Pollen deswegen wollte ich 
die Geschichte in Assembler schreiben. Es geht für diese Anwendung 
tatsächlich im Bereich von ns. Leider steht mir bei der Karte keine 
Interruptleitung zur Verfügung. Mein Gedanke war folgender

- in C -Wert per UART übergeben berechnen und übergeben an 
Assemblerfunktion
- Zeit bis hierhin muss ich als Offset herausbekommen(Messen)
- übergeben aus dem C-Code extern void set_fast(uint8_t value); an ASM

- im Assemblerfile Pollen(PH3 bzw. PH2 für ret ) und den übergebenen 
Wert(value) so schnell wie möglich an den Port schreiben( 6 Cycles ) 
müssten es dann sein.
Deswegen mache ich mir solche Mühe mit der Sache. Meinst du kürzer als 
der Compiler würde man es eh nicht schaffen ? Dann lass ich es gern mit 
Assembler! Bin für jede Möglichkeit offen Zeit zu sparen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christoph wrote:

> Meinst du kürzer als
> der Compiler würde man es eh nicht schaffen ?

Siehe oben: ja.  Ist mit -Os compiliert, aber das sollte egal sein,
solange du überhaupt irgendeine Optimierung hast.

von katzeklo (Gast)


Lesenswert?

> sbic _SFR_IO_ADDR(PORTH),PH2

Was ist das denn für ein Syntax? Geht es nicht mehr mit

sbic    PORTH, PH2

?

von Jörg X. (Gast)


Lesenswert?

>> Geht es nicht mehr mit
>  sbic  PORTH, PH2

nicht im _inline_-Assembler des (AVR-)GCC :(
hth. Jörg

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.