Forum: Mikrocontroller und Digitale Elektronik Symbolische Adressen


von P. F. (pfuhsy)


Lesenswert?

Hallo zusammen,

ich komme gerade nicht weiter, vielleicht hat ja jemand einen 
Anhaltspunkts. Ich weiß nicht genau wie ich es in Worte fassen oder 
nennen soll, ich vermutet es sind symbolische Adressen.

Also mein µC hat seine Ports in einer Header definiert:
1
/* Port B */
2
#define PORTB  _SFR_IO8(0x18)
3
4
/* PORTB */
5
#define PB7  7
6
#define PB6  6
7
#define PB5  5
8
#define PB4  4
9
#define PB3  3
10
#define PB2  2
11
#define PB1  1
12
#define PB0  0

Und das ganze kann ich dann ja über die Register??? ansprechen.
PORTB:PORTB7 | PORTB6 | PORTB5 | PORTB4 | PORTB3 | PORTB2 | PORTB1 | 
PORTB0

Ich sende Daten per Funk an meinen µC und will sozusagen diese genauso 
codieren.
1
/* Byte1 */
2
#define BYTE_1  ???
3
4
/* BYTE 1 */
5
#define BEF7  7
6
#define BEF6  6
7
#define BEF5  5
8
#define BEF4  4
9
#define BEF3  3
10
#define BEF2  2
11
#define BEF1  1
12
#define BEF0  0

BYTE_1     BEF7 | BEF6 | BEF5 | BEF4 | BEF3 | BEF2 | BEF1 | BEF0

Mal angenommen ich sende 1 Byte "A".
Dann repräsentiert es das BEF0 von BYTE_1.
Sende ich ein 2tes Byte, das repräsentiert dann das BEF1 von BYTE_1, 
usw.

"A" wäre binär "0000 1010". Im Umkehrschluss würde das aufgeschlüsselt 
so aussehen:
Bit BEF7 = 0;
Bit BEF6 = 0;
Bit BEF5 = 0;
Bit BEF4 = 0;
Bit BEF3 = 1;
Bit BEF2 = 0;
Bit BEF1 = 1;
Bit BEF0 = 0;

Ich weiß nicht genau wie ich verfahren kann und wonach ich eigentlich 
suchen soll um mir ein paar Infos zu holen.

von Easylife (Gast)


Lesenswert?

Du solltest dich vielleicht erstmal Grundsätzlich mit Bitoperationen 
beschäftigen.

http://www.oreilly.de/catalog/cplus2ger/chapter/ch11.pdf

von P. F. (pfuhsy)


Lesenswert?

Echt jetzt ? Das ist jetzt der Tip ? Mich damit zu beschäftigen, obwohl 
ich seit Tagen nichts anderes mache !

von Werner (Gast)


Lesenswert?

Peter F. schrieb:
> Mich damit zu beschäftigen, obwohl ich seit Tagen nichts anderes mache !
Dann sollte dir sowohl der Unterschied zwischen Bit-Nummer und 
-Wertigkeit als auch die Wirkung der bitweise Oder-Verknüpfung 
inzwischen etwas klarer sein.

von Fachmann (Gast)


Lesenswert?

Was ist genau dein Problem? Du kannst die bits so definieren aber sie 
weden nicht an BYTE_1 gebunden. Weil der compiler nicht weiss, dass 
BYTE_1 und bits BEF7 bis BEF0 zusammen gehören.

von npn (Gast)


Lesenswert?

Hallo Peter,

versuchen wir das ganze mal ein wenig aufzudröseln.
> #define PB0  0
sagt nur aus, daß der Ausdruck "PB0" ersetzt werden soll durch "0".

Also z.B. wird "PORTB & (1<<PB0)" ersetzt durch "PORTB & (1<<0)"

Was du mit dem "A" meinst, weiß ich nicht so recht. Das "A" ist binär 
gesehen "0100 0001" (hex 0x41). Das sind 8 Bit, und das kannst du nicht 
in einem Bit von BYTE_1 unterbringen, wie du das oben schreibst.
Insofern ist der Hinweis, dir die Bitoperationen nochmal zu Gemüte zu 
führen, schon berechtigt.

Hier http://www.mikrocontroller.net/articles/Bitmanipulation steht sehr 
viel geschrieben zu diesem Thema, da kannst du dich informieren.

von Werner (Gast)


Lesenswert?

