您现在的位置是:首页 >学无止境 >STM32-HAL-SPI-W25Q128FV简单读写测试(2)网站首页学无止境

STM32-HAL-SPI-W25Q128FV简单读写测试(2)

青云双青 2023-06-25 20:00:02
简介STM32-HAL-SPI-W25Q128FV简单读写测试(2)

具体的配置接上文STM32-HAL-SPI-读写W25Q128FV-JEDEC ID(1)

为了要进行芯片的读写操作,因此要先了解一下芯片的相关读写指令。

  • 芯片相关的读写指令
0x50允许写状态寄存器的命令0x05读状态寄存器命令
0x01写状态寄存器命令0x9F读器件JEDEC ID命令
0x06写使能命令0x20擦除扇区命令
0x03读数据区命令0xC7批量擦除命令
0xA5哑命令,可以为任意值,用于读操作0x01状态寄存器中的正在编程标志(WIP)

一、Flash的基本读写操作

本次擦写测试非全片擦写,仅仅使用划定大小进行擦写

读写测试地址TEST_ADDR0
读写测试划定大小TEST_SIZE4*1024
连续擦写起始地址0x02
读写一个数值地址0x00

1.1 向芯片中的某个地址(addr:0x02)连续写入不定长的数据并读取

void falsh_Read_Write_Test(void)

向flash芯片写入一串不定长的数据
存储的时候类型都是以字符或者数字

代码示例

