Symbolische Adressen

#3876421
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.
Gast #3876515
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.
Gast #3876521
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?
Gast #3876533
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".
Gast #3876537
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, ...
#3876551
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.
#3876584
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.
Gast #3876627
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
#3876668
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
#3876887
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.
#3877210
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.
#3877581
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
Gast #3877812
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren