查看: 1858|回复: 0

[分享] RT1064学习笔记(5)--Flash例程(Flash Demo)

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32018
    最后登录
    2024-4-9
    发表于 2020-5-14 09:56:22 | 显示全部楼层 |阅读模式
    RT1064学习笔记(5)--Flash例程(Flash Demo)

    RT1064之Flash例程
    Ps:本例程主要作用是,展示如何使用FLASH储存数据的概念
    主板为:逐飞RT1064 + 母板


    一,NAND flash 控制原理(基于RT1052)
    NAND flash 作用类似于电脑的固态硬盘,主要用于存储数据。相同容量 NAND flash要比 Nor flash 便宜很多, NAND flash 只能按页读、写,所以在 NAND flash 中不能执行代码。 NAND flash 一般容量较大,用于存储大量的数据。


    二,FLASH宏定义介绍
    1)FLAHS扇区
    1. <font face="微软雅黑" size="3">//定义flash最后一个扇区,避免与程序冲突
    2. //存储参数最好从最后一个扇区开始使用
    3. #define EXAMPLE_FLASH_SECTOR        (FLASH_SECTOR_NUM-1)</font>
    复制代码
    2)FLASH所在扇区页编号
    1. <font face="微软雅黑" size="3">//定义所在扇区的页编号
    2. #define EXAMPLE_FLASH_SECTOR_PAGE   (0)</font>
    复制代码
    3)存储参数的个数
    1. <font face="微软雅黑" size="3">#define FLASH_SAVE_NUM  4
    2. //宏定义需要存储参数的个数    一个页最多为256字节,一个参数需要占4个字节,因此最多这里为256/4=64</font>
    复制代码
    4)读与写的数据
    1. <font face="微软雅黑" size="3">uint8  write_data1;
    2. uint16 write_data2;
    3. uint32 write_data3;
    4. float  write_data4;


    5. uint8  read_data1;
    6. uint16 read_data2;
    7. uint32 read_data3;
    8. float  read_data4;

    9. uint8  read_data11;
    10. uint16 read_data22;
    11. uint32 read_data33;
    12. float  read_data44;

    13. //存储数据数组
    14. uint32 write_buf[FLASH_SAVE_NUM];

    15. uint32 read_buf[FLASH_SAVE_NUM];
    16. </font>
    复制代码
    三,关于flash的相关函数
    1)flash_init()
    1. <font face="微软雅黑" size="3">//-------------------------------------------------------------------------------------------------------------------
    2. //  @brief      flash初始化
    3. //  @param      void                 
    4. //  @return                                     返回1有表示失败  返回0表示成功
    5. //  @since      v1.0
    6. //  Sample usage:               
    7. //-------------------------------------------------------------------------------------------------------------------
    8. uint8 flash_init(void)
    9. </font>
    复制代码
    2)flash_check()
    1. <font face="微软雅黑" size="3">//-------------------------------------------------------------------------------------------------------------------
    2. //  @brief      校验FLASH是否有数据
    3. //  @param      sector_num                 需要写入的扇区编号   参数范围0-1023
    4. //  @param      page_num                 当前扇区页的编号     参数范围0-255
    5. //  @return                                     返回1有数据,返回0没有数据,如果需要对有数据的区域写入新的数据则应该对所在扇区进行擦除操作
    6. //  @since      v1.0
    7. //  Sample usage:               flash_check(500,0);//校验500号扇区,第0页是否有数据
    8. //-------------------------------------------------------------------------------------------------------------------
    9. uint8 flash_check(uint32 sector_num, uint32 page_num)
    10. </font>
    复制代码
    3)flash_erase_sector()
    1. <font face="微软雅黑" size="3">/-------------------------------------------------------------------------------------------------------------------
    2. //  @brief      擦除扇区
    3. //  @param      sector_num                 需要写入的扇区编号   参数范围0-1023
    4. //  @return                                     返回1有表示失败  返回0表示成功
    5. //  @since      v1.0
    6. //  Sample usage:               flash_erase_sector(500);
    7. //-------------------------------------------------------------------------------------------------------------------
    8. uint8 flash_erase_sector(uint32 sector_num)
    9. </font>
    复制代码
    4)flash_page_program()
    1. <font face="微软雅黑" size="3">/-------------------------------------------------------------------------------------------------------------------
    2. //  @brief      编程一页
    3. //  @param      sector_num                 需要写入的扇区编号   参数范围0-1023
    4. //  @param      page_num                 需要写入的页编号     参数范围0-255
    5. //  @param      buf                     需要写入的数据地址   传入的数组类型必须为uint32
    6. //  @param      len                     需要写入的数据长度   参数范围1-64
    7. //  @return                                     返回1有表示失败  返回0表示成功
    8. //  @since      v1.0
    9. //  Sample usage:               
    10. //-------------------------------------------------------------------------------------------------------------------
    11. uint8 flash_page_program(uint32 sector_num, uint32 page_num, const uint32 *buf, uint8 len)
    12. </font>
    复制代码
    5)flash_read_page()
    1. <font face="微软雅黑" size="3">//-------------------------------------------------------------------------------------------------------------------
    2. //  @brief      编程一页
    3. //  @param      sector_num                 需要读取的扇区编号       参数范围0-1023
    4. //  @param      page_num                 需要读取的页编号         参数范围0-255
    5. //  @param      buf                     需要读取的数据地址       传入的数组类型必须为uint32
    6. //  @param      len                     需要读取的数据长度       参数范围1-64
    7. //  @return                                     返回1有表示失败  返回0表示成功
    8. //  @since      v1.0
    9. //  Sample usage:               
    10. //-------------------------------------------------------------------------------------------------------------------
    11. void flash_read_page(uint32 sector_num, uint32 page_num, uint32 *buf, uint8 len)
    12. </font>
    复制代码
    四,关于数据的写入与读取
    1.关于数据的写入
    1. <font face="微软雅黑" size="3"> //设置需要写入的数据
    2.     write_data1 = 66;
    3.     write_data2 = 6666;
    4.     write_data3 = 666666;
    5.     write_data4 = 6666.66;
    6.    
    7.     if(flash_check(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE))//校验当前 扇区所在页是否有数据,如果有数据则擦除整个扇区
    8.     {
    9.         status = flash_erase_sector(EXAMPLE_FLASH_SECTOR);//擦除扇区,如果扇区已经有数据则必须擦除扇区之后才能再次写入新的数据
    10.         if(status)  while(1);//擦除失败
    11.     }
    12.    
    13.     write_buf[0] = write_data1;
    14.     write_buf[1] = write_data2;
    15.     write_buf[2] = write_data3;
    16.    
    17.     //存储浮点时,首先取变量地址然后以uint32 *来访问变量获取数据。
    18.     //write_buf[3] = *(uint32 *)&write_data4;
    19.     //不能使用此类格式write_buf[3] = (uint32)write_data4;这样会导致强制转换为整型,导致小数部分丢失
    20.     //也可以使用库提供的宏定义 读取float类型的二进制数据
    21.     write_buf[3] = float_conversion_uint32(write_data4); //
    22.    
    23.     status = flash_page_program(EXAMPLE_FLASH_SECTOR, EXAMPLE_FLASH_SECTOR_PAGE, write_buf, FLASH_SAVE_NUM);
    24.     if(status)  while(1);//写入失败
    25. </font>
    复制代码
    2.关于数据的读取
    1. <font face="微软雅黑" size="3">//读取数据有两个方式
    2.     //第一种方式为全部读取出来放在数组里,然后自行分配
    3.     flash_read_page(EXAMPLE_FLASH_SECTOR, EXAMPLE_FLASH_SECTOR_PAGE, read_buf, FLASH_SAVE_NUM);
    4.     //分别读取对应数据
    5.     read_data1 = read_buf[0];
    6.     read_data2 = read_buf[1];
    7.     read_data3 = read_buf[2];
    8.     read_data4 = uint32_conversion_float(read_buf[3]);      //读取浮点数时,应该使用宏函数将uint32类型转换为float
    9.    
    10.     //第二种方式,与以前的flash读取方式比较接近
    11.     DCACHE_CleanInvalidateByRange(FLASH_BASE_ADDR + EXAMPLE_FLASH_SECTOR * FLASH_SECTOR_SIZE, FLASH_SAVE_NUM*4);//读取flash前,最好先清空缓存
    12.     read_data11 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+0,uint8);
    13.     read_data22 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+1,uint16);
    14.     read_data33 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+2,uint32);
    15.     read_data44 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+3,float);
    16. </font>
    复制代码
    五,整体主函数代码
    1. <font face="微软雅黑" size="3">int main(void)
    2. {
    3.     DisableGlobalIRQ();
    4.     board_init();   //务必保留,本函数用于初始化MPU 时钟 调试串口
    5.     flash_init();   //初始化flash
    6.    

    7.     //设置需要写入的数据
    8.     write_data1 = 66;
    9.     write_data2 = 6666;
    10.     write_data3 = 666666;
    11.     write_data4 = 6666.66;
    12.         
    13.    
    14.     if(flash_check(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE))//校验当前 扇区所在页是否有数据,如果有数据则擦除整个扇区
    15.     {
    16.         status = flash_erase_sector(EXAMPLE_FLASH_SECTOR);//擦除扇区,如果扇区已经有数据则必须擦除扇区之后才能再次写入新的数据
    17.         if(status)  while(1);//擦除失败
    18.     }
    19.    
    20.     write_buf[0] = write_data1;
    21.     write_buf[1] = write_data2;
    22.     write_buf[2] = write_data3;
    23.    
    24.     //存储浮点时,首先取变量地址然后以uint32 *来访问变量获取数据。
    25.     //write_buf[3] = *(uint32 *)&write_data4;
    26.     //不能使用此类格式write_buf[3] = (uint32)write_data4;这样会导致强制转换为整型,导致小数部分丢失
    27.     //也可以使用库提供的宏定义 读取float类型的二进制数据
    28.     write_buf[3] = float_conversion_uint32(write_data4); //
    29.    
    30.     status = flash_page_program(EXAMPLE_FLASH_SECTOR, EXAMPLE_FLASH_SECTOR_PAGE, write_buf, FLASH_SAVE_NUM);
    31.     if(status)  while(1);//写入失败

    32.     //读取数据有两个方式
    33.     //第一种方式为全部读取出来放在数组里,然后自行分配
    34.     flash_read_page(EXAMPLE_FLASH_SECTOR, EXAMPLE_FLASH_SECTOR_PAGE, read_buf, FLASH_SAVE_NUM);
    35.     //分别读取对应数据
    36.     read_data1 = read_buf[0];
    37.     read_data2 = read_buf[1];
    38.     read_data3 = read_buf[2];
    39.     read_data4 = uint32_conversion_float(read_buf[3]);      //读取浮点数时,应该使用宏函数将uint32类型转换为float
    40.    
    41.     //第二种方式,与以前的flash读取方式比较接近
    42.     DCACHE_CleanInvalidateByRange(FLASH_BASE_ADDR + EXAMPLE_FLASH_SECTOR * FLASH_SECTOR_SIZE, FLASH_SAVE_NUM*4);//读取flash前,最好先清空缓存
    43.     read_data11 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+0,uint8);
    44.     read_data22 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+1,uint16);
    45.     read_data33 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+2,uint32);
    46.     read_data44 = flash_read(EXAMPLE_FLASH_SECTOR,EXAMPLE_FLASH_SECTOR_PAGE*FLASH_PAGE_SIZE+3,float);

    47.     EnableGlobalIRQ(0);

    48.     //通过在线调试直接查看 read_data1 - read_data3 和 read_data11 - read_data33 变量的内容即可
    49.         //观察写入的数据与读出的数据是否一致
    50.     while(1)
    51.     {
    52.     }
    53. }

    54. </font>
    复制代码




    文章出处:CSDN



    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-25 05:28 , Processed in 0.108787 second(s), 18 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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