This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/MSP430FR5994: What use union?

Part Number: MSP430FR5994

Tool/software: TI C/C++ Compiler

What use union?

Compiler v17.6.0.STS / CCS 6.2.0.00050

In code:

union long_as_array{
	unsigned long l;
	unsigned char a[4];
};

union long_as_array IEEE754;
unsigned char buff[255];
unsigned char pos=12;

IEEE754.l=*(unsigned long*)&buff[pos];

load to long part 0x01020304

in array part set only a[1] other byte - not in long

why?

  • update

    if union write as

    union long_as_array{
    	unsigned char a[4];
    	unsigned long l;
    };
    
    

    and load to l=0x01020304
    in a array [0x00,0x04,0x00,0x00]

    strange...

  • Technically this is not legal, but it usually works. Can you provide a short test case that shows the problem?
  • thank for your ansver/

    I write test clear code

    Variant 1

    #include <msp430.h>
    
    union long_as_array{
    	unsigned char a[4];
    	unsigned long l;
    };
    
    unsigned char pos;
    unsigned char BUFF[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    unsigned int exp;
    unsigned char neg;
    
    void IEEE2Long(unsigned char* buff, unsigned char pos){
    	union long_as_array IEEE754;
    	IEEE754.l=*(unsigned long*)&buff[pos];
    	neg=IEEE754.a[0] & BIT7?1:0;
    	exp=(IEEE754.a[0]<<1)+(IEEE754.a[1] & BIT7?1:0);
    }
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
        IEEE2Long(BUFF,12);
    	while(1);
    }

    Strange result in view

    I move union variablle to global

    #include <msp430.h>
    
    union long_as_array{
    	unsigned char a[4];
    	unsigned long l;
    };
    
    unsigned char pos;
    unsigned char BUFF[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    unsigned int exp;
    unsigned char neg;
    union long_as_array IEEE754;
    
    void IEEE2Long(unsigned char* buff, unsigned char pos){
    	IEEE754.l=*(unsigned long*)&buff[pos];
    	neg=IEEE754.a[0] & BIT7?1:0;
    	exp=(IEEE754.a[0]<<1)+(IEEE754.a[1] & BIT7?1:0);
    }
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
        IEEE2Long(BUFF,12);
    	while(1);
    }

    and it work!

  • You are attempting to implement type punning.  An internet search on that term will give you a good background on it.

    Based on your comments and code, I presume you are interested in doing bit operations on floating point types.  It turns out the compiler supplies some intrinsics for this very purpose.  They are not documented in the manual, so here they are:

    float              __u32_bits_as_f32(unsigned long);
    unsigned long      __f32_bits_as_u32(float);
    double             __u64_bits_as_f64(unsigned long long);
    unsigned long long __f64_bits_as_u64(double);

    Use them in your source as you would a C function.  However, they cause no code to be generated.  The underlying bit string is interpreted as the new type.  To see some examples of usage, search for them in the compiler RTS source code.  It is in a location similar to ...

    C:\ti\ccsv7\tools\compiler\ti-cgt-msp430_16.9.3.LTS\lib\src

    Thanks and regards,

    -George

  • Thanks, found this in

    _defs.h

    math_intr_access.h

    math_private.h

    but I do not need the full support of the whole range float. I operation on each byte in send me float from sensor

    My sensor out data in percentages and temperature in range -100 to 100

    If load standart float lib - lost many memory and very slow operation.

    I invented a trick :) in float range 128 to -128 with accuracy 10E-5 (real use 10E-4)

    use only bit shift and 1 divider at the end calculate and transfer float to long for operation

    for example

    98.7654321 = 9876543

    0.001234=123

    further operate with long

  • Okay, then you might want to consider using fixed-point arithmetic (e.g. Q16). This lets you use the integral operations but still have fractional values.

  • Thanks!
    This is support in Compiler v17.6.0.STS? Where to read about it?
  • Fixed-point math is not a built-in feature of the compiler.  It is a library you can get from here.  Please understand this library is not supplied by the compiler development team.  If you have questions about it, please post them in the MSP430 device forum.

    Thanks and regards,

    -George

  • thanks

    I understood

    Union work only in global scope!