void falsh_Read_Write_Test(void)
{	
	uint8_t i;
	uint8_t CMP_Flag = 1;
	
	uint8_t Tx_Buffer[] = "HelloWorld";  
	const uint8_t BufferSize  = sizeof(Tx_Buffer)/sizeof(Tx_Buffer[0]);//要写入的数据长度
	uint8_t Rx_Buffer[BufferSize];//缓冲区的大小是待定的
	
	/*擦除1个扇区 全部写为0xFF 即全部的bit刷为1*/
	sf_EraseSector(0x00000000);  /*可以不写,因为后面的sf_WriteBuffer自动写前擦除*/
	/*向目标地址写入数据*/
	sf_WriteBuffer(Tx_Buffer,0x02,BufferSize);
	printf("写入的数据为:%s 写入数据的大小为:%d 
", Tx_Buffer,BufferSize);
	/*读出目标地址的数据*/
	sf_ReadBuffer(Rx_Buffer,0x02,BufferSize);
	printf("读出的数据为:%s
", Rx_Buffer);
	
	/*比较目标地址和待读取地址数据*/
	for(i=0;i<BufferSize;i++)
	{
		if(Tx_Buffer[i] != Rx_Buffer[i])
		{
			CMP_Flag = 0;
			break;
		}
	}
	
	if(CMP_Flag == 1)
		printf("恭喜,Falsh芯片读写不定长数据测试成功!
");
	else
		printf("What?Falsh芯片读写不定长数据测试失败!
");
	
	HAL_Delay(1000);	
    
    sfReadTest();	/* 读串行Flash数据,并打印出来数据内容 */
}
  • 打印出来的数据:
[result]
FF FF 48 65 6C 6C 6F 57 6F 72 6C 64 00 FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
... ... (省略很多的FF)
 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
数据长度: 4096字节, 读耗时: 3ms, 读速度: 1365333 Bytes/s   
  • 执行扇区擦写,全部擦写为0xFF,即将每一个比特位写入1,因此可以看到全部都是FF
  • 执行写的地址是从0x02开始的,因此可以看到第三位的数据才改变
  • 后面连续的11字节写入预设的字符串
  • 但是最后一位补了,因为字符数组在最后是自动补0

读写流程分析

  1. 定义一个比较标志(CMP_Flag)并初始化为1,用于比较目标地址和待读取地址数据是否一致。
  2. 定义一个要写入的字符串 Tx_Buffer,并通过 sizeof(Tx_Buffer)/sizeof(Tx_Buffer[0]) 获取其长度 BufferSize
  3. 调用 sf_EraseSector 函数对存储器中的指定扇区进行擦除。
  4. 调用sf_WriteBuffer函数将Tx_Buffer写入存储器的指定地址。
  5. 调用 sf_ReadBuffer 函数从存储器的指定地址读取数据到 Rx_Buffer
  6. 使用 for 循环比较 Tx_BufferRx_Buffer 中的数据是否一致,如果存在不一致的情况,则将 CMP_Flag 置为0。
  7. 最后根据 CMP_Flag 的值输出测试结果,如果一致则输出 “恭喜,Falsh芯片读写不定长数据测试成功!” 否则输出“What?Falsh芯片读写不定长数据测试失败!”。

函数分析

sf_EraseSector(0x00000000);  /*可以不写,因为后面的sf_WriteBuffer自动写前擦除*/
  • 扇区擦写函数,可以一次性擦除4K字节的空间,地址为扇区的起始地址,一般设置为4的倍数,如0x0000擦除扇区1 0x2000擦除扇区2。

在这里插入图片描述

擦除一个扇区,256个字节

sf_WriteBuffer(Tx_Buffer,0x02,BufferSize);
  • 连续向空间中的某个地址写入一系列数据的函数,这个函数自带擦写功能即在写之前便会自己进行擦写。

在这里插入图片描述

按位置连续写入

在这里插入图片描述

写入的11个字节数据放大图
sfReadTest();	
  • 读测试函数,可以将测试区域按字节打印到终端。

1.2 向芯片中的某个地址(addr:0x00)写入一个数值

void falsh_Read_Write_OneData_Test(void)

向Flash芯片写入一个数值,由于Flash的一个字节有8位,因此就是存储一个值的范围是0~255

代码示例:

void falsh_Read_Write_OneData_Test(void)
{	
	#define n 4  //测试用,指定一个字节
	
	uint8_t WriteData[5] = {12,13,14,15,16};  
	uint8_t ReadData = 0;  
	
	/*擦除扇区*/
	sf_EraseSector(0x00000000);  //要求地址为4的倍数 
	/*向目标地址写入数据*/
	sf_WriteBuffer(&WriteData[n],0x00,1);
	printf("写入的数据为:%d 写入数据的大小为:%d 
", WriteData[4],1);
	/*读出目标地址的数据*/
	sf_ReadBuffer(&ReadData,0x00,1);
	printf("读出的数据为:%d 
", ReadData);	
	
	if(ReadData == WriteData[n])
		printf("恭喜,Falsh芯片单个数字读写测试成功!


");
	else
		printf("What?Falsh芯片单个数字读写测试失败!


");
	
	HAL_Delay(1000);	
	
	sfReadTest();	/* 读串行Flash数据,并打印出来数据内容 */
}
  • 查看Flash的读写情况
10 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
 ... ... (省略很多的FF)
 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
数据长度: 4096字节, 读耗时: 3ms, 读速度: 1365333 Bytes/s
  • 执行扇区擦写,全部擦写为0xFF,即将每一个比特位写入1,因此可以看到全部都是FF
  • 执行写的地址是从0x00开始的,因此可以看到仅仅第一字节的数据改变

读写流程分析

  1. 定义一个测试用的字节数 n,用于指定待写入的数据。
  2. 定义一个长度为 5 的 WriteData 数组,并将其第 n 个元素赋值为 12,13,14,15,16。
  3. 调用 sf_EraseSector 函数对存储器中的指定扇区进行擦除。
  4. 调用sf_WriteBuffer函数将 WriteData[n] 写入存储器的指定地址。
  5. 调用 sf_ReadBuffer 函数从存储器的指定地址读取数据到ReadData
  6. 比较 ReadDataWriteData[n]是否相等,如果相等则输出“恭喜,Falsh芯片单个数字读写测试成功!”,否则输出“What?Falsh芯片单个数字读写测试失败!”。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。