Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

sending a float in serial

Status
Not open for further replies.

stygops

Newbie level 6
Joined
Aug 31, 2004
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
114
hello,
im trying to send a float number from 89s8252 to pc via serial, using the term232 I can see the number that i was sended in th ecomputer, but this is not complete..
ex:
i send 98624.8736 and i receive 95624.8800...

why this occur??

my code is in C.

void main (void)
{
float conta = 0;
unsigned char cont;
bit buffer[40];

SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xfd; /* TH1: reload value for 9600 baud */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */

conta = 98624.8736;
sprintf(buffer, "%.4f\0", conta);
{
while(buffer[cont]!=0x00)
{
putchar(buffer[cont]);
cont++;
}
while(1){}
}
}

very thanks, sorry bad english ;p
 

Hi

Define a union which consists of a float and four byte variable, then let the equal part equal to float number(that you want tosend), and send byte variables to PC.

Regards
 

If your C compiler's float is IEEE 32-bit format, then it has a 24 bit fraction, and therefore a resolution of approximately seven decimal digits.

Try using double instead of float. It has a lot more bits.
 

I have tried use double instead of float... the error remains...

circuit_seller: can you make a example of how this??
 

What is the result of the following modified code ?
Code:
void main (void)
{
double conta = 0;
unsigned char cont;
bit buffer[40];

SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xfd; /* TH1: reload value for 9600 baud */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */

conta = 98624.8736;
sprintf(buffer, "%.4lf\n", conta);
{
while(buffer[cont]!=0x00)
{
putchar(buffer[cont]);
cont++;
}

conta = 98624.8736F;
sprintf(buffer, "%.4lf\n", conta);
{
while(buffer[cont]!=0x00)
{
putchar(buffer[cont]);
cont++;
}

conta = 98624.8736L;
sprintf(buffer, "%.4lf\n", conta);
{
while(buffer[cont]!=0x00)
{
putchar(buffer[cont]);
cont++;
}

while(1){}
}
}
Telga
 

stygops said:
I have tried use double instead of float... the error remains...
Oh.
It's possible that your compiler's float and double are both 32-bits. That would be no fun. See what your compiler manuals says about that, or try printing sizeof(float) and sizeof(double).

Or maybe sprintf is broken.
 

hai,
get the starting address of float variable by a pointer and convert to char pointer and transmit those 4 bytes . on the pc side get the four char and reassable it in the same order and convert into float, that will be work fine.

please check weather the float value 98624.8736 represented by 4 bytes occupies same hex values both in ur xcompiler and the compiler on the pc side because each compiler represents float in diff format.


Murugan
 

ok,
i have used an union and send the float in bytes..
but the float is represented in '5' bytes!!
and i convert the hexa numbers that i receive and its compatible with the number sended... but rounded...
 

float will be always represented by 4 bytes in any compiler, check the attachment below if the hex values are same in ur xcompiler and compiler in pc and the value is represented by two in the same way(identical 4 byte hex values) then the compiler on the pc side may have rounded off check the preprocessor header file math.h

murugan
 

Hi stygops

Here is a code i have used to transfer a floating point result to PC from DSP UART.

union
{
char a[4];
short b[2];
float f;
} Data3,Result2,Result3;


Result2.f = GetValue(&Data2[0]);
TempValue1 = Result2.b[0] & 0xFF;
TempValue2 = (Result2.b[0] & 0xFF00) >> 8;
TempValue3 = Result2.b[1] & 0xFF;
TempValue4 = (Result2.b[1] & 0xFF00) >> 8;
while ((ScibRegs.SCICTL2.all & 0xC0) != 0xC0);
ScibRegs.SCITXBUF = TempValue1;
while ((ScibRegs.SCICTL2.all & 0xC0) != 0xC0);
ScibRegs.SCITXBUF = TempValue2;
while ((ScibRegs.SCICTL2.all & 0xC0) != 0xC0);
ScibRegs.SCITXBUF = TempValue3;
while ((ScibRegs.SCICTL2.all & 0xC0) != 0xC0);
ScibRegs.SCITXBUF = TempValue4;

in the PC side also you should get a float pointer to the received byte array.

Regards
 

muruga86 said:
float will be always represented by 4 bytes in any compiler
That is a common implementation. C does not require it.

Don't expect more than FLT_DIG decimal digits of precision for float, or DBL_DIG decimal digits for double. Those are defined in float.h. The C standard says their values must be at least 6 and 10 respectively.
 

thanks echo for the information, we mostly use float values which are of 4 bytes in length and six digits in precission. each compiler process float differently based on the values set in float.h include file.


Most C books tell you that the valid range for floats is 10-38 to 1038. Have you ever thought how such an odd range is used? Well, the answer lies in the IEEE representation. Since the exponent of a float in IEEE format is stored with a positive bias of 127, the smallest positive value that you can store in a float variable is 2-127, which is approximately 1.175 x 10-38. The largest positive value is 2128, which is about 3.4 x 1038. Similarly for a double variable the smallest possible value is 2-1023, which is approximately 2.23 x 10-308. The largest positive value that can be held in a double variable is 21024, which is approximately 1.8 x 10308. There is one more quirk. After obtaining the IEEE format for a float when time comes to actually store it in memory it is stored in the reversed order. That is if we call the four byte IEEE form as ABCD then while storing in memory it is stored in the form DCBA. Let us understand this with an example. Suppose the floating-point number in question is 5.375. Its IEEE representation is 0100 0000 1010 1100 0000 0000 0000 0000. Expressed in hex this is 40 AC 00 00. While storing this in memory it is stored as 00 00 AC 40. How do we confirm this? How else but through a program. Here it is...

main( )
{
float a = 5.375 ;
char *p ;
int i ;

p = ( char * ) &a ;
for ( i = 0 ; i <= 3 ; i++ )
printf ( "%02x ", ( unsigned char ) p ) ;
}

extracte from site


**broken link removed**
 
Last edited by a moderator:

IEEE 754 doesn't discuss bytes or byte storage order. That's up to the implementation.
Little endian machines such as Pentium use 00 00 AC 40. Big endian machines such as PowerPC use 40 AC 00 00.

The C standard doesn't require any particular floating point format. Thankfully, most modern CPUs and compilers use IEEE 754.

But all this seems to be deviating from the original question. He was sending an ASCII string, not binary.
 

i have tride again.

the code im using:

void main (void)
{
unsigned char cont=0;
union conta {
float num;
unsigned char num2[3];
};
union conta numero;

SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xfd; /* TH1: reload value for 9600 baud */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */

numero.num = 98624.8736;
while(cont<4)
{
putchar(numero.num2[cont]);
cont++;
}
while(1){}
}


the fifth byte that im receiving probably is trash..
so, now i send only four bytes, this has resolved the problem of the comunication stop if any byte is zero.
but the number 98624.8736 is rounded to 98624.875! (i calculate this using the C51.pdf file if keil help)

thanks a lot... :p
 

Hi

Use the code i have posted, you will be suceed.

Regards
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top