mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Variable Register


Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,


ich verwende einen ATmega16 und den GCC. Kann mir jemand sagen wie ich 
eine Variable z.B. unsigned char x, auf die Speicheradresse des PORTB 
zugreifen lassen kann.

Ich kenne das nur vom PIC und CCS.

z.B. #byte x=0x44;  z.B.

Danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Ports sind aus C-Sicht wie ganz normale Variablen
zu benutzen:

  x = PORTB;

  PORTB = 5;
  PORTB = a;


http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort:

Wie kann ich der Variablen z.B. x die Adresse z.B. von PORB geben?

Das wäre noch interessant für mich.

Danke

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre nur mit viel Aufwand und einem Linkerskript möglich, lässt sich 
aber mit einem #define viel einfacher hinpfuschen:

   #define MeineVariable PORTB

Allerdings ist von beiden Vorgehensweisen DEUTLICH abzuraten. Warum soll 
man im Sourcecode Portzugriffe verschleiern? Was spricht dagegen, PORTB 
auch so zu nennen?

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mein eigentliches Problem ist folgendes:

/*********************************************************************** 
*********************
                                  Definitionen:
************************************************************************ 
*********************/
#ifndef F_CPU
#define F_CPU 4000000
#endif


typedef unsigned char byte;

typedef struct
              {
        unsigned char rs  :1;    //PB0
        unsigned char rw  :1;    //PB1
        unsigned char en  :1;    //PB2
        unsigned char data:4;    //PB3-PB6
        }bit;


typedef union
              {
        byte  ports;
        bit   pin;
        }portb;

portb port;


/*********************************************************************** 
*********************
                                  Bibliotheken:
************************************************************************ 
*********************/
#include <avr/interrupt.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>

/*********************************************************************** 
*********************
                                  Main-Funktion
************************************************************************ 
*********************/
int main (void)
{
unsigned int i;
DDRB=0xFF;
PORTB=port.ports;
while(1)
{
port.pin.rw=   1;
port.pin.rs=   1;
port.pin.en=   1;
port.pin.data=15;
PORTB=port.ports;
for(i=0;i<=100;i++)
{
_delay_ms(50);
}
port.pin.rs=  0;
port.pin.en=  0;
port.pin.rw=  0;
port.pin.data=0;
PORTB=port.ports;
for(i=0;i<=100;i++)
{
_delay_ms(50);
}
}
return 0;
}

Das Programm funktioniert nur dann, wenn ich jeweils nach dem ein/aus 
schalten der Bitfelder, die Zeile "PORTB=port.ports;" einfüge.
Ich wollte eigentlich diese Zeile global definieren, so dass ich sie 
nicht jeweils nach dem Schalten der Bitfelder ergänzen muss.

Hat jemand eine Idee?
Danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly wrote:
> Das wäre nur mit viel Aufwand und einem Linkerskript möglich, lässt sich
> aber mit einem #define viel einfacher hinpfuschen:
>
>    #define MeineVariable PORTB
>
> Allerdings ist von beiden Vorgehensweisen DEUTLICH abzuraten. Warum soll
> man im Sourcecode Portzugriffe verschleiern? Was spricht dagegen, PORTB
> auch so zu nennen?

Na ja, so dumm finde ich das gar nicht.

#define LCD_PORT PORTA
#define LCD_DDR  DDRA

int main()
{
  LCD_DDR = 0xFF;
  LCD_PORT = 0xFF;
}

hat ja doch einen gewissen dokumentarischen Zweck. Von der
Einfachheit einer möglichen Umstellung mal abgesehen.

Und manchmal, aber nur manchmal, kommt man dann tatsächlich in
die Verlegenheit eine Funktion schreiben zu müssen, der man
einen beliebigen Port übergibt und die auf diesem übergebenen
Port arbeitet. Dann übergibt man einen Zeiger.
Steht aber alles in der Doku zur avr-lib

RTFM

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.
Schreib dir eine Funktion dafür
void SetAll( uint8_t rw, uint8_t rs, uint8_t en, uint8_t data )
{
  port.pin.rs   =  rs;
  port.pin.en   =  en;
  port.pin.rw   =  rw;
  port.pin.data = data;

  PORTB = port.ports;
}

int main (void)
{
  unsigned int i;

  DDRB=0xFF;

  while(1)
  {
    SetAll( 1, 1, 1, 15 );
    for(i=0;i<=100;i++)
    {
      _delay_ms(50);
    }

    SetAll( 0, 0, 0, 0 );
    for(i=0;i<=100;i++)
    {
      _delay_ms(50);
    }
  }
  return 0;
}

Sieht doch (in main()) gleich besser aus.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da du allerdings sowieso den kompletten Port neu
setzt, kannst du dir das ganze Bitfeld-Gerödel auch
sparen und ganz einfach machen:
void SetAll( uint8_t rw, uint8_t rs, uint8_t en, uint8_t data )
{
  PORTB |=  ( rs << PB) | ( rw << PB1 ) | ( en << PB2 ) | ( data << PB3 );
}

Bitfelder werden IMHO kräftig überschätzt, während Funktionen
kräftig unterschätzt werden.

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.