字节转浮点数

项目场景:

使用STM32串口通讯,读取仪器的值,数值通过单精度浮点数来传输的。


问题描述

通过串口读取的数据,需要把4个字节转化为Float,转化过程出现死机的现象,经过排除就发下在运行到

return *((float*)byteArray);

之后就会进入硬件中断,如下所示

HardFault_Handler

        ;// This version is for Cortex M3, Cortex M4 and Cortex M4F
        tst    LR, #4            ;// Check EXC_RETURN in Link register bit 2.
        ite    EQ
        mrseq  R0, MSP           ;// Stacking was using MSP.
        mrsne  R0, PSP           ;// Stacking was using PSP.
        b      HardFaultHandler  ;// Stack pointer passed through R0.

        END

相关代码如下所示:

static float ByteToFloat(uint8_t* byteArray)
{  
    return *((float*)byteArray);
}

static void test(uint8_t *_ucaBuf, uint16_t _usLen)
{
    float flag;
    uint8_t *p;
    p = &_ucaBuf[0];
    float = ByteToFloat(p);
}

void main()
{
    uint8_t byteTemp[5] = { 0x00, 0x01, 0xe2, 0x40, 0x01 };
    test(byteTemp,5)
}

使用电脑,进一步测试

int main()
{
	uint8_t byteTemp[4] = { 0x00, 0x01, 0xe2, 0x40, 0x01 };
	float testv = *((float*)byteTemp);

    printf("%f can be written %e\n",testv,testv);
}

输出结果:7.062622 can be written 7.062622e+000

通过上面测试发现C语言支持这种写法,但是不清楚为何单片机内不能这样写。

换一片单片机,继续测试

    uint8_t byteTemp[8] = { 0x00, 0x01, 0xe2, 0x40, 0x00, 0x01, 0xe2, 0x40};
    float testv = *((float *)&byteTemp[0]);
    printf("%f can be written %e\n", testv, testv);

设置byteTemp[0],可以正常运行

设置byteTemp[4],也可以正常运行

其他值,会进入HardFault_Handler。

通过这个测试可以基本确定是单片机的原因。

原因分析:

通过电脑测试,排除了C语言语法的问题。

可能的原因有三种:

  1. 硬件检测出错
  2. 编译器的问题
  3. 单片机的问题

通过上述测试,发现是单片机的原因,查找资料发现 :STM32在程序调用入口处必须满足8字节对齐,对于C语言,不需要用户去管,编译器都帮我们处理好了。


解决方案:

将ByteToFloat更改

static float ByteToFloat(uint8_t *byteArray)
{
  float flag;
  uint8_t byte[4];
 
  memcpy(byte,byteArray,4);
 
  flag = *((float *)byte);
  return flag;
}

通过测试

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值