npn schrieb:
> Das sind 8 Bit, und das kannst du nicht
> in einem Bit von BYTE_1 unterbringen, wie du das oben schreibst.

BYTE_1 ist nur ein Platzhalter für die Textersetzung durch den 
Präprozessor. Wer weiß, was dem Ausdruck im übrigen Quellcode für eine 
Bedeutung zukommen soll?

von npn (Gast)


Lesenswert?

Werner schrieb:
> npn schrieb:
>> Das sind 8 Bit, und das kannst du nicht
>> in einem Bit von BYTE_1 unterbringen, wie du das oben schreibst.
>
> BYTE_1 ist nur ein Platzhalter für die Textersetzung durch den
> Präprozessor. Wer weiß, was dem Ausdruck im übrigen Quellcode für eine
> Bedeutung zukommen soll?

Stimmt, da stehen ja nur drei Fragezeichen. Ich habe einfach mal 
angenommen, daß er wirklich ein Byte gemeint hat wegen der Zeile
1
BYTE_1     BEF7 | BEF6 | BEF5 | BEF4 | BEF3 | BEF2 | BEF1 | BEF0
die allerdings auch nichts aussagt... Ich gehe mal davon aus, daß er 
meint, BYTE_1 wird repräsentiert durch (BEF7 oder BEF6 oder...BEF0).
Deswegen auch mein Link zum Artikel "Bitmanipulation".

von gvs (Gast)


Lesenswert?

Peter F. schrieb:
> Mal angenommen ich sende 1 Byte "A".
> Dann repräsentiert es das BEF0 von BYTE_1.
> Sende ich ein 2tes Byte, das repräsentiert dann das BEF1 von BYTE_1,
> usw.

Codierung ist wohl eher dein Problem.

Konstanten für Werte die vom Port gelesen werden:
'A'         = 0b00000001
'2tes Byte' = 0b00000010

Auswertung:
Wenn PORTB == 'A' tue dies,
wenn PORTB == '2tes Byte' tue das, ...

von P. F. (pfuhsy)


Lesenswert?

npn schrieb:
> Also z.B. wird "PORTB & (1<<PB0)" ersetzt durch "PORTB & (1<<0)"
Das weiß ich.

> Was du mit dem "A" meinst, weiß ich nicht so recht. Das "A" ist binär
> gesehen "0100 0001" (hex 0x41).
"A" ist nur das beispiel was ich Stelle von "0100 0001" sende.

> Das sind 8 Bit, und das kannst du nicht
> in einem Bit von BYTE_1 unterbringen, wie du das oben schreibst.
Das ist mir auch klar. das "A" aoll das komblette BYTE_1 wiederspiegeln, 
wie die 0 und PB0 bei "PORTB & (1<<PB0)" ersetzt durch "PORTB & (1<<0).

> Was ist genau dein Problem? Du kannst die bits so definieren aber sie
> weden nicht an BYTE_1 gebunden. Weil der compiler nicht weiss, dass
> BYTE_1 und bits BEF7 bis BEF0 zusammen gehören.
Das ist es. wie sag ich ihn den das sie zusammen gehören ?

> BYTE_1 wird repräsentiert durch (BEF7 UND BEF6 UND...BEF0)
Ja so hab ich es gemeint.

Ich sag doch, ich kann das nur schwer erklären.
Im grunde genommen möchte ich die Bits manipulieren und auswerten, so 
wie ich es schon mit PORTA, B und C mache, nur das es sich hier um meine 
eigene definition handelt, eben BYTE_1 als Beispiel.

von P. F. (pfuhsy)


Lesenswert?

> Deswegen auch mein Link zum Artikel "Bitmanipulation".
Gut das lese ich mir noch durch, vielleicht bringt es mich weiter.

von Bernd K. (prof7bit)


Lesenswert?

Peter F. schrieb:

> Ich sag doch, ich kann das nur schwer erklären.
> Im grunde genommen möchte ich die Bits manipulieren und auswerten,

Gib doch mal ein ganz konkretes und möglichst vollständiges Beispiel 
von dem was Du konkret machen willst bei dem Du einzelne Bits in einem 
Byte (mehrere gleichzeitig? Immer nur eins?) manipulieren willst und 
dann können wir uns anhand des konkreten Beispiels Gedanken machen wie 
man das am elegantesten hinschreibt.

: Bearbeitet durch User
von Fachmann (Gast)


