EmbDev.net

Forum: µC & Digital Electronics Treat char [ ] array as float


von gast (Guest)


Rate this post
useful
not useful
Dear All,

I am new to the forum and probably my question has already been answered 
somewhere else. Nevertheless, here is the problem:

CHIP:     ATA6286
GOAL:     Read out 4 bytes from EEPROM and treat them as a float
COMPILER: CodeVisionAVR v. 2.04.0
DEBUGGER: AVR Studio v. 4.13 Build 528

I am trying to store a float number into the EEPROM of the chip by 
externally sending the float bytewise and then read it out internally 
using the ATA6286 chip itself. Storing the bytes seems to work fine - I 
have already checked this.

However, since it is not possible to read more than one byte at a time 
from the EEPROM, reading out the float values has to be done bytewise. 
For the purpose I have defined a little struct as follows:
1
typedef union
2
{
3
 float          value;
4
 unsigned char  byte_val[4];
5
 unsigned int   int_val[2];
6
} float_byte_int;
7
8
....
9
10
float_byte_int fbi_VAR;

This allows me to read out the single bytes from the EEPROM (I have 
already taken care of the endianness) and store them into the
1
 fbi_VAR.byte_val[i]
 position of the char array. Theoretically the call
1
 fbi_VAR.value
 should already give me the float I am trying to read out. However, it 
fails.

Could you please provide me with any hints whatsoever and help me out of 
this mess?

I will be eternally grateful.

Cheers,
Borislav

von Jürgen (Guest)


Rate this post
useful
not useful
Could you elaborate what you mean by "it fails"?
(Compiler, wrong values, ...)

Jürgen

von gast (Guest)


Rate this post
useful
not useful
Dear Jürgen,

When I write '-1.0' for instance the hexadecimal representation of it is 
'0x7F800000'. When I read the bytes out within the chip I get 
'0x7F800000' but the float value assigned to my variable is '-0'.

If this helps:

Whenever I read out the bytes in reverse order - that is '0x0000807F', I 
get the following number '4.60957130e-041', which is exactly the same 
value I get also within the second debug platform (when I reverse bytes 
there as well of course) which I use to send the float data remotely.

Looking forward to your reply!

Best,
Borislav

von Rene H. (Guest)


Rate this post
useful
not useful
How did you take care to the endianness?

Please show also the code part where the values are written into the 
eeprom.

Regards,
René

von Lupin (Guest)


Rate this post
useful
not useful
float myflaot = -1.0f;
char* mychar = ((char*)&myfloat);
float myfloat2 = *((float*)mychar);

wouldnt this work?

von gast (Guest)


Rate this post
useful
not useful
Dear All,

Here is the code I use to read and write to the EEPROM:
1
unsigned char eeprom_read_byte(const unsigned int addr)
2
{
3
    while(EECR & (1<<EEWE));
4
    #asm("cli");
5
  
6
    EEARH = ((addr & 0xFF00) >> 8);
7
    EEARL = ( addr & 0x00FF );
8
    
9
    EECR |= (1 << EERE);       // start read access
10
  
11
    #asm("sei");
12
    return EEDR;
13
}
14
15
void eeprom_write_byte(unsigned int addr, unsigned char val)
16
{
17
    while(EECR & (1<<EEWE));
18
    #asm("cli");
19
20
    EEARH = ((addr & 0xFF00) >> 8);
21
    EEARL = ( addr & 0x00FF );
22
    
23
    EEDR = val;
24
    
25
    EECR = 0x04;
26
    EECR = 0x02;
27
28
    while(EECR & (1<<EEWE));
29
    #asm("sei");
30
31
}

I don't really see the point of sending it since as I already told you - 
it works. As for the endianness it just depends where I write the first 
byte of the 4-byte long chunk of memory -> in
1
 fbi_VAR.byte_val[0x03]
 or
1
 fbi_VAR.byte_val[0x00]
.

@Lupin:

I still haven't checked your proposition out.

Probably I didn't make it clear enough, though -> I am using two debug 
platforms for the two chips which comprise my system. The ATA6286 is the 
slave. This means that the float values are written down into the EEPROM 
bytewise externally, and then read out by the ATA6286. This means that
1
 float myflaot = -1.0f;
 line will not be applicable for my case since this variable declaration 
should appear within the code for the other chip and is thus not visible 
for the ATA6286. Nevertheless, I got the idea and will try it out right 
away. I will write back to provide feedback.

Best regards,
Borislav

von gast (Guest)


Rate this post
useful
not useful
Dear Lupin,

Your idea doesn't help much unfortunately. I tried it out but still 
nothing. :( So problem still not solved!!!

Looking forward to your input.

Best regards,
Borislav

von Rene H. (Guest)


Rate this post
useful
not useful
(Under the circumstance I dont't know much about ATA6286 but ....)

this looks a little bit sensless to me?
1
    EECR = 0x04;
2
    EECR = 0x02;

von Jürgen (Guest)


Rate this post
useful
not useful
> When I write '-1.0' for instance the hexadecimal representation of it is
> '0x7F800000'.

That is a bit strange. In IEEE754 single precision floating point this 
is positive infinity. -1.0 is 0xbf800000.

So maybe the cause of your problem is that you have incompatible 
floating point formats?

Jürgen

von gast (Guest)


Rate this post
useful
not useful
Dear Jürgen,

This is also the only explanation I can think of.

I actually defined a float in the ATA6286, assigned '-1.0' to it and 
wrote it to the EEPROM internally. The hexidecimal representation for it 
was exactly '0xBF800000', which is completely different from the 
representation of the PIC controller ('0x7F800000') I am using as a 
master device.

Do you have any idea about any possible workaround for this problem?

Thank you very much for the help!

Best regards,
Borislav

von Alex (Guest)


Rate this post
useful
not useful
It should be a matter of bias and sign/exp encoding.
Try to find how the PIC encodes the exponent, the bias used and where is 
the sign. And then write a small conversion routine because both formats 
are not compatible :-(

von gast (Guest)


Rate this post
useful
not useful
Dear All,

PROBLEM SOLVED!!! :)

It turns out that the ATA6286 and the Microchip PIC microcontroller I am 
using use different data formats (as Jürgen already pointed out). I did 
a bit of testing and it seems that the ATA6286 uses the most common 
standard IEEE 754, while the Microchip (for whatever historical reasons 
the manufacturer does not mention) uses the PICmicro(TM) 32-BIT Floating 
Point Representation.

The difference between both is minute - just the position of the sign 
bit. While in the case of IEEE 754 the sign bit stays leftmost, the sign 
bit in the PICmicro notation stays at position 9 starting the counting 
from 1 from left to right (bit 23).

SOLUTION:
---------
                .
ATA6286 Float:  seee eeee emmmm mmmm mmmm mmmm mmmm mmmm
                          .
PIC Float:      eeee eeee smmmm mmmm mmmm mmmm mmmm mmmm

s = sign bit, e = exponent, m = mantissa

Swaping the positions of the sign bits seems to be enough for the 
conversion from one type to the other.

Anyways thanks to all those who replied and tried to help. I appreciate 
it!

Best regards,
Borislav

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.