STM32/STM8技术论坛
直播中

李德鹏

8年用户 205经验值
私信 关注
[问答]

STM32F103VET6flash存储float变量,读取时为什么只有整数部分

        用STM32F103VET6flash存储float变量,读取时只有整数部分。代码如下:往flash写13.12,读出来DATAW[0]显示13.0。

#define FLASH_PAGE_SIZE         ((uint32_t)0x00000800)   /* FLASH Page Size */
#define FLASH_USER_START_ADDR   ((uint32_t)0x0803F800)   /* Start @ of user Flash area */
#define FLASH_USER_END_ADDR     ((uint32_t)0x0803FFFF)   /* End @ of user Flash area */

void Save_factory_parameter()
{
  uint32_t Addr = FLASH_USER_START_ADDR , i;        //FLASH_USER_START_ADDR的地址留给出厂值设置标志位用的
  FLASH_Unlock();
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
  while( FLASH_ErasePage(FLASH_USER_START_ADDR ) != FLASH_COMPLETE );
  while( FLASH_ProgramWord( Addr , 13.12 ) != FLASH_COMPLETE ) ;
  FLASH_Lock();
}

void Read_factory_parameter()
{
  uint32_t Addr = FLASH_USER_START_ADDR ;

  DATAW[0] = *(__IO uint32_t *)Addr;
}

回帖(21)

李刚

2019-2-14 05:20:11
虽然float和int在内存中都占用4个字节,但是你在调用 FLASH_ProgramWord( Addr , 13.12 )的时候,编译器会把13.12转换成整数13。
要想写入float 13.12,你得定义一个float变量。
伪代码演示:
float f = 13.12;
FLASH_ProgramWord( Addr , *((uint32_t*)&f )) //这样就把内存的4个字节写入到FLASH中。
读的时候是相反的过程。读出是一个整数,然后转换成float型的指针,读出float值。
举报

张倩

2019-2-14 05:27:32
本帖最后由 creep 于 2015-10-8 15:50 编辑

浮点数在内存中存储方式和整数不太相同,要先转换下才能能存储,你这样直接写进去应该是被强制转换成了整数进行存储所以小数部分会丢失。

具体的转换方法:float数据在内存中的存储方法
比较简单的方法是先乘个因子放大若干倍转换为整数存储然后读取时再除以这个因子还原。
举报

徐昕

2019-2-14 05:32:36
union TEST
{
unsigned int hexvalue;//4 byte
float floatvalue;//4 byte
};
存储读取时用hexvalue成员,
当float用时用floatvalue成员。
举报

黄敏

2019-2-14 05:48:09
帮顶                             
举报

李德鹏

2019-2-14 06:04:08
"比较简单的方法是先乘个因子放大若干倍转换为整数存储然后读取时再除以这个因子还原。"这个方法还不错
举报

李德鹏

2019-2-14 06:17:27
引用: 胡德胜快回答 发表于 2019-2-14 16:01
union TEST
{
unsigned int hexvalue;//4 byte

用联合体来做,我等会试一下,谢谢帮忙
举报

李晨灵

2019-2-14 06:26:09
FLASH_ProgramWord函数不是以float 方式做存储的,原型 FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);    其中 uint32_t 是整数型含数,建议你 把  float进两 两次转换成整数型,可以放大100倍方式存入
举报

姬房有

2019-2-14 06:38:15
联合体应该不错
举报

李娟

2019-2-14 06:56:51
本帖最后由 wofei1314 于 2015-10-9 07:31 编辑

while( FLASH_ProgramWord( Addr , 13.12 ) != FLASH_COMPLETE ) ;
最好改为while( FLASH_ProgramWord( Addr , 13.12f ) != FLASH_COMPLETE ) ;

然后 float DATAW[n];定义成float比较好,不知道你是如何定义的

最后用这个读:  DATAW[0] = *(__IO uint32_t *)Addr;
举报

李德鹏

2019-2-14 07:14:10
引用: zhhx1985 发表于 2019-2-14 17:26
本帖最后由 wofei1314 于 2015-10-9 07:31 编辑

while( FLASH_ProgramWord( Addr , 13.12 ) != FLASH_COMPLETE ) ;

谢谢你的回答,数组我也是定义成float型的,如右 float Data1W[2];

9楼的方法可行,我试过了。
举报

李德鹏

2019-2-14 07:22:11
引用: 你我然后 发表于 2019-2-14 15:49
虽然float和int在内存中都占用4个字节,但是你在调用 FLASH_ProgramWord( Addr , 13.12 )的时候,编译器会把13.12转换成整数13。
要想写入float 13.12,你得定义一个float变量。
伪代码演示:

非常感谢,你的方法我试了一下,可行!
举报

李德鹏

2019-2-14 07:41:16
引用: zhhx1985 发表于 2019-2-14 17:26
本帖最后由 wofei1314 于 2015-10-9 07:31 编辑

while( FLASH_ProgramWord( Addr , 13.12 ) != FLASH_COMPLETE ) ;

感谢你的回答,while( FLASH_ProgramWord( Addr , 13.12f ) != FLASH_COMPLETE ) ;这样写法编译器报错!

举报

李德鹏

2019-2-14 07:50:33
引用: yuxiangxyz 发表于 2019-2-14 16:55
FLASH_ProgramWord函数不是以float 方式做存储的,原型 FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);    其中 uint32_t 是整数型含数,建议你 把  float进两 两次转换成整数型,可以放大100倍方式存入

谢谢,你的答复
举报

石栓柱

2019-2-14 08:07:48
float乘多少倍后存int
举报

李德鹏

2019-2-14 08:12:50
引用: Xavier_1995 发表于 2019-2-14 18:37
float乘多少倍后存int

我觉得这样做有点繁琐
举报

石栓柱

2019-2-14 08:18:30
引用: szzjfyp 发表于 2019-2-14 18:42
我觉得这样做有点繁琐

这个应该最实用简单的方法了,精度基本上也不会有损失

举报

李晨灵

2019-2-14 08:28:59
float i;
int j
i=13.12;
j=(i)*100;

while( FLASH_ProgramWord( Addr ,j ) != FLASH_COMPLETE ) ;  
试一下行不行
举报

李娟

2019-2-14 08:35:56
引用: szzjfyp 发表于 2019-2-14 18:10
感谢你的回答,while( FLASH_ProgramWord( Addr , 13.12f ) != FLASH_COMPLETE ) ;这样写法编译器报错!

FLASH_ProgramWord这个函数的第二个参数你看看是啥?应该是不支持直接传float格式的,所以错误,可以这样
float val=13.12;
while( FLASH_ProgramWord( Addr ,(WORD *)(&val)) != FLASH_COMPLETE ) ;
举报

王晾其

2019-2-14 08:47:12
过来支持下!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分