Forum: Mikrocontroller und Digitale Elektronik Was bedeutet _SFR_IO8


von Kürbis (Gast)


Lesenswert?

Guten Morgen,
eine dumme Frage aber ich finde keine Antwort.
Wenn ich mir die Defines von den Hardware Registern zum Beispiel
1
#define DDRB    _SFR_IO8(0x17)
ansehe kommt dieses _SFR_IO8 vor dahinter dann die Adresse.
Ist das so eine Art Pointer?
Oder anders gefragt wie würde man den Zugriff auf auf PORTB mit einen 
Pointer realisieren?
Danke für die Hilfe

von g457 (Gast)


Lesenswert?

> Oder anders gefragt wie würde man den Zugriff auf auf PORTB mit einen
> Pointer realisieren?

Den Zugriff auf das Register PORTB realisiert man indem man das dafür 
vorgesehene Define PORTB dafür benutzt. Das war jetzt einfach.

HTH

von Selbstgucken macht schlau (Gast)


Lesenswert?

Jede IDE, die auch nur einen Hauch Selbstrespekt hat, bietet eine 
Funktion an, zur Definition/Deklaration eines Symbols bzw. Macros zu 
springen.

Also kannst Du Dir einfach selbst ansehen, was sich in Deiner 
ungenannten "toolchain" hinter dem Macro _SFR_IO8 verbirgt.

von Stefan F. (Gast)


Lesenswert?

