[讨论] 【AG32VF407测评】学习SPI Flash读写测试

meiyao   2023-9-2 16:11 楼主

今天写一篇大佬lenxvp发的SPI,个人感觉这个芯片非常的神奇,经过些时间的学习,体会到了更上一层楼的感觉,所以特意发一篇出来。

先说一个SPI的特点和问题点,

当实现对板载SPI_FLASH的读写操作时,需要注意以下几点1

  1. 不同型号的SPI_FLASH在命令和支持的参数上可能存在差异,因此需要根据具体的型号和规格进行操作。
  2. 可以使用SFUD(串行 Flash 通用驱动)等工具来规避不同型号的SPI_FLASH之间的差异,并实现统一管理。
  3. 添加分区管理功能可以更好地管理SPI_FLASH中的数据,例如将数据存储在不同的区域或对数据进行分类。
  4. 可以使用flash实现数据库管理,例如将数据存储在数据库中,以便于查询、修改和删除等操作。
  5. 扩展SPI外设的开发可以增加更多的功能和性能,例如增加更多的控制指令、优化数据传输速度等。

AG32VF407的Flash-SPI控制器是一个用于控制SPI通信的模块,它支持使用SPI协议对Flash存储器进行读写操作。

该控制器包括以下3组17个寄存器:

  1. 控制寄存器(CTRL):用于配置和控制SPI控制器的操作。
  2. 段控制寄存器(PHASE_CTRL):每个段控制寄存器都可以独立配置,用于控制每个段的子操作。
  3. 段数据寄存器(PHASE_DATA):用于存储每个段的数据。

Flash-SPI控制器可以将一轮完整的读写或配置等操作细分为8个以下的段(PHASE),每个段都可以配置为独立的子操作,例如读写数据、读取数据等。通过映射引脚的方式,可以将SPI0和SPI1连接到Flash存储器上,从而使用这两个SPI接口来控制Flash的读写操作。

以上这些都是在网站上查询的,可能个别有一些区别。

1、原理图:

1693641517473.jpg

MCU引脚连接:

1693641626556.jpg

Flash实物位置:

1693641739605.png

 

 

 2、SPI的使用方法与特点:

1693641834809.jpg
1693641951810.jpg

 3、读取时序与框架:

 

1693642020278.jpg

 

 

1693642123148.jpg
 

4.代码的分析,这个写的非常的好,所以贴出来,让我一下就明白了用处:

这段代码是C语言编写的,用于与SPI(串行外设接口)闪存进行通信并获取其相关标识信息。让我逐行解释一下代码的各个部分。

第1行:


 
cuint32_t eid = SPI_FLASH_ReleaseDP(spi);

这行代码调用了名为SPI_FLASH_ReleaseDP的函数,它将spi作为参数传递给该函数。该函数的目的是释放双端口(DP)的SPI闪存。该函数的返回值被存储在名为eid的变量中。uint32_t是一个无符号32位整数类型,用于表示eid变量的数据类型。

第2行:


 
cprintf("Electronic ID: 0x%x\n", eid);

这行代码使用printf函数打印一条消息,消息的内容是"Electronic ID: 0x%x\n"。其中,%x是一个格式说明符,表示以16进制格式打印变量eid的值。

第3行:


 
cuint32_t rdid = SPI_FLASH_ReadID(spi);

这行代码调用了名为SPI_FLASH_ReadID的函数,它将spi作为参数传递给该函数。该函数的目的是读取SPI闪存的ID。该函数的返回值被存储在名为rdid的变量中。

第4行:


 
cprintf("RDID: 0x%06x\n", rdid);

这行代码使用printf函数打印一条消息,消息的内容是"RDID: 0x%06x\n"。其中,%06x表示以16进制格式打印变量rdid的值,并保留至少6位数的宽度。

第5行:


 
cuint32_t mfid = SPI_FLASH_ReadManufacturerID(spi);

这行代码调用了名为SPI_FLASH_ReadManufacturerID的函数,它将spi作为参数传递给该函数。该函数的目的是读取SPI闪存的制造商ID。该函数的返回值被存储在名为mfid的变量中。

第6行:


 
cprintf("MFID: 0x%04x\n", mfid);

这行代码使用printf函数打印一条消息,消息的内容是"MFID: 0x%04x\n"。其中,%04x表示以16进制格式打印变量mfid的值,并保留至少4位数的宽度。

第7行:


 
cuint32_t uniqueID[4] = {0, 0, 0, 0};

这行代码定义了一个名为uniqueID的数组,该数组包含4个无符号32位整数元素,并将所有元素初始化为0。这个数组用于存储SPI闪存的唯一ID。

第8行:


 
cuint64_t mcycle = UTIL_GetMcycle();

这行代码调用了名为UTIL_GetMcycle的函数,该函数返回当前CPU的时钟周期数(以64位无符号整数表示)。返回的值被存储在名为mcycle的变量中。这个变量用于计算执行读取唯一ID操作所需的时间。

第11行:


 
cSPI_FLASH_ReadUniqueID(spi, uniqueID, spi_dmac_channel);

这行代码调用了名为SPI_FLASH_ReadUniqueID的函数,它将spi、uniqueID和spi_dmac_channel作为参数传递给该函数。该函数的目的是读取SPI闪存的唯一ID,并将结果存储在数组uniqueID中。注意,这行代码在注释中被标记为//注释符号,这意味着它被程序员暂时删除或不需要执行。可能是因为代码在某些条件下或特定情况下才会执行此行。

第12行:


 
cmcycle = UTIL_GetMcycle() - mcycle;

这行代码获取当前CPU的时钟周期数,然后减去第8行获取的初始时钟周期数,得到执行读取唯一ID操作所需的时间(以时钟周期数表示)。结果被存储在变量mcycle中。

第13行:


 
cprintf("Unique id: 0x%08x%08x%08x%08x

 

5.输出结果,相关的我就没有更改:

1693642280278.jpg

 

回复评论 (1)

板载SPI_FLASH的读写操作是有点小区别

点赞  2023-9-4 07:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复