_SFR_IO_ADDR() ATMEGA2560

Gast #584429
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 !!!!



#584436
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.
#584452
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.
Gast #585265
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
Moderator Persönliche Seite #585285
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...
Gast #585356
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

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