mikrocontroller.net

Forum: Compiler & IDEs atmega64 pointer arithmetik


Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> uint16_t window[801];

sram</hüstel>

Autor: g457 (Gast)
Datum:

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

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: mh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Überleg dir mal wo sie hintereinander stehen und wo sie hintereinander 
stehen müssen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und welchen Typ das Ding hat, wo sie hingeschrieben werden sollen.

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Guru (Gast)
Datum:

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

Das kannst Du nicht.
Das kann niemand.

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
*((uint16_t *)(&data_small0)) = (uint16_t)(64000);

das geht aber

Autor: g457 (Gast)
Datum:

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

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

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

HTH

Autor: Guru (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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. :-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Guru (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
data_small0 = (uint8_t) (window[windowsize] & 0xFF);
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.

Autor: Guru (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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? :-)

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint16_t whole;
            whole = window[windowsize--] ;

das geht schon

puzzling, aint it?

Autor: Guru (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm es scheint garnicht hieran zu liegen

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

Autor: Guru (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>hm es scheint garnicht hieran zu liegen

Verlass Dich drauf. Es war in jedem Fall Murks.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: maurion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.