Forum: Compiler & IDEs GPIOR0-2 richtig nutzen


von ubbut (Gast)


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-Codeoptimierung
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

von Peter D. (peda)


Lesenswert?

Versuchs einfach mal mit Bitvariablen:
1
#include <avr\io.h>
2
//       Access bits like variables:
3
4
struct bits {
5
  uint8_t b0:1;
6
  uint8_t b1:1;
7
  uint8_t b2:1;
8
  uint8_t b3:1;
9
  uint8_t b4:1;
10
  uint8_t b5:1;
11
  uint8_t b6:1;
12
  uint8_t b7:1;
13
} __attribute__((__packed__));
14
15
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
16
#define  SBIT(x,y)  SBIT_(x,y)
17
18
#define blabla  SBIT( GPIOR0, 0 )
19
#define blublu  SBIT( GPIOR1, 7 )
20
#define blibli  SBIT( GPIOR2, 6 )
21
22
23
void test( void )
24
{
25
  blabla = 1;
26
  blublu = 0;
27
  blibli = 1;
28
29
  if( blabla && !blublu )
30
    blibli = 0;
31
}

Allerdings ist nur GPIOR0 bitadressierbar.


Peter

von Michael S. (Gast)


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.

von Peter D. (peda)


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

von ubbut (Gast)


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?

von (prx) A. K. (prx)


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.

von Michael S. (Gast)


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.

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.