// Question B of the first top embedded cup finals
// 7913377 vrs570540852 3754 accepted 376 K 0 Ms GCC 2259b 01:05:35
// This is a topic for simulating Modbus protocol. It mainly describes the underlying programming of C involving network transmission data encoding, CRC verification code, and floating point number conversion.
// In the floating point conversion, I directly write this encoding in the memory (in the unsigned long mode), then read this memory using the float pointer, and automatically convert it to a floating point.
// Note: you can design the conversion according to the ieee754 standard.AlgorithmOr directly use the C language float implementation features: In x86 Linux,
// The GCC compiler uses the C LanguageCode"Float F = 34.9;" compiled into assembly code "movl $0x420b999a,-4 (% EBP)" (at&t x86 Assembly format ),
// That is to say, the single-precision floating point 34.9 is represented by the integer 0x420b999a in the memory. You can use this feature to complete the conversion.
# Include <stdio. h>
# Define datastart 6
Unsigned int CRC;
Char inputstr [100];
// Convert the character to a hexadecimal integer
Unsigned int changeto16 (char ch)
{
If (CH-'9' <= 0)
Return ch-'0 ';
Else
Return ch-'A' + 10;
}
// One round of CRC Conversion
Void crc_change (unsigned int data)
{
Int I;
CRC ^ = data;
For (I = 0; I <8; I ++)
{
If (CRC> 0x0001)
{
CRC> = 1;
CRC ^ = 0xa001;
}
Else
CRC> = 1;
}
}
Int main ()
{
Unsigned int slaaddr, func, staaddr, numofbyte;
Unsigned int temp, tempcrc;
Unsigned int I, Len;
Unsigned long floatdata;
Unsigned long * longaddr;
Float * floataddr;
While (scanf ("% u, % u", & slaaddr, & func, & staaddr, & numofbyte )! = EOF)
{
CRC = 0 xFFFF;
Crc_change (slaaddr );
Crc_change (func );
Crc_change (staaddr> 8 );
Crc_change (staaddr & 0x00ff );
Crc_change (numofbyte> 8 );
Crc_change (numofbyte & 0x00ff );
Temp = CRC & 0x00ff;
Temp <= 8;
CRC = (CRC> 8) | temp;
Printf ("% 02x % 02x % 04x % 04x % x \ n", slaaddr, func, staaddr, numofbyte, CRC );
Scanf ("% s", & inputstr );
CRC = 0 xFFFF;
Crc_change (changeto16 (inputstr [0]) * 16 + changeto16 (inputstr [1]);
Crc_change (changeto16 (inputstr [2]) * 16 + changeto16 (inputstr [3]);
Len = changeto16 (inputstr [4]) * 16 + changeto16 (inputstr [5]);
Crc_change (LEN );
For (I = 0; I <Len * 2; I + = 2)
Crc_change (changeto16 (inputstr [I + datastart]) * 16 + changeto16 (inputstr [I + 1 + datastart]);
Temp = CRC & 0x00ff;
Temp <= 8;
CRC = (CRC> 8) | temp;
Tempcrc = changeto16 (inputstr [I + datastart]) x 0x1000
+ Changeto16 (inputstr [I + 1 + datastart]) x 0x0100
+ Changeto16 (inputstr [I + 2 + datastart]) x 0x0010
+ Changeto16 (inputstr [I + 3 + datastart]);
If (CRC! = Tempcrc)
{
Printf ("crc_error \ n ");
Continue;
}
For (I = 0; I <Len * 2; I + = 8)
{
Floatdata = changeto16 (inputstr [I + datastart]) * 0x10000000
+ Changeto16 (inputstr [I + 1 + datastart]) x 0x01000000
+ Changeto16 (inputstr [I + 2 + datastart]) x 0x00100000
+ Changeto16 (inputstr [I + 3 + datastart]) x 0x00010000
+ Changeto16 (inputstr [I + 4 + datastart]) x 0x00001000
+ Changeto16 (inputstr [I + 5 + datastart]) x 0x00000100
+ Changeto16 (inputstr [I + 6 + datastart]) x 0x00000010
+ Changeto16 (inputstr [I + 7 + datastart]);
longaddr = & floatdata;
floataddr = (float *) longaddr; // this step is quite dangerous. Be careful!
if (I> 0)
printf (",");
printf ("%. 1f ", * floataddr);
}< br> printf (" \ n ");
}< br> return 0;
}