硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3042|回复: 8
收起左侧

[有问必答] 求助,C语言语法问题。。数据转换

[复制链接]

335

主题

2040

回帖

3050

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3050
发表于 2018-6-28 09:49:44 | 显示全部楼层 |阅读模式
问题描述:
一个数组 char buff[4],里面存储了4个字节的十六进制数据,是一个浮点数的十六进制表达。
希望把它转换成一个tempfloat数据。float* ffff;
采用以下语句,第二句话执行就进入了硬件fault。
    ffff=(float*)&usart_buffe[0];//取得buff的地址,并强制转换成一个浮点的地址。
  tempfloat= *ffff;//把数据赋值给浮点数tempfloat,此处死机,进入硬件fault。。。。

百思不得其解!!!!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2018-6-28 10:17:10 | 显示全部楼层
这个里面隐含了一个知识点。
1、如果用户开启了硬件FPU,那么使用float变量,务必要4字节对齐,这个要求是强制性的。你这里的char buff[4]不是4四字节对齐的,操作就会硬件异常。
2、如果关闭了硬件FPU,就不会有问题了。因为CM内核支持字节非对齐访问。

QQ截图20180628101807.png
回复

使用道具 举报

335

主题

2040

回帖

3050

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3050
 楼主| 发表于 2018-6-28 10:47:07 | 显示全部楼层
本帖最后由 caicaptain2 于 2018-6-28 10:54 编辑
eric2013 发表于 2018-6-28 10:17
这个里面隐含了一个知识点。
1、如果用户开启了硬件FPU,那么使用float变量,务必要4字节对齐,这个要求是 ...

感谢感谢! 卡在这个bug处一整天了。。。。。因为把float拆解成char[4]的时候没有问题。 把char[4]还原成float就出毛病了。
f4必须开硬件float啊。。。。。不然好浪费哦。

申明变量的时候,加个关键字对齐,是否可行?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2018-6-28 10:58:02 | 显示全部楼层
caicaptain2 发表于 2018-6-28 10:47
感谢感谢! 卡在这个bug处一整天了。。。。。因为把float拆解成char[4]的时候没有问题。 把char[4]还原成 ...

可以的,或者直接定义个uint32_t变量就行,他定义的全局变量都是4字节对齐的。
回复

使用道具 举报

5

主题

196

回帖

211

积分

高级会员

积分
211
发表于 2018-6-28 11:34:39 | 显示全部楼层
用union把float和u8做在一起就好了,让编译器去处理这些破事
回复

使用道具 举报

335

主题

2040

回帖

3050

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3050
 楼主| 发表于 2018-6-28 11:43:23 | 显示全部楼层
本帖最后由 caicaptain2 于 2018-6-28 11:49 编辑
alexyzhov 发表于 2018-6-28 11:34
用union把float和u8做在一起就好了,让编译器去处理这些破事

是的。最后就是这样子处理的。 只是代码多了好几行。
因为串口接收到的都是8位的字节,然后设计一个中间union变量,把串口buffer的全部字节复制到这个union数组里面,再处理float

再问一个问题,如下union数组,用sizeof(),希望得到tempformat[10]的字节大小40,里面怎么写?
typedef union{
float ffff;
char cccc[4];
uint8_t iiii[4];
} UserFtoCtoI  tempformat[10];    //联合体,方便整形和浮点转换。

sizeof(?)      

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2018-6-28 12:15:06 | 显示全部楼层
caicaptain2 发表于 2018-6-28 11:43
是的。最后就是这样子处理的。 只是代码多了好几行。
因为串口接收到的都是8位的字节,然后设计一个中间 ...

你的处理方法稍麻烦了,无需联合体这些。

直接定义一个结构体变量,你的数据是什么类型都没有关系,全部结构体封装进去。

然后获取这个结构体的地址发送即可,无需任何中间转换,简单省事。
接收端收到后,依然是这个结构体类型的,简单省事。
回复

使用道具 举报

335

主题

2040

回帖

3050

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3050
 楼主| 发表于 2018-7-3 15:58:34 | 显示全部楼层
eric2013 发表于 2018-6-28 12:15
你的处理方法稍麻烦了,无需联合体这些。

直接定义一个结构体变量,你的数据是什么类型都没有关系,全 ...

不是很懂?
串口接收到的数据长度不一,含义也不一样,结构体不好定义内部的数据类型和长度啊?
比如第一次串口数据是10个字节,第二次是15个字节,结构体就无法整啊
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2018-7-4 00:15:13 | 显示全部楼层
caicaptain2 发表于 2018-7-3 15:58
不是很懂?
串口接收到的数据长度不一,含义也不一样,结构体不好定义内部的数据类型和长度啊?
比如 ...

如果成长度不固定的话,的确不方便了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-19 04:00 , Processed in 0.194825 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表