Lesenswert?

Ich weiss nicht genau wie das in deinem compiler gemacht wird aber in 
JAL
geht das so:

var byte vport_b
var volatile bit  vpin_b0 at vport_b : 0
var volatile bit  vpin_b1 at vport_b : 1
var volatile bit  vpin_b2 at vport_b : 2
var volatile bit  vpin_b3 at vport_b : 3
var volatile bit  vpin_b4 at vport_b : 4
var volatile bit  vpin_b5 at vport_b : 5
var volatile bit  vpin_b6 at vport_b : 6
var volatile bit  vpin_b7 at vport_b : 7

von P. F. (pfuhsy)


Lesenswert?

Bernd K. schrieb:
> Gib doch mal ein ganz konkretes und möglichst vollständiges Beispiel
> von dem was Du konkret machen willst

Ok, ich versuche es nochmal.
Irgendwo muss das definiert sein:
BYTE_1:     BEF7 | BEF6 | BEF5 | BEF4 | BEF3 | BEF2 | BEF1 | BEF0
wie hier die Ports des µC:
PORTB:PORTB7 | PORTB6 | PORTB5 | PORTB4 | PORTB3 | PORTB2...

Damit will ich sagen, dass das 7te Bit von BYTE_1 BEF7 heisst, das 6te 
Bit BEF6 usw.

Dann sage ich:
1
BYTE_1 |= (1<<BEF7) | (0<<BEF6);
wie bei den Ports des µC:
1
PORTB |= (1<<PORTB7); //Muss nicht richtig sein, nur ein Beispiel.

Und zu guter letzt will ich dann die Daten mit meiner Funktion senden:
1
DATEN_SENDEN(BYTE_1); //

Das klappt ja schon:
1
DATEN_SENDEN("0123456789012345");

Zusammenfassung:
1
Unklare definition ???
2
BYTE_1 |= (1<<BEF7) | (0<<BEF6); //Wertezuweisung
3
DATEN_SENDEN(BYTE_1);  Senden

von Bernd K. (prof7bit)


Lesenswert?

