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扇区

//定义flash最后一个扇区,避免与程序冲突
//存储参数最好从最后一个扇区开始使用
#define EXAMPLE_FLASH_SECTOR        (FLASH_SECTOR_NUM-1)

2)FLASH所在扇区页编号

//定义所在扇区的页编号
#define EXAMPLE_FLASH_SECTOR_PAGE   (0)

3)存储参数的个数

#define FLASH_SAVE_NUM  4
//宏定义需要存储参数的个数    一个页最多为256字节,一个参数需要占4个字节,因此最多这里为256/4=64

4)读与写的数据

uint8  write_data1;
uint16 write_data2;
uint32 write_data3;
float  write_data4;


uint8  read_data1;
uint16 read_data2;
uint32 read_data3;
float  read_data4;

uint8  read_data11;
uint16 read_data22;
uint32 read_data33;
float  read_data44;

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

uint32 read_buf[FLASH_SAVE_NUM];

三,关于flash的相关函数

1)flash_init()


//-------------------------------------------------------------------------------------------------------------------
//  @brief      flash初始化
//  @param      void 		
//  @return     				返回1有表示失败  返回0表示成功
//  @since      v1.0
//  Sample usage:               
//-------------------------------------------------------------------------------------------------------------------
uint8 flash_init(void)

2)flash_check()

//-------------------------------------------------------------------------------------------------------------------
//  @brief      校验FLASH是否有数据
//  @param      sector_num 		需要写入的扇区编号   参数范围0-1023
//  @param      page_num	 	当前扇区页的编号     参数范围0-255
//  @return     				返回1有数据,返回0没有数据,如果需要对有数据的区域写入新的数据则应该对所在扇区进行擦除操作
//  @since      v1.0
//  Sample usage:               flash_check(500,0);//校验500号扇区,第0页是否有数据
//-------------------------------------------------------------------------------------------------------------------
uint8 flash_check(uint32 sector_num, uint32 page_num)

3)flash_erase_sector()

/-------------------------------------------------------------------------------------------------------------------
//  @brief      擦除扇区
//  @param      sector_num 		需要写入的扇区编号   参数范围0-1023
//  @return     				返回1有表示失败  返回0表示成功
//  @since      v1.0
//  Sample usage:               flash_erase_sector(500);
//-------------------------------------------------------------------------------------------------------------------
uint8 flash_erase_sector(uint32 sector_num)

4)flash_page_program()

/-------------------------------------------------------------------------------------------------------------------
//  @brief      编程一页
//  @param      sector_num 		需要写入的扇区编号   参数范围0-1023
//  @param      page_num 		需要写入的页编号     参数范围0-255
//  @param      buf 		    需要写入的数据地址   传入的数组类型必须为uint32
//  @param      len 		    需要写入的数据长度   参数范围1-64
//  @return     				返回1有表示失败  返回0表示成功
//  @since      v1.0
//  Sample usage:               
//-------------------------------------------------------------------------------------------------------------------
uint8 flash_page_program(uint32 sector_num, uint32 page_num, const uint32 *buf, uint8 len)

5)flash_read_page()

//-------------------------------------------------------------------------------------------------------------------
//  @brief      编程一页
//  @param      sector_num 		需要读取的扇区编号       参数范围0-1023
//  @param      page_num 		需要读取的页编号         参数范围0-255
//  @param      buf 		    需要读取的数据地址       传入的数组类型必须为uint32
//  @param      len 		    需要读取的数据长度       参数范围1-64
//  @return     				返回1有表示失败  返回0表示成功
//  @since      v1.0
//  Sample usage:               
//-------------------------------------------------------------------------------------------------------------------
void flash_read_page(uint32 sector_num, uint32 page_num, uint32 *buf, uint8 len)

四,关于数据的写入与读取

1.关于数据的写入

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

2.关于数据的读取

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

五,整体主函数代码
int main(void)
{
    DisableGlobalIRQ();
    board_init();   //务必保留,本函数用于初始化MPU 时钟 调试串口
    flash_init();   //初始化flash
    

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

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

    
    
    EnableGlobalIRQ(0);
	
	
    //通过在线调试直接查看 read_data1 - read_data3 和 read_data11 - read_data33 变量的内容即可
	//观察写入的数据与读出的数据是否一致
    while(1)
    {

    }

    
}
  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Nor Flash代码是一种非易失性存储器的编程语言。Nor Flash是一种常见的闪存技术,用于存储固件、操作系统和其他固化数据。Nor Flash代码使用类似于C语言的语法,它可以用来编写存储在Nor Flash芯片中的程序和数据。以下是一个简单的Nor Flash代码示例: ```c #include <flash.h> // 定义存储位置和大小 #define FIRMWARE_START_ADDRESS 0x100000 #define FIRMWARE_SIZE 0x8000 // 定义固件数据 const uint8_t firmware_data[FIRMWARE_SIZE] = { 0x00, 0x01, 0x02, 0x03, // 在这里添加实际的固件数据 }; // 主程序入口 int main() { // 初始化Nor Flash硬件 flash_init(); // 擦除存储区域 flash_erase(FIRMWARE_START_ADDRESS, FIRMWARE_SIZE); // 写入固件数据 flash_write(FIRMWARE_START_ADDRESS, firmware_data, FIRMWARE_SIZE); // 退出程序 return 0; } ``` 以上是一个简单的Nor Flash代码示例,它首先包含了flash头文件,然后定义了固件在Nor Flash中的存储位置和大小。接着,定义了固件数据的数组,这里只是一个简单的示例,实际情况下应该包含实际的固件数据。然后,在主程序入口函数中,通过flash_init()函数初始化Nor Flash硬件,然后使用flash_erase()函数擦除存储区域,最后使用flash_write()函数写入固件数据。最后,返回0表示程序正常退出。 这只是一个简单的示例,实际应用中可能涉及更复杂的代码和功能。Nor Flash代码可以根据具体需求进行编写和调整,以实现相应的应用功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值