• STM32内部flash存储小数——别样的C语言技巧


    今天在进行STM32内部falsh存储的时候,发现固件库历程的函数原型是这样的:

    第一个是地址,在我的STM32中是2K一页的,第二个是要写入的数据。

    问题就来了,存储一个小数该怎么办呢?固件库给的是整形数据啊!

    三种解决办法:

    第一:最具大众性的

    把小数乘以系数放大,当做整数存储,然后再除以放大系数得到小数本身。例如 float  a=1.23; int b=a*100;把b存进去,取出来的时候再除以100,就可以得到小数a了。这是最简单可能也是最好想到的了,但同时,这也是最麻烦的了。稍有C语言基础的都不会选择这个方式,所以pass 掉了。

    第二:基础扎实性的

    不管你说小数,还是整数,在内存中的二进制表述形式都是0或1的组合,关键就在于怎么去解析,这里也不去说符合

    IEEE 754什么规范了,记住就是,C语言中float 4字节,double 8字节。在笔者的IDE上,指针是4字节的。
    所以,我们可以这样调用ST的库函数:
    eg:
    Address为内部flash的一个地址;
    float  a=1.23;
    FLASH_ProgramWord(Address,*(volatile uint32_t *)&a);
    先对a取地址,然后把这个地址强转成uint32_t *类型,再解引用,此时编译器会按照整形的规则去解读这个地址的内容,
    但是最后在取出这个地址的内容时,我们这样:
    *(__IO float*) Address
    首先是把地址转换成float *类型,然后解引用,编译器就会按照float的规则取解读这个地址里的内容了,这样就可以存储小数了。
    第三种:创新深思性的
    C语言中,有一个东西叫做联合,union。同样列举上面的例子 float数据a;
    建立联合体如下:

    union test
    {
      float a;
      uint32_t b;
    }Test;

    Test.a=1.23;
    你不是说ST库函数是uint32_t(4字节)类型的吗?那好,我就用联合体来给你存,
    FLASH_ProgramWord( Address,Test.b);这样进行存储,联合体的实质还是第二种方式的理论。
    读取flash数据的时候,也是直接按照库函数读取:
    *(__IO uint32_t*) Address
    但是,这样的数据可以直接和Test.b比较,看看是否相等,相等证明写入和读取一致,是成功的。当我们想用float数据的时候,
    直接使用Test.a

    Summary:
    活学活用C语言,带着创造性去研究,方能看到些许 Linus Torvalds的思维。


  • 相关阅读:
    Java线程池之ThreadPoolExecutor
    React Native开发环境的搭建
    Android Lint——内嵌于Android Studio的代码优化工具
    Android异步处理技术
    NavigationView的头部的事件监听
    进程间通信之AIDL
    跨进程通信之Messenger
    Android 进程增加存活率
    android MVP模式思考
    Vim学习
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/8604904.html
Copyright © 2020-2023  润新知