Treat char [ ] array as float

Guest #1312098
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
Guest #1312136
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
Guest #1312161
How did you take care to the endianness?

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

Regards,
René
Guest #1312167
float myflaot = -1.0f;
char* mychar = ((char*)&myfloat);
float myfloat2 = *((float*)mychar);

wouldnt this work?
Guest #1312195
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
Guest #1312241
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
Guest #1312255
(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;
Guest #1312274
> 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
Guest #1312283
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
Guest #1313347
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 :-(
Guest #1313379
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

Reply

A question of your own? This thread is over 17 years old. Ask it in a thread of its own – more people read along there, and it gets answered more often and sooner.

Start a new thread

A fix, an addition or feedback on this thread? Then reply here.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.