Forum: Mikrocontroller und Digitale Elektronik pic c: Pointer um Eins erhöhen


von dotm (Gast)


Lesenswert?

Hallo
Ich will ein Int array möglichs schnell per spi übertragen. Daher dachte 
ich ich erhöhe einfach den Pointer.
Ganz sicher kann man das auch anders erledigen, aber es geht mal um 
Prinzip.

Mein Code zum testen schaut in etwa so aus:
1
volatile unsigned int test[4]= {0x1122, 0x3344, 0x4455, 0x5566};
2
LSB = *test;
3
MSB = *((&test+1));

Die Variablen stehen im Speicher so drin:
1
0058: 22 11 44 33

Die ausgabe ist nun:
MSB = 22
LSB = 44

der Pointer zählt also um zwei hoch da es ein Int- Array ist.
Richtig wenn man es so will, falsch wenn ich eigentlich auf das MSB 
kommen will. Auch *((&test+0b01)) führt nicht dazu dass der Pointer nur 
eins vorrückt.
Wie bekomm ich denn die Adresse so raus dass sie nicht als Pointer 
verarbeitet wird sondern als normale Zahl?
fg
m.

von Rene H. (Gast)


Lesenswert?

Den Pointer nach (unsigned char *) oder (uint8_t *) casten. Sollte 
eigentlich klappen.

Grüsse,
René

von Dominik S. (dasd)


Lesenswert?

Zum einen muss das heißen:
1
volatile unsigned int test[4]= {0x1122, 0x3344, 0x4455, 0x5566};
2
LSB = (*test);
3
MSB = *((test+1));

Vor das "test" beim MSB darf kein &.

Wenn mich jetzt nicht alles täuscht:

Dein Integer ist 16 Bit breit, dein "Pointer" ist wenn du das so 
schreibst ebenfalls ein Pointer auf eine 16 Bit breite Zahl.

Möglichkeit 1: Den Wert vor der Zuweisung ins MSB ein Byte nach links 
schieben.

Möglichkeit 2: 8-bit Pointer benutzen und damit wirklich auf die 
einzelnen Speicherstellen zugreifen.
1
uint8_t* ptr = test;
2
LSB = *ptr;
3
MSB = *(ptr+1);

von dotm (Gast)


Lesenswert?

Rene H. schrieb:
> Den Pointer nach (unsigned char *) oder (uint8_t *) casten.

tatsächlich. so rennts.
1
MSB = *((unsigned char*)&test+1);

Vielen Dank

von Rene H. (Gast)


Lesenswert?

Das würde mich aber wundern. test ist schon ein Pointer. Du hast also 
ein doppel Pointer. Entweder Du nimmst die Adresse von test[0] oder 
lässt das Ampersand weg.

Lies mal das Posting von Dominik, er hat das sehr genau und gut erklärt.

Grüsse,
R.

von dotm (Gast)


Lesenswert?

Dominik S. schrieb:
> Möglichkeit 2: 8-bit Pointer benutzen und damit wirklich auf die
> einzelnen Speicherstellen zugreifen.
> uint8_t* ptr = test;
> LSB = *ptr;
> MSB = *(ptr+1);

Da beschwert sich der Compiler dass der Pointer inkompatibel ist! Wenn 
ich das als Char caste geht das super. Der Compiler macht da auch keinen 
Blödsinn draus:
1
157:                       LSB = *test;
2
00A1  0859     MOVF test, W
3
00A2  00C3     MOVWF LSB
4
158:                       MSB = *((unsigned char*)&test+1);
5
00A3  085A     MOVF 0x5A, W
6
00A4  00C4     MOVWF MSB

von dotm (Gast)


Lesenswert?

Rene H. schrieb:
> Das würde mich aber wundern. test ist schon ein Pointer. Du hast also
> ein doppel Pointer. Entweder Du nimmst die Adresse von test[0] oder
> lässt das Ampersand weg.

test ist ein int-array. &test bringt mir die adresse des arrays. dann 
nach unsigned char casten und um eins erhöhen ergibt mir ein unsigned 
char mit einer zahl die der nächsten Speicherzelle entspricht. mit * hol 
ich mir den Wert der nächsten Speicherstelle.
Wo hab ich nun meinen Denkfehler (vorallem es funktioniert ja...)
1
MSB = *((unsigned char*)&test+1);

