文章目录
- 一、Flash的基本读写操作
- 1.1 向芯片中的某个地址(addr:0x02)连续写入不定长的数据并读取
- 代码示例
- 读写流程分析
- 函数分析
- 1.2 向芯片中的某个地址(addr:0x00)写入一个数值
- 代码示例:
- 读写流程分析
具体的配置接上文STM32-HAL-SPI-读写W25Q128FV-JEDEC ID(1)
为了要进行芯片的读写操作,因此要先了解一下芯片的相关读写指令。
- 芯片相关的读写指令
0x50 | 允许写状态寄存器的命令 | 0x05 | 读状态寄存器命令 |
---|---|---|---|
0x01 | 写状态寄存器命令 | 0x9F | 读器件JEDEC ID命令 |
0x06 | 写使能命令 | 0x20 | 擦除扇区命令 |
0x03 | 读数据区命令 | 0xC7 | 批量擦除命令 |
0xA5 | 哑命令,可以为任意值,用于读操作 | 0x01 | 状态寄存器中的正在编程标志(WIP) |
一、Flash的基本读写操作
本次擦写测试非全片擦写,仅仅使用划定大小进行擦写
读写测试地址 | TEST_ADDR | 0 |
---|---|---|
读写测试划定大小 | TEST_SIZE | 4*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 \r\n", Tx_Buffer,BufferSize);
/*读出目标地址的数据*/
sf_ReadBuffer(Rx_Buffer,0x02,BufferSize);
printf("读出的数据为:%s\r\n", 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芯片读写不定长数据测试成功!\r\n");
else
printf("What?Falsh芯片读写不定长数据测试失败!\r\n");
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
,因为字符数组在最后是自动补0
的
读写流程分析
- 定义一个比较标志(CMP_Flag)并初始化为1,用于比较目标地址和待读取地址数据是否一致。
- 定义一个要写入的字符串
Tx_Buffer
,并通过sizeof(Tx_Buffer)/sizeof(Tx_Buffer[0])
获取其长度BufferSize
。 - 调用
sf_EraseSector
函数对存储器中的指定扇区进行擦除。 - 调用
sf_WriteBuffer
函数将Tx_Buffer
写入存储器的指定地址。 - 调用
sf_ReadBuffer
函数从存储器的指定地址读取数据到Rx_Buffer
。 - 使用 for 循环比较
Tx_Buffer
和Rx_Buffer
中的数据是否一致,如果存在不一致的情况,则将 CMP_Flag 置为0。 - 最后根据 CMP_Flag 的值输出测试结果,如果一致则输出 “恭喜,Falsh芯片读写不定长数据测试成功!” 否则输出“What?Falsh芯片读写不定长数据测试失败!”。
函数分析
sf_EraseSector(0x00000000); /*可以不写,因为后面的sf_WriteBuffer自动写前擦除*/
- 扇区擦写函数,可以一次性擦除4K字节的空间,地址为扇区的起始地址,一般设置为4的倍数,如0x0000擦除扇区1 0x2000擦除扇区2。
sf_WriteBuffer(Tx_Buffer,0x02,BufferSize);
- 连续向空间中的某个地址写入一系列数据的函数,这个函数自带擦写功能即在写之前便会自己进行擦写。
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 \r\n", WriteData[4],1);
/*读出目标地址的数据*/
sf_ReadBuffer(&ReadData,0x00,1);
printf("读出的数据为:%d \r\n", ReadData);
if(ReadData == WriteData[n])
printf("恭喜,Falsh芯片单个数字读写测试成功!\r\n\r\n\r\n");
else
printf("What?Falsh芯片单个数字读写测试失败!\r\n\r\n\r\n");
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
开始的,因此可以看到仅仅第一字节的数据改变
读写流程分析
- 定义一个测试用的字节数
n
,用于指定待写入的数据。 - 定义一个长度为 5 的
WriteData
数组,并将其第 n 个元素赋值为 12,13,14,15,16。 - 调用
sf_EraseSector
函数对存储器中的指定扇区进行擦除。 - 调用
sf_WriteBuffer
函数将WriteData[n]
写入存储器的指定地址。 - 调用
sf_ReadBuffer
函数从存储器的指定地址读取数据到ReadData
。 - 比较
ReadData
和WriteData[n]
是否相等,如果相等则输出“恭喜,Falsh芯片单个数字读写测试成功!”,否则输出“What?Falsh芯片单个数字读写测试失败!”。