Nichts hindert Dich daran zu definieren:
1
#define BEF0 0
2
#define BEF1 1
3
#define BEF2 2
4
#define BEF3 3
5
#define BEF4 4
6
#define BEF5 5
7
#define BEF6 6
8
#define BEF7 7
9
10
11
void foo () {
12
    uint8_t bar = (1 << BEF4) | (1 << BEF6);
13
    send(bar);

Ich würds aber eher so machen:
1
#define LINKS             0b00000001
2
#define RECHTS            0b00000010
3
#define BREMSE_VORNE      0b00000100
4
#define BREMSE_HINTEN     0b00001000
5
#define RUECKWAERTS       0b00010000
6
#define DRITTEL_GAS       0b00100000
7
#define ZWEI_DRITTEL_GAS  0b01000000
8
#define VOLL_GAS          0b01100000
9
#define HUPE              0b10000000
10
11
void foo() {
12
    send(VOLL_GAS | BREMSE_VORNE);
13
    _delay_ms(1000);
14
    send(VOLL_GAS);
15
    _delay_ms(6000);
16
    send(LINKS | VOLL_GAS | HUPE);
17
    _delay_ms(500);
18
    send(RECHTS | BREMSE_HINTEN);
Das wäre einfacher zu lesen, es dokumentiert sich selbst und Du hast 
nicht kreuz und quer im Code diese namenlosen nichtssagenden Bitnummern 
stehen. Das würd ich übrigens auch mit den Portbit-Nummern machen. Gib 
ihnen sinnvolle Namen gleich zu Anfang und verwende sie ansonsten 
nicht mehr direkt.
1
#define ABBLENDLICHT   (1 << PB3)
2
#define FERNLICHT      (1 << PB4)
3
#define BREMSLICHT     (1 << PB5)

Und es hängt alles davon ab was Du genau tun willst. Gib doch mal ein 
konkretes Beispiel für ein konkretes Problem.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Peter F. schrieb:

> Das ist es. wie sag ich ihn den das sie zusammen gehören ?

Gar nicht.
WOzu auch?

> Ich sag doch, ich kann das nur schwer erklären.
> Im grunde genommen möchte ich die Bits manipulieren und auswerten, so
> wie ich es schon mit PORTA, B und C mache, nur das es sich hier um meine
> eigene definition handelt, eben BYTE_1 als Beispiel.

Kann es sein, dass dir nicht klar ist, dass du die Bitoperation, wie du 
zb das Bit 0 im PORTA setzt
1
   PORTA |= ( 1 << PB0 );
oder wie Bernd das sehr sinnvoll mit einer anderen Makro-Benamung 
vorschlägt
1
#define BLINKER_LINKS  (1<<PB0)
2
3
4
  PORTA |= BLINKER_LINKS;

genausogutr auf ganz stinknormale Variablen anwenden kannst?
1
#define BLINKER_LINKS  (1<<PB0)
2
3
uint8_t LightStatus;
4
5
...
6
7
   LightStatus |= BLINKER_LINKS;
8
9
   SendStatus( LightStatus );

Die Bitoperationen sind ein allgemeines Schema, um in einem Byte (oder 
Word ... ) 1 Bit zu setzen, 1 Bit zu löschen, 1 Bit abzufragen. Das hat 
erst mal nichts mit einem Port an sich zu tun. Das es bei Ports 
funktioniert, liegt daran, dass die Portdefinitionen entsprechend 
zurecht gelegt wurden. Aber den Bitoperationen an sich ist das ziemlich 
egal, worauf sie arbeiten. Links vom = steht ein 'Ding', und in diesem 
Ding wird 1 Bit gesetzt. Der Rest, wie das umzusetzen ist, ist Sache des 
Compilers.

Dann hat halt zum Beispiel dein Sender eine Variable, in der er die 
gewünschte Situation der Lichter mitführt, wenn der Benutzer am Sender 
eine Taste drückt, dann wird die in dieser Variablen entsprechend 
mitgeführt (Bit setzen löschen) und die neue Lichtsituation an den 
Empfänger übermittelt, welcher dann die Bits entsprechend aufdröselt und 
an die Portbits verteilt, so dass die Licht entsprechend leuchten oder 
nicht leuchten.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Peter F. schrieb:
>
>> Das ist es. wie sag ich ihn den das sie zusammen gehören ?
>
> Gar nicht.
> WOzu auch?

D.h. das stimmt nicht ganz.
Über Strukturen könnte man das erreichen. Und ja: das hätte durchaus 
auch Vorteile.

von Daniel A. (daniel-a)


Lesenswert?

Werden hier Bit-fields gesucht?

Ein getestetes und funktionierendes Beispiel:
1
#include <stdio.h>
2
3
#define BF_DEF(by,bi) \
4
  union { \
5
    unsigned char by; \
6
    struct { \
7
      unsigned bi ## 0:1; \
8
      unsigned bi ## 1:1; \
9
      unsigned bi ## 2:1; \
10
      unsigned bi ## 3:1; \
11
      unsigned bi ## 4:1; \
12
      unsigned bi ## 5:1; \
13
      unsigned bi ## 6:1; \
14
      unsigned bi ## 7:1; \
15
    }; \
16
  }
17
18
19
int main(){
20
  BF_DEF(yte,it) b;
21
  b.yte = 0;
22
  b.it7 = 1;
23
  printf("0x%x\n",(int)b.yte);
24
  return 0;
25
}

Ausgabe: 0x80

Getestet mit:
gcc (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3

Compiliert mit folgenden Parametern:
gcc -Wall -Wextra -pedantic -Werror -std=c11

von Georg (Gast)


Lesenswert?

Karl Heinz schrieb:
> Über Strukturen könnte man das erreichen. Und ja: das hätte durchaus
> auch Vorteile.

Es gibt aber nur sehr wenige Prozessoren, bei denen man Port Bits 
einzeln per I/O-Befehl ansprechen kann (und das mit Nebenwirkungen), bei 
den meisten kann man nur das ganze 8bit-Port einlesen oder ausgeben. 
Dann führt kein Weg dran vorbei, die Bitmanipulation, um ein bestimmtes 
Bit zu setzen oder rückzusetzen, selbst durchzuführen mit den bekannten 
And/Or-Befehlen.

Mein Eindruck ist, dass da der TO hängt: er möchte PortB Bit 7 mit einem 
Befehl ausgeben, aber das geht i.A. so nicht.

Georg

von P. F. (pfuhsy)


Lesenswert?

Hab mir ein paar Tipps zu Herzen genommen. Funktioniert jetzt so wie es 
haben wollte. Danke Männer.

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.