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

news/2024/11/24 7:47:15/

文章目录

  • 一、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_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 \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");elseprintf("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 FFFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
... ... (省略很多的FF)FF FF FF FF FF FF FF FF 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

读写流程分析

  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 \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");elseprintf("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 FFFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF... ... (省略很多的FF)FF FF FF FF FF FF FF FF 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芯片单个数字读写测试失败!”。

http://www.ppmy.cn/news/57178.html

相关文章

可观测性:你的应用健康吗?

一、需求来源 首先来看一下&#xff0c;整个需求的来源&#xff1a;当把应用迁移到 Kubernetes 之后&#xff0c;要如何去保障应用的健康与稳定呢&#xff1f;其实很简单&#xff0c;可以从两个方面来进行增强&#xff1a; 首先是提高应用的可观测性&#xff1b;第二是提高应…

如何用 GPT-4 帮你写游戏?

你知道的&#xff0c;GPT-4 发布了。 目前你想要用上 GPT-4&#xff0c;主要的渠道是 ChatGPT Plus 。作为交了订阅费的用户&#xff0c;你可以在对话的时候选择模型来使用。 另一种渠道&#xff0c;就是申请官方 API 的排队。我在申请 New Bing Chat 的时候&#xff0c;耐心被…

交叉编译相关知识整理

因为嵌入式设备的特殊性&#xff0c;比如其内存&#xff0c;性能可能相比与通用设备较弱&#xff0c;或者设备上缺少编译工具链等等原因&#xff0c;很多时候想要在嵌入式设备上使用某些程序时&#xff0c;需要在 在通用机器上编译好&#xff0c;而在嵌入式设备上运行&#xff…

Shell(五)Bash行操作目录堆栈

1.光标移动 Ctrl a&#xff1a;移到行首。Ctrl b&#xff1a;向行首移动一个字符&#xff0c;与左箭头作用相同。Ctrl e&#xff1a;移到行尾。Ctrl f&#xff1a;向行尾移动一个字符&#xff0c;与右箭头作用相同。Alt f&#xff1a;移动到当前单词的词尾。Alt b&#…

Github创建一个新仓库,关联本地数据并上传文件的图文步骤

工作中&#xff0c;我们经常会使用github来承享别人的代码果实&#xff0c;同时我们也会把自己的成果分享给别人&#xff0c;互相帮助。 今天的这篇图文教程非常重要&#xff0c;目标是使用Github来创建一个远程仓库&#xff0c;并和本地仓库对接&#xff0c;同时要做上传新内容…

报错解决:Could not find a package configuration file provided by “Pangolin“以及一系列问题

报错解决&#xff1a;Could not find a package configuration file provided by "Pangolin" 博主在使用cmake编译自己的工程时&#xff0c;遇到了如下报错&#xff1a; CMake Error at CMakeLists.txt:5 (find_package):By not providing "FindPangolin.cmake…

QT双缓冲机制

QT双缓冲机制 双缓冲机制介绍实现步骤绘图区实现drawwidget.h文件drawwidget.cpp文件注意Painter的无参数构造 主选项区域实现mainwindow.h文件mainwindow.cpp文件 双缓冲机制介绍 双缓冲机制&#xff0c;是指在控件绘制时&#xff0c;会首先将要绘制的内容绘制在一个图片中&am…

互联网摸鱼日报(2023-04-30)

互联网摸鱼日报&#xff08;2023-04-30&#xff09; InfoQ 热门话题 被ChatGPT带火的大模型&#xff0c;如何实际在各行业落地&#xff1f; Service Mesh的未来在于网络 百度 Prometheus 大规模业务监控实战 软件技术栈商品化&#xff1a;应用优先的云服务如何改变游戏规则…