von Rene H. (Gast)


Lesenswert?

Wenn Du das machst, beschwert sich der Compiler? Das kann ich fast nicht 
glauben:
1
volatile unsigned int test[4]= {0x1122, 0x3344, 0x4455, 0x5566};
2
3
....
4
5
unsigned char* ptr = (unsigned char*) test;
6
7
unsigned char LSB;
8
unsigned char MSB;
9
10
11
while (...) {
12
   LSB = *(ptr++);
13
   MSB = *(ptr++);
14
15
  ...
16
}
17
18
19
.....

Das ist nur Prosa und man kann das auch wesentlich eleganter lösen. Aber 
um das geht es hier ja nicht.

Grüsse,
R.

von Rene H. (Gast)


Lesenswert?

Sorry, musste editieren, hatte "Bullsh...." geschrieben :-)

von dotm (Gast)


Lesenswert?

Rene H. schrieb:
> Wenn Du das machst, beschwert sich der Compiler?

main.c:42: warning: illegal conversion between pointer types

Rene H. schrieb:
> Das ist nur Prosa und man kann das auch wesentlich eleganter lösen.


vorallem wie dus gemacht hast ist die Type des Pointers ja soundso egal 
da du vor dem Erhöhen um Eins ja soundso als char castest :)

von Rene H. (Gast)


Lesenswert?

Eben!

Ist schon spät, sorry :-)

Grüsse,
R.

von Dominik S. (dasd)


Lesenswert?

Rene H. schrieb:
> Sorry, musste editieren, hatte "Bullsh...." geschrieben :-)

Hatte mich gerade gewundert :)

dotm schrieb:
> Da beschwert sich der Compiler dass der Pointer inkompatibel ist!

Ja, stimmt schon. Bei meinem Post von oben fehlt der Cast.

dotm schrieb:
> uint8_t* ptr = test;

Geht so natürlich nicht, müsste wie Rene gerade sagte natürlich
1
 uint8_t* ptr = (uint8_t*) test;

heißen, also mit Cast - sonst passt es wie der Compiler sagt natürlich 
nicht zusammen (8 <-> 16 bit Pointer).

dotm schrieb:
> MSB = *((unsigned char*)&test+1);

Das & scheint egal zu sein, auch wenn es eigentlich keinen wirklichen 
Sinn oder Zweck erfüllt.

dotm schrieb:
> test ist ein int-array. &test bringt mir die adresse des arrays.

Nur "test" (also ohne &) bringt dir auch schon die Adresse des ersten 
Elements.
Darum auch das mit dem weglassen.

von Karl H. (kbuchegg)


Lesenswert?

dotm schrieb:
> Rene H. schrieb:
>> Das würde mich aber wundern. test ist schon ein Pointer. Du hast also
>> ein doppel Pointer. Entweder Du nimmst die Adresse von test[0] oder
>> lässt das Ampersand weg.
>
> test ist ein int-array. &test bringt mir die adresse des arrays.

no.
Der Name eines Arrays alleine (also ohne Indexoperation) steht schon für 
die Startadresse des Arrays. Du brauchst da keinen &.


> Wo hab ich nun meinen Denkfehler (vorallem es funktioniert ja...)

Aber nur, weil dein Compiler gutmütig ist und den & ignoriert.
>
> MSB = *((unsigned char*)&test+1);
1
  MSB = *((unsigned char*)test + 1);

von dotm (Gast)


Lesenswert?

Dominik S. schrieb:
> Nur "test" (also ohne &) bringt dir auch schon die Adresse des ersten
> Elements.
> Darum auch das mit dem weglassen.

aso! klar.

von Rene H. (Gast)


Lesenswert?

Dominik S. schrieb:
> Rene H. schrieb:
>> Sorry, musste editieren, hatte "Bullsh...." geschrieben :-)
>
> Hatte mich gerade gewundert :)

Naja, wenn man 12 Stunden in irgendwelchem Code rum geferkelt hatte und 
nebenbei noch Postings in Prosa schreibt und der Chef-Chef Dich 
anquatscht kommt selten etwas schlaues raus.
Ich hab es zum Glück nochmals durchgesehen bevor man mich in der Luft 
zerrissen hat :-)

Grüsse,
R.

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.