pic c: Pointer um Eins erhöhen

Gast #2903185
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.
#2903221
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);
Gast #2903252
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.
Gast #2903255
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
Gast #2903265
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);
Gast #2903273
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.
#2903301
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.
#2903304
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);
Gast #2903732
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.

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