- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 23

Thema: 16-bit int in 2 8-bit int zerlegen

  1. #11
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    34
    Beiträge
    460
    Anzeige

    Powerstation Test
    Ja, stimmt, ich hab die ausgabevariable unsigned gemacht, hab ich übersehen.

    Es kommt aber auf das selbe, weil das höchstwertige bit auf jeden fall ein vorzeichenbit ist.

    lg
    Christoph

  2. #12
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo Christoph2,
    Es kommt aber auf das selbe, weil das höchstwertige bit auf jeden fall ein vorzeichenbit ist.
    Bei der ganzen Geschichte hier geht es ja nur um das Aufsplitten von einer 16-Bit-Variable (egal ob mit Vorzeichen oder ohne) in zwei 8-Bit-Variablen, um sie über I2C versenden zu können.

    Dabei werden einfach die 16 Bits der Ausgangsvariable in 2x 8 Bit aufgeteilt, gesendet und dann beim Empfänger wieder zusammengesetzt.

    Das Vorzeichen einer Integer spielt beim byteweisen Versenden gar keine Rolle, denn da werden einfach 2x 8 Bit übertragen. Da könnten auch z.B. Pixel eines Bildes drin sein oder eine Word-Variable, ganz egal.

    So erklärt sich, dass auf der "Transportseite" (2 Bytes werden über I2C versendet) die beiden High-/Low-Bytes uint8_t sind:
    Jedes Byte transportiert ja nur die 8 Bits und ist daher vorzeichenfrei.

    Deutlicher würde das Ganze, wenn man den Vorschlag von Besserwessi mit der Union umsetzt:
    Da würde man eine int16_t (oder uint16_t egal) definieren und an derselben Speicherstelle zwei Bytes (uint8_t). Man kann dann an dieser Stelle eine Integer ablegen und direkt als 2 Bytes weiterverarbeiten (z.B. senden).

    Puh ...

    Zum Schluß noch der Gag: Es funktioniert auch mit int8_t !

    Gruß Dirk

  3. #13
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von Besserwessi
    Man kann auch direkt auf die einzelnen Bytes zugreifen, wenn man die Variable als union definiert.

    Es könnte sein dass GCC das per Optimierung auch so hinkriegt.
    GCC kann schon lange scalar replacement of aggregates, d.h. Komponenten eines zusammengesetzten Objekts werden ebenso effizient wie Skalare bekandelt, falls sie selber welche sind.

    Ausnahme sind Bitfelder, die bis dato in avr-gcc nicht sehr effizient behandelt werden. Insbesondere für einzelne Bits ist der Code deutlich schlechter, als er sein könnte. Demnägst gibt's aber vielleicht in Patch, das auch das behebt. Dann kann auf Bit ein einem Bitfeld ebenso effizient zugegriffen werden wie über das C-übliche Masken-Gefummel.
    Disclaimer: none. Sue me.

  4. #14
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2014
    Beiträge
    13

    Unglücklich

    Hallo Community,

    ich weiß, dass der Thread >6 Jahre alt ist, aber warum einen neuen eröffnen wenn mein Problem hier 100% liegt.

    mein Vorhaben ganz simpel: eine Zahl (16bit) soll auch wie hier in 2x(8bit) zerlegt werden und via UART auf einen zweiten µC gesendet und auf einer 7-Segment LED-Anzeige ausgegeben werden.
    Mit einer 8-bit Zahl habe ich die Ansteuerung des 7-Segment Displays getestet um dies schonmal abzuhaken in seiner Funktion.

    Problem ist, wenn ich eine 16-bit Zahl (hier 6789) sende, gibt die LED-Anzeige lauter Zufallszahlen aus und wechselt hin- und her.

    Ich stehe mit meiner Programmiererfahrung noch ziemlich am Anfang und habe versucht eine Lösung zu finde, jedoch ohne Erfolg. Ich poste die wichtigen Ausschnitte meines Codes (unwichtiges rausgelöscht) was das Senden und Empfangen angeht, wäre nett wenn mir einer helfen kann (ist ja bestimmt nichts großes)

    SENDEN
    Code:
    .
    .
    .
    .
    uint16_t zahl=6789;
    
    uint8_t HByte;
    uint8_t LByte;
    
    
    void daten_senden (uint8_t data)
    {
    	while (!(UCSRA & (1<<UDRE))){} //warten bis senden möglich ist
    	
    	UDR = data; //Zeichen in den Ausgabepuffer schreiben
    }
    
    void usart_init (void)
    {
    	UCSRB |= (1<<TXEN); //Daten senden
    	UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  // Asynchron 8N1
    	UBRRH = UBRR_VAL >> 8;
    	UBRRL = UBRR_VAL & 0xFF;
    }
    
    
    int main(void)
    {
        usart_init();
    
        while (1) 
        {
    		
    		HByte = (zahl >> 8);
    		LByte = zahl & 0xff;		
    
    		daten_senden(HByte);
    		daten_senden(LByte);		
        }
    }


    EMPFANGEN

    Code:
    .
    .
    .
    
    
    uint16_t zahl;
    uint8_t usart_empfang; 
    
    void usart_init (void)
    {
    	UCSRB |= (1<<RXEN) |(1<<RXCIE) ; //Daten empfangen und Interrupt für Datenempfang enable
    	UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  // Asynchron 8N1
    	UBRRH = UBRR_VAL >> 8;
    	UBRRL = UBRR_VAL & 0xFF;
    }
    
    
    ISR(USART_RXC_vect)
    {
    	usart_empfang = UDR;	
    }
    
    
    int main(void)
    {	
    	usart_init();
    	
    	sei();
    	
        while (1) 
        {
    		
    		uint8_t HByte = usart_empfang;
    		uint8_t LByte = usart_empfang;
    			
    		zahl = (((uint16_t) HByte) << 8 ) | LByte;
    		
    		zahl_ausgeben(zahl);	
    		
    		
        }
    }
    Geändert von opc (15.04.2016 um 14:20 Uhr)

  5. #15
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo Christoph,
    Zitat Zitat von Christoph2 Beitrag anzeigen
    ahhh danke!!
    Ich hab aber nur die low variable uint8_t gemacht, die high hab ich int8_t gemacht, sonst hab ich keine vorzeichen bei der int16_t.
    Ich denke du hast das mit signed und unsigned noch nicht wirklich verstanden.

    Der 8-Bit-Wert 0b11111111 hat unsigned den Wert 255 und signed -1.
    Das höchstwertige Bit ist das Vorzeichen 0 = "+" und 1 = "-" (zumindest beim üblichen 2er Komplement)

    Wird nun unsigned auf 16-Bit erweitert ergibt dies 0b00000000'11111111, bei signed wird es 0b11111111'11111111

    Der 8-Bit-Wert 0b01111111 ist unsigned und signed = 127.
    Entsprechend wird unsigned und signed als 16-Bit 0b00000000'01111111

    Bei der Erweiterung werden die zusätzlichen Bits bei unsigned immer mit 0en gefüllt.
    Bei signed, entsprechend dem Vorzeichen-Bit mit 0en oder 1ern.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  6. #16
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2014
    Beiträge
    13
    Hallo Peter,
    der letzte Post war von mir auf einen 6 Jahre alten Thread, aber mit neuer Ausgangslage (wie erwähnt)!

    Bitte sieh dir meinen Post an.

  7. #17
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    34
    Beiträge
    1.192
    Hallo,
    ich würde in der Empfangs-Programm vor dem Zusammenbauen a=(b<<8 )|c das most significant byte erst als uint16 casten bevor es geshiftet wird.
    Also a=( ((uint16_t)b) <<8 ) |c
    Grüße,
    Bernhard

  8. #18
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2014
    Beiträge
    13
    Grüß dich Bernhard,

    erledigt (auch hier im Code im Forum).

    Sieht nun so aus:

    zahl = (((uint16_t) HByte) << 8 ) | LByte;

    Leider immer noch dasselbe Problem.

    Gruß
    Markus

  9. #19
    HaWe
    Gast
    Code:
    uint8_t   highbyte, lowbyte;
    int16_t   intval;
    
    // bytes zu int:
    intval = lowbyte + (highbyte << 8);
    
    //int zu bytes:
    lowbyte  = intval & 0x00ff;
    highbyte = (intval >> 8) & 0x00ff;
    hoffe, das stimmt...! 8-)

  10. #20
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2014
    Beiträge
    13
    @HaWe: ja das ist schon richtig so, mein Fehler muss woanders liegen.

    Hab dein Codeschnipsel auch testweise soeben mal eingebaut bzw. ersetzt -> führt leider zum selben Ergebnis.

    Habe mal testweise ein delay (1s) nach der Zahlenausgabe aufs 7-Segment geschrieben, daran erkennt man deutlich, dass zwischen zwei völlig wirren Zahlenkombinationen hin- und hergewechselt wird, also scheint der Fehler weiterhin an der Umsetzung 16bit / 2*8bit und umgekehrt zu liegen.

    Bin um jeden Tipp dankbar
    Geändert von opc (15.04.2016 um 14:38 Uhr)

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests