Forum: Compiler & IDEs atmega64 pointer arithmetik


von maurion (Gast)


Lesenswert?

Hallo Leute,
ich programmiere fuer den atmega64
mein programm laeuft fein, nur wird der folgende code eingefuegt, haengt 
der mega, der compiler gibt keinen fehler


    uint16_t window[801];
    uint8_t data_small0,data_small1;

    uint16_t windowsize;

    windowsize = 799;

 ((uint16_t *)(&data_small0)) = window[windowsize--];  //mag er nicht


ich will einfach den 16 bit wert von window[x] aufteilen auf data_small0 
und data_small1


Ich komm grad nicht auf die Loesung

Viele Gruess
maurion

von g457 (Gast)


Lesenswert?

> uint16_t window[801];

sram</hüstel>

von g457 (Gast)


Lesenswert?

..und sowas..
> uint8_t data_small0;
  ^^^^^^^
[..]
> ((uint16_t *)(&data_small0)) = [..]
    ^^^^^^^^^^
..ist ebenfalls mutig.

von maurion (Gast)


Lesenswert?

g457 schrieb:
> sram</hüstel>

ja davon hab ich 4 Kb

g457 schrieb:
> ..und sowas..
>> uint8_t data_small0;

dahinter steht ja noch ein uint8, gibt zusammen 16bit

von mh (Gast)


Lesenswert?

Überleg dir mal wo sie hintereinander stehen und wo sie hintereinander 
stehen müssen.

von Klaus W. (mfgkw)


Lesenswert?

... und welchen Typ das Ding hat, wo sie hingeschrieben werden sollen.

von g457 (Gast)


Lesenswert?

>> sram</hüstel>
>
> ja davon hab ich 4 Kb

das sollte heissen 'kuck mal ob da wirklich noch genug frei ist, das ist 
eine ganze Menge die Du da haben willst, und zu wenig ram kann sich u.a. 
genau so äussern'.

>>> uint8_t data_small0;
>
> dahinter steht ja noch ein uint8, gibt zusammen 16bit

Wo genau hast du dem Compiler das mittgeteilt ∗hust∗? Vielleicht doch 
besser umschreiben anstatt auf die magische Gedankenkraft vertrauen? ;-)

HTH

von maurion (Gast)


Lesenswert?

window[1]= window[windowsize--] ;
das macht er ohne murren, also daran wirds nicht liegen

wie kann ich denn dem compiler mitteilen, dass die beiden chars 
hintereinander stehen sollen?

von Guru (Gast)


Lesenswert?

>wie kann ich denn dem compiler mitteilen, dass die beiden chars
>hintereinander stehen sollen?

Das kannst Du nicht.
Das kann niemand.

von maurion (Gast)


Lesenswert?

*((uint16_t *)(&data_small0)) = (uint16_t)(64000);

das geht aber

von g457 (Gast)


Lesenswert?

> wie kann ich denn dem compiler mitteilen, dass die beiden chars
> hintereinander stehen sollen?

z.B. so:
1
uint16_t data_small0;
2
[..]
3
data_small0 = window[windowsize--];

Wenns sein muss ein bisschen Pointerarithmetik. Oder Bitgeschiebe. Oder 
ein adäquates struct.

HTH

von Guru (Gast)


Lesenswert?

>das geht aber

So? Na toll. Wie lange?

Ich schreibe gleich mal was längeres dazu. Lies am besten mal inzwischen 
in einem C-Buch. :-)

von Klaus W. (mfgkw)


Lesenswert?

Wenn es der Compiler schluckt und sogar das Programm nicht abstürzt, ist 
es noch lange nicht richtig.

maurion schrieb:
> *((uint16_t *)(&data_small0)) = (uint16_t)(64000);
>
> das geht aber

data_small0 hat doch nur 8 Bit.
Wieso schreibst du da 16 rein?

Man kann in C viele Schweinereien machen; sowas gehört dazu.
Aber das zu machen, ohne es zu verstehen, hat sich nicht bewährt.

von maurion (Gast)


Lesenswert?

window[1] = (uint16_t)window[0];    //mag er
*((uint16_t *)(&data_small0)) = (uint16_t)(64000); //mag er

*((uint16_t *)(&data_small0)) = (uint16_t)window[0] ;//mag er nicht

