atmega64 pointer arithmetik

Gast #2100378
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
Gast #2100437
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
Gast #2100452
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
#2100454
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.
Gast #2100465
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.
Gast #2100468
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? :-)
Gast #2100477
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);
Gast #2100520
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?
Gast #2100635
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

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