arm-none-eabi-gcc 的 printf 好像并不能支持double的输出。
使用double f = va_arg(ap, double);并将f内存打印出来时发现,
1. 当第一次出现浮点参数时,会出现4个字节的不明数据,从而导致后面的数据顺序全乱了
2. 还一点就是参数是8字节对齐的,va_arg一次,不管什么类型都会强制偏移8个字节。
3. 现在的办法是用个8字节的缓冲,先把拿数据再出来再重新拼接
usartPrintf("ft1:\n %f %f %f\n",f[0],f[1],f[2]);
usartPrintf("ft1:\n %d\n %f %f\n",in[0],f[1],f[2]);
usartPrintf("ft2:\n %f %d\n %f\n",f[0],in[1],f[2]);
usartPrintf("ft3:\n %f %f %d\n",f[0],f[1],in[2]);
extern void hexFloatTest(double f);
hexFloatTest(f[0]);
hexFloatTest(f[1]);
hexFloatTest(f[2]);
ft1:
Hex:[E8] [3] [0] [0] [0] [0] [0] [20]
Hex:[DB] [49] [93] [40] [0] [0] [0] [0]
Hex:[0] [80] [4B] [40] [0] [0] [0] [A0]
ft1:
1334
Hex:[0] [80] [4B] [40] [0] [0] [0] [A0]
Hex:[1] [BC] [DD] [3F] [0] [0] [0] [A0]
ft2:
Hex:[E8] [3] [0] [0] [0] [0] [0] [20]
1083394523
Hex:[1] [BC] [DD] [3F] [0] [0] [0] [A0]
ft3:
Hex:[E8] [3] [0] [0] [0] [0] [0] [20]
Hex:[DB] [49] [93] [40] [0] [0] [0] [0]
1078689792
Hex:[0] [0] [0] [20] [DB] [49] [93] [40]
Hex:[0] [0] [0] [0] [0] [80] [4B] [40]
Hex:[0] [0] [0] [A0] [1] [BC] [DD] [3F]
解决办法:
void uartPrintfloat(const char* format, ...)
{
char str[30];
char c = 0;
char ch = 0;
bool catchFloat = 0;
union _floatHex
{
double _f;
uint8_t _u8;
int8_t _i8;
uint16_t _u16;
int16_t _i16;
uint32_t _u32;
int32_t _i32;
uint64_t _u64;
int64_t _i64;
uint8_t hex[8];
}ftmp;
va_list ap;
va_start(ap, format);
char *p = 0;
while ((c = *format))
{
switch (c)
{
case '%':
ch = *++format;
switch (ch)
{
case 'd':
{
if(catchFloat)
{
p = va_arg(ap, char[8]);
memcpy(&ftmp.hex[4],p,4);
}
else
{
p = va_arg(ap, char[8]);
memcpy(&ftmp.hex[0],p,8);
}
myitoa(ftmp._i64, str, 10);
Serial_puts(&serialHandle[serial1], str);
break;
}
case 'f':
if (!catchFloat)
{
catchFloat = 1;
/**FIXME 第一次遇到浮点数据时,前面有4个不明字节数据, 跳过它! */
/**NOTE 不管什么类型都是8字节对齐的! */
p = va_arg(ap, char[8]);
memcpy(ftmp.hex,&p[4],4);
}
p = va_arg(ap, char[8]);
memcpy(&ftmp.hex[4],p,4);
// hexFloatTest(f);
int32_t n;
n = ftmp._f;
myitoa(n, str, 10);
Serial_puts(&serialHandle[serial1], str);
Serial_putc(&serialHandle[serial1], '.');
n = (ftmp._f - n) * 1000000;
if (n < 0)
n = (unsigned)-n;
myitoa(n, str, 10);
Serial_puts(&serialHandle[serial1], str);
memcpy(ftmp.hex,&p[4],4);
break;
case '%':
Serial_putc(&serialHandle[serial1], '%');
break;
default:
Serial_putc(&serialHandle[serial1], '%');
Serial_putc(&serialHandle[serial1], ch);
break;
}
break;
default:
Serial_putc(&serialHandle[serial1], c);
break;
}
format++;
}
va_end(ap);
Serial_flush(&serialHandle[serial1]);
}
重新测试:
double f[3]={1234.464f,55.0f,0.4646f};
uint32_t in[3]={1334,56463,846};
// usartPrintf("float test1:%f--%f---%f##\n",1234.0154f,12.0f,34.464f);
// usartPrintf("ft1:\n %f %f %f\n",f[0],f[1],f[2]);
// usartPrintf("ft1:\n %d\n %f %f\n",in[0],f[1],f[2]);
// usartPrintf("ft2:\n %f %d\n %f\n",f[0],in[1],f[2]);
// usartPrintf("ft3:\n %f %f %d\n",f[0],f[1],in[2]);
// extern void hexFloatTest(double f);
// hexFloatTest(f[0]);
// hexFloatTest(f[1]);
// hexFloatTest(f[2]);
extern void uartPrintfloat(const char* format, ...);
uartPrintfloat("ft1:\n %f %f %f\n",f[0],f[1],f[2]);
uartPrintfloat("ft1:\n %d\n %f %f\n",in[0],f[1],f[2]);
uartPrintfloat("ft2:\n %f %d\n %f %d\n",f[0],in[1],f[2], in[2]);
uartPrintfloat("ft3:\n %f %f %d\n",f[0],f[1],in[2]);
ft1:
1234.463989 55.0 0.464599
ft1:
1334
0.464599 0.464599
ft2:
1234.463989 56463
0.464599 846
ft3:
1234.463989 55.0 846
貌似可以用了,字符串参数类型没有测试,估计后面还有坑