von maurion (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> data_small0 hat doch nur 8 Bit.
> Wieso schreibst du da 16 rein?

Danke Klaus, aber das hab ich oben schon erwaehnt.
Ich gehe davon aus, dass meine beiden char variablen hintereinander im 
Speicher stehen und somit platz fuer 16 bit da ist

von Guru (Gast)


Lesenswert?

Beachte noch mal das Hauptproblem:

Du willst eine 16-Bit Variable in zwei 8-Bit Variablen speichern.

Ausser mit einem cast auf 8 Bit, womit Du auch Information verlieren 
würdest, ist die Idee mit dem cast nicht zielführend.


Lass Dir das nochmal auf der Zunge zergehen:
Du willst eine 16-Bit Variable in zwei 8-Bit Variablen speichern.


Was liegt da näher, als die 16 Bit in zwei 8 Bit Teile aufzuspalten und 
so zu speichern.

Also:
1
data_small0 = (uint8_t) (window[windowsize] & 0xFF);
2
data_small1 = (uint8_t) ((window[windowsize--] & 0xFF00) >> 8);


DAS macht Sinn. Der cast rechts und nicht links. Links macht Dir der 
Compiler gnadenlos alles platt was da sonst noch stehen mag. Rechts aber 
bekommst Du garantiert nur Vanilleeis, äh, sorry, das was Du willst, 
nämlich 8 Bit.

von Guru (Gast)


Lesenswert?

>Ich gehe davon aus, dass meine beiden char variablen hintereinander im
>Speicher stehen und somit platz fuer 16 bit da ist

Wieso gehst Du da immer noch von aus?
Erstens funktioniert es nicht und zweitens habe ich schon geschrieben, 
das es nicht geht und drittens steht nirgends, in keinem C-Buch und 
schon garnicht bei K&R das Du davon ausgehen kannst.

Hast Du das "davon ausgehen" im Lotto gewonnen, oder was? :-)

von maurion (Gast)


Lesenswert?

nunja, ich gehe davon aus, dass es mit dem was Guru sagt geht

aber ich habs inzwischen nochmal probiert und bin wieder gescheitert und 
bevor ich es mache wie guru moechte ich doch wissen, wos hier hakt

       union
        {
            struct
            {
                   uint8_t upper;
                   uint8_t lower;
            } data8;
            uint16_t whole;
        } sample;


//die folgende Zeile geht nicht, alles andere schon
        sample.whole = window[windowsize--] ;

        uart1_putc(sample.data8.upper);//
        uart1_putc(sample.data8.lower);

von maurion (Gast)


Lesenswert?

uint16_t whole;
            whole = window[windowsize--] ;

das geht schon

puzzling, aint it?

von Guru (Gast)


Lesenswert?

Das mit der union sollte mit pragma "pack" auch funktionieren. Was 
heisst: "geht nicht"?

>puzzling, aint it?

Nicht wirklich. Eher mäßig amüsante Anfänger-Kapriolen.

von maurion (Gast)


Lesenswert?

hm es scheint garnicht hieran zu liegen

die funktion , die die daten weiterverarbeitet ist irgendwie kaputt
danke aber fuer die muehe

von Guru (Gast)


Lesenswert?

>hm es scheint garnicht hieran zu liegen

Verlass Dich drauf. Es war in jedem Fall Murks.

von Klaus W. (mfgkw)


Lesenswert?

maurion schrieb:
> Ich gehe davon aus, dass meine beiden char variablen hintereinander im
> Speicher stehen und somit platz fuer 16 bit da ist

Dafür bekommt man bestenfalls einen ersten Preis für spekulatives 
Programmieren.

von maurion (Gast)


Lesenswert?

ihr hattet recht, die 800 woerter speicher waren zu viel. warum hat mich 
der kompiler nicht darauf hingewiesen, woher weiss ich, wieviel speicher 
ich mir nehmen kann?

  ADMUX &= 0xF0;
    ADMUX |= 3; //channel nr

    while(windowsize) {
        ADCSRA |= (1<<ADSC);
        while( ADCSRA & (1<<ADSC) );
        window[windowsize--] = ADC;
    }

hat jemand ne idee, wie ich diese Analogwertaufnahmeroutinge schneller 
machen kann? *was kann ich nach ausserhalb des loops versetzen?

von Andreas (Gast)


Lesenswert?

maurion schrieb:
> ihr hattet recht, die 800 woerter speicher waren zu viel. warum hat mich
> der kompiler nicht darauf hingewiesen, woher weiss ich, wieviel speicher
> ich mir nehmen kann?

Weil es nicht die Aufgabe des Compilers ist, auf Deinen Speicher zu 
achten. Es ist Aufgabe des Betriebssystems, auf den Speicher zu achten. 
Wenn man kein Betriebssystem benutzt, sondern auf dem blanken Metall 
programmiert, muss man sich selber darum kümmern.
Wieviel Speicher Du Dir nehmen kannst, steht im Datenblatt Deines 
Controllers. Wieviel Platz zu einem bestimmten Zeitpunkt im 
Programmablauf noch frei ist, musst Du zur Laufzeit feststellen.

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.