项目场景:
使用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语言语法的问题。
可能的原因有三种:
- 硬件检测出错
- 编译器的问题
- 单片机的问题
通过上述测试,发现是单片机的原因,查找资料发现 :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; }
通过测试