In einer halbwegs anständigen IDE brauchst du nur mit gedrückter 
Strg-Taste auf das Makro klicken, dann siehst du dessen Quelltext, 
woraus sich ergibt, was es bedeutet.
1
#ifndef __SFR_OFFSET
2
/* Define as 0 before including this file for compatibility with old asm
3
   sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
4
#  if __AVR_ARCH__ >= 100
5
#    define __SFR_OFFSET 0x00
6
#  else
7
#    define __SFR_OFFSET 0x20
8
#  endif
9
#endif
10
11
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)

Offenbar wird da bei einigen AVR Architekturen schlicht 0x20 zur Adresse 
des Registers addiert.

von void (Gast)


Lesenswert?

Kürbis schrieb:
> Ist das so eine Art Pointer?

https://electronics.stackexchange.com/questions/463585/what-does-sfr-io80x04-do-avr

Ist ein Makro (Define) mit einem Pointer.
(*(volatile uint8_t *)(mem_addr))

von Stefan F. (Gast)


Lesenswert?

Ich sehe gerade, dass ich im falschen Abschnitt der Datei geguckt habe. 
Korrektur:
1
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
2
3
#ifndef __SFR_OFFSET
4
#  if __AVR_ARCH__ >= 100
5
#    define __SFR_OFFSET 0x00
6
#  else
7
#    define __SFR_OFFSET 0x20
8
#  endif
9
#endif
10
11
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

Zusätzlich zu dem Offset wird das Argument wohl noch als "volatile 
uint8_t *" gekennzeichnet, was Sinn ergibt, denn es sind ja Zeiger auf 8 
Bit Register. Volatile deswegen, weil der Compiler Zugriffe nicht weg 
optimieren soll. Wenn jemand im Programmcode dreimal schreibt, soll das 
auch dreimal im Register ankommen, nicht nur der letzte Wert. Und wer 
dreimal liest, will wirklich dreimal aus dem Register/Port lesen, nicht 
nur einmal und dann den selben Wert 2x wieder verwenden.

von Kürbis (Gast)


Lesenswert?

Ich verwende das Atmel studio.
Leider löst mir das Atmelstudio das _SFR_IO8 nicht auf

g457 schrieb:
> Den Zugriff auf das Register PORTB realisiert man indem man das dafür
> vorgesehene Define PORTB dafür benutzt. Das war jetzt einfach.

Das weiß ich.
Die Frage war aber wie man es machen könnte wenn man einen Pointer 
nehmen möchte?
Danke für die Hilfe

von Stefan F. (Gast)


Lesenswert?

Kürbis schrieb:
> Die Frage war aber wie man es machen könnte wenn man einen Pointer
> nehmen möchte?

DDRB ist ein de-renzenzierter Zeiger mit der Adresse des DDRB Registers.

&DDRB ist die Adresse von DDRB, bzw ein Zeiger auf das Register.

Indem du ein & voran stellst, neutralisiert du das erste Sternchen in 
dem Ausdruck

> (*(volatile uint8_t *)(mem_addr))

Daraus wird dann praktisch:

(volatile uint8_t *)(mem_addr)

Also ein Zeiger auf ein uint8_t

von Yalu X. (yalu) (Moderator)


Lesenswert?

Kürbis schrieb:
> Ich verwende das Atmel studio.
> Leider löst mir das Atmelstudio das _SFR_IO8 nicht auf

Man kann das ganz klassisch auch manuell herausfinden. Die _SFR_*-Makros
sind in <avr/sfr_defs.h> definiert.

: Bearbeitet durch Moderator
von Stefan F. (Gast)


Lesenswert?

Yalu X. schrieb:
> Man kann das ganz klassisch auch manuell herausfinden. Die _SFR_*-Makros
> sind in <avr/sfr_defs.h> definiert.

Dazu muss man erst wissen, in welche Datei das steht. Die Suchfunktion 
von Windows ist bei solch trivialen Sachen ja leider eher irreführend 
als verlässlich.

Gut, dass es für jeden Furz Programme zum Downloaden gibt.

von Kürbis (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Yalu X. schrieb:
>> Man kann das ganz klassisch auch manuell herausfinden. Die _SFR_*-Makros
>> sind in <avr/sfr_defs.h> definiert.
>
> Dazu muss man erst wissen, in welche Datei das steht. Die Suchfunktion
> von Windows ist bei solch trivialen Sachen ja leider eher irreführend
> als verlässlich.
>
> Gut, dass es für jeden Furz Programme zum Downloaden gibt.

wie meinst du das?

von Stefan F. (Gast)


Lesenswert?

Kürbis schrieb:
> Die Suchfunktion
>> von Windows ist bei solch trivialen Sachen ja leider eher irreführend
>> als verlässlich.
>> Gut, dass es für jeden Furz Programme zum Downloaden gibt.

> wie meinst du das?

Das der Dateimanager von Windows oft an solch trivialen Dingen wie 
Volltextsuche scheitert, und man zum Glück vernünftig funktionierende 
Programme von anderen Entwicklern downloaden kann.

Die Suchfunktion von Windows wurde in dem Moment verschlimmbessert, als 
Microsoft den Suchindex einführte. Ganz fies ist das in Kombination mit 
versteckten Plugins, die einige binäre Dateiformate indizieren. Das hat 
noch nie richtig funktioniert.

Frühe konnte man den Index einfach abschalten. Dann war die Suche zwar 
langsamer, dafür aber zuverlässig. Heute geht das nicht mehr, ohne Index 
ist die Suchfunktion noch kaputter, als mit.

Wenn der Dateimanager sagt "Rechnung 241414" wurde nicht gefunden, dass 
heißt das gar nichts. Selbst in Plain Text Dateien wie C Quelltexten 
übersieht die Suchfunktion vom Dateimanager viele Treffer.

von Kürbis (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Kürbis schrieb:
>> Die Frage war aber wie man es machen könnte wenn man einen Pointer
>> nehmen möchte?
>
> DDRB ist ein de-renzenzierter Zeiger mit der Adresse des DDRB Registers.
>
> &DDRB ist die Adresse von DDRB, bzw ein Zeiger auf das Register.
>
> Indem du ein & voran stellst, neutralisiert du das erste Sternchen in
> dem Ausdruck
>
>> (*(volatile uint8_t *)(mem_addr))
>
> Daraus wird dann praktisch:
>
> (volatile uint8_t *)(mem_addr)
>
> Also ein Zeiger auf ein uint8_t

Und wenn ich nur die Adresse angeben will ohne mit den & Operator drüber 
zu gehwn
Danke für die Hilfwe

von Stefan F. (Gast)


Lesenswert?

Kürbis schrieb:
> Und wenn ich nur die Adresse angeben will

Dann schreibst du

> volatile uint8_t *zeiger = 0x37;

oder:

> volatile uint8_t *zeiger = &DDRB;

Die Adresse des gewünschten Registers kannst du dem Datenblatt deines 
Mikrocontrollers entnehmen.

von Kürbis (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Kürbis schrieb:
>> Und wenn ich nur die Adresse angeben will
>
> Dann schreibst du
>
>> volatile uint8_t *zeiger = 0x37;
>
> oder:
>
>> volatile uint8_t *zeiger = &DDRB;
>
> Die Adresse des gewünschten Registers kannst du dem Datenblatt deines
> Mikrocontrollers entnehmen.

Danke für die Hilfe

von Axel S. (a-za-z0-9)


Lesenswert?

Kürbis schrieb:
> Die Frage war aber wie man es machen könnte wenn man einen Pointer
> nehmen möchte?

Man liest einfach die Anleitung und macht es dann so.

LMGTFY: https://www.google.com/search?&q=avr%20port%20pointer

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.