www.mikrocontroller.net

Forum: Compiler & IDEs GPIOR0-2 richtig nutzen


Autor: ubbut (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

MCU: ATMega168, GCC

habe in meinem Code 3 globale Flags, bei denen ich nur Bits schreibe, 
lösche und abfrage.

Wollte meinen Code nun hinsichtlich Geschwindigkeit und Größe optimieren 
und die GPIOR0-2 register nutzen.

Habe es zunächst so probiert:

#define flags1 GPIOR0
#define flags2 GPIOR1
#define flags3 GPIOR2

dadurch wurde der Code sogar leicht größer!

Habe dann hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Co...
gelsen und das ganze so probiert

register uint8_t counter8_1 asm("r2");

das ist offensichtlich falsch, ich erhalte die fehlermeldung:
invalid register name for 'flags1'

wie geht es richtig?

dankeschön

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs einfach mal mit Bitvariablen:

#include <avr\io.h>
//       Access bits like variables:

struct bits {
  uint8_t b0:1;
  uint8_t b1:1;
  uint8_t b2:1;
  uint8_t b3:1;
  uint8_t b4:1;
  uint8_t b5:1;
  uint8_t b6:1;
  uint8_t b7:1;
} __attribute__((__packed__));

#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
#define  SBIT(x,y)  SBIT_(x,y)

#define blabla  SBIT( GPIOR0, 0 )
#define blublu  SBIT( GPIOR1, 7 )
#define blibli  SBIT( GPIOR2, 6 )


void test( void )
{
  blabla = 1;
  blublu = 0;
  blibli = 1;

  if( blabla && !blublu )
    blibli = 0;
}

Allerdings ist nur GPIOR0 bitadressierbar.


Peter

Autor: Michael S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Peter
> Allerdings ist nur GPIOR0 bitadressierbar.

Kannst du das erläutern ?
Wenn ich in Assembler denke, dann sieht doch der Mechanismus so aus:

IN  R16, GPIORx
Register R16 manipulieren und dann ggf.:
OUT GPIORx, R16

oder die direkte Abfrage eines einzelnen Bits mit

SBIS  GPIORx, y  ; Skip if Bit.y in I/O Register is set
SBIC  GPIORx, y  ; Skip if Bit.y in I/O Register is cleared

(mit der Einschränkung, dass dies nur mit I/O Adresse 0-31 funktioniert,
beim attiny25 liegen GPIOR0 - GPIOR2 bei 0x11 - 0x13, sollte also 
funktionieren)

Habe ich da Wesentliches übersehen ?

@ ubbut

Ich verwende auch gerne freie I/O-Register als volatile-Variablen,
denn bezahlt habe ich sie schließlich.
Das gewinnt einige zusätzliche Bytes - die nebenbei noch schnell im 
Zugriff sind.
Nach meiner Erinnerung wurde der Programmcode dadurch auch immer kürzer.
Probleme hatte ich immer mit den neuern mc's, wenn ich z.B. Timer 
explizit
im Register PRR abgeschaltet habe - dann waren die zugehörigen Register 
nicht mehr nutzbar.

mfg

Michael S.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael S. wrote:

> (mit der Einschränkung, dass dies nur mit I/O Adresse 0-31 funktioniert,
> beim attiny25 liegen GPIOR0 - GPIOR2 bei 0x11 - 0x13, sollte also
> funktionieren)

Es ging aber um den ATMega168.


Peter

Autor: ubbut (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe gerade nochmal rumprobiert und zwar nicht die Lösung, aber 
zumindest wahrscheinlich den Grund dafür gefunden, dass mein Code größer 
wird.

Beim ersetzen von zwei Flag Variablen durch die GPIORx regiter wird der 
Code tatsächlich kleiner, bei einer bestimmten aber erheblich größer.

Die entsprechende Variable verwende ich im Code stellenweise auch so:

array[1 & flag_variable]

könnte das der Grund sein?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Hauptgrund dürfte darin liegen, dass die GPIORx wahrscheinlich wie 
alle anderen I/O-Register "volatile" sind, und daher nicht auf 
CPU-Register optimiert werden. Bei Operationen wie "Bit setzen" und "Bit 
abfragen" stört das nicht. Bei anderen hingegen schon.

Autor: Michael S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Peter,

stimmt auffallend.
Für meine Zwecke sind die Tinys meist völlig ausreichend.
Bei den Megas macht der Einsatz von I/O-Registern offensichtlich keinen 
rechten Sinn mehr, der Speichergewinn in nicht nennenswert - und die 
Vorteile im einfacheren Zugriff entfallen.
Beim Mega168 liegen ausser PORTD und GPIOR0 tatsächlich alle Register 
oberhalb der Adresse 31.
Man lernt halt immer wieder dazu.

Michael S.

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.