STM32 SPI接口读写W25Q256串行FLASH实战指南
1. SPI读写串行FLASH实验概述在嵌入式系统开发中外部存储扩展是常见需求。SPI接口的串行FLASH因其体积小、容量大、接口简单等特点成为存储扩展的热门选择。本实验将基于STM32平台详细介绍如何通过SPI接口读写W25Q256串行FLASH芯片。2. 硬件设计与连接2.1 硬件选型与连接实验采用W25Q256JV系列FLASH芯片其主要特性如下存储容量32Mbit4MB工作电压2.7V-3.6VSPI时钟频率最高104MHz支持标准SPI、Dual SPI和Quad SPI模式硬件连接示意图STM32F4 W25Q256 PA5(SCK) - CLK PA6(MISO) - DO PA7(MOSI) - DI PA4(NSS) - CS 3.3V - VCC GND - GND2.2 重要引脚说明WP#写保护引脚高电平禁用写保护HOLD#暂停引脚高电平禁用暂停功能CS#片选信号低电平有效3. SPI协议基础3.1 SPI工作模式W25Q256支持SPI模式0和模式3模式0CPOL0CPHA0模式3CPOL1CPHA1实际使用中多采用模式3其时序特点时钟空闲时为高电平数据在时钟的第二个边沿下降沿采样3.2 SPI数据传输格式数据传输特点全双工同步传输MSB先行8位数据帧长度支持单线、双线和四线模式4. 软件实现4.1 SPI初始化配置void SPI_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // 使能时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // 配置GPIO GPIO_InitStruct.GPIO_Pin GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd GPIO_PuPd_UP; GPIO_Init(GPIOA, GPIO_InitStruct); GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); // 配置CS引脚 GPIO_InitStruct.GPIO_Pin GPIO_Pin_4; GPIO_InitStruct.GPIO_Mode GPIO_Mode_OUT; GPIO_Init(GPIOA, GPIO_InitStruct); GPIO_SetBits(GPIOA, GPIO_Pin_4); // 配置SPI SPI_InitStruct.SPI_Direction SPI_Direction_2Lines_FullDuplex; SPI_InitStruct.SPI_Mode SPI_Mode_Master; SPI_InitStruct.SPI_DataSize SPI_DataSize_8b; SPI_InitStruct.SPI_CPOL SPI_CPOL_High; SPI_InitStruct.SPI_CPHA SPI_CPHA_2Edge; SPI_InitStruct.SPI_NSS SPI_NSS_Soft; SPI_InitStruct.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_2; SPI_InitStruct.SPI_FirstBit SPI_FirstBit_MSB; SPI_InitStruct.SPI_CRCPolynomial 7; SPI_Init(SPI1, SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); }4.2 基本读写函数uint8_t SPI_FLASH_SendByte(uint8_t byte) { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) RESET); SPI_I2S_SendData(SPI1, byte); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) RESET); return SPI_I2S_ReceiveData(SPI1); } uint8_t SPI_FLASH_ReadByte(void) { return SPI_FLASH_SendByte(DUMMY_BYTE); }5. FLASH操作指令集5.1 常用指令列表指令名称指令编码功能描述Write Enable0x06写使能Write Disable0x04写禁止Read Data0x03读取数据Page Program0x02页编程最大256字节Sector Erase0x20扇区擦除4KBBlock Erase0xD8块擦除64KBChip Erase0xC7整片擦除Read Status Reg0x05读取状态寄存器Read ID0x9F读取制造商和设备ID5.2 状态寄存器说明状态寄存器格式| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |---|---|---|---|---|---|---|---| |SUS| 0 | 0 |BP2|BP1|BP0|WEL|BUSY|关键位说明BUSY(位0)1表示设备忙0表示就绪WEL(位1)写使能锁存位BP0-2(位2-4)块保护控制位6. 关键功能实现6.1 读取设备IDuint32_t SPI_FLASH_ReadID(void) { uint32_t Temp 0; FLASH_CS_LOW(); SPI_FLASH_SendByte(READ_ID); Temp SPI_FLASH_SendByte(DUMMY_BYTE) 16; Temp | SPI_FLASH_SendByte(DUMMY_BYTE) 8; Temp | SPI_FLASH_SendByte(DUMMY_BYTE); FLASH_CS_HIGH(); return Temp; }6.2 扇区擦除void SPI_FLASH_SectorErase(uint32_t SectorAddr) { SPI_FLASH_WriteEnable(); FLASH_CS_LOW(); SPI_FLASH_SendByte(SECTOR_ERASE); SPI_FLASH_SendByte((SectorAddr 16) 0xFF); SPI_FLASH_SendByte((SectorAddr 8) 0xFF); SPI_FLASH_SendByte(SectorAddr 0xFF); FLASH_CS_HIGH(); SPI_FLASH_WaitForWriteEnd(); }6.3 页编程void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) { SPI_FLASH_WriteEnable(); FLASH_CS_LOW(); SPI_FLASH_SendByte(PAGE_PROGRAM); SPI_FLASH_SendByte((WriteAddr 16) 0xFF); SPI_FLASH_SendByte((WriteAddr 8) 0xFF); SPI_FLASH_SendByte(WriteAddr 0xFF); while(NumByteToWrite--) { SPI_FLASH_SendByte(*pBuffer); pBuffer; } FLASH_CS_HIGH(); SPI_FLASH_WaitForWriteEnd(); }6.4 数据读取void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead) { FLASH_CS_LOW(); SPI_FLASH_SendByte(READ_DATA); SPI_FLASH_SendByte((ReadAddr 16) 0xFF); SPI_FLASH_SendByte((ReadAddr 8) 0xFF); SPI_FLASH_SendByte(ReadAddr 0xFF); while(NumByteToRead--) { *pBuffer SPI_FLASH_SendByte(DUMMY_BYTE); pBuffer; } FLASH_CS_HIGH(); }7. 实际应用注意事项7.1 擦除与写入时序写入前必须先擦除全FF状态擦除最小单位是扇区4KB写入最大单位是页256字节跨页写入需要分多次操作7.2 性能优化建议合理规划存储结构减少擦除次数批量写入时尽量对齐页边界使用双缓冲技术提高写入效率重要数据考虑写入校验机制7.3 常见问题排查写入失败检查是否执行了写使能WP引脚是否为高电平目标区域是否已擦除电源电压是否稳定读取异常检查SPI模式设置是否正确时序参数是否匹配信号线是否有干扰8. 实验验证8.1 测试流程初始化SPI接口读取设备ID验证通信擦除测试扇区写入测试数据回读校验数据比较写入与读取数据8.2 示例代码int main(void) { uint8_t write_data[] SPI FLASH Test Data; uint8_t read_data[sizeof(write_data)]; uint32_t flash_id; // 硬件初始化 SystemInit(); SPI_Config(); // 读取ID flash_id SPI_FLASH_ReadID(); if(flash_id ! W25Q256_ID) { // ID不匹配处理 while(1); } // 擦除扇区 SPI_FLASH_SectorErase(TEST_SECTOR_ADDR); // 写入数据 SPI_FLASH_PageWrite(write_data, TEST_SECTOR_ADDR, sizeof(write_data)); // 读取数据 SPI_FLASH_BufferRead(read_data, TEST_SECTOR_ADDR, sizeof(read_data)); // 数据校验 if(memcmp(write_data, read_data, sizeof(write_data)) 0) { // 测试成功 } else { // 测试失败 } while(1); }通过本实验我们完整实现了SPI接口读写串行FLASH的功能。在实际项目中可根据需求在此基础上扩展更复杂的存储管理功能如实现简单的文件系统或数据日志存储等。

相关新闻

Linux驱动移植实战:从环境搭建到调试优化

Linux驱动移植实战:从环境搭建到调试优化

1. Linux驱动移植概述第一次接触Linux驱动移植是在2012年给一块ARM开发板适配触摸屏驱动。当时花了整整三天时间才让那个该死的触摸屏正常工作,期间经历了无数次内核崩溃和硬件锁死。现在回想起来,那段经历让我深刻理解了驱动移植的本质——它就像给汽车…

2026/7/19 19:36:16阅读更多 →
MTK Android驱动开发核心技术与优化实践

MTK Android驱动开发核心技术与优化实践

1. MTK Android驱动开发全景解析作为移动芯片领域的隐形冠军,联发科(MediaTek)平台在Android设备中占据着重要市场份额。其驱动架构设计直接影响着设备性能表现和功能实现。对于开发者而言,深入理解MTK驱动体系是进行底层优化的必…

2026/7/19 19:36:16阅读更多 →
2026微服务生存指南:从单体边界到SLO契约的架构重构

2026微服务生存指南:从单体边界到SLO契约的架构重构

1. 项目概述:这不是一次技术升级,而是一场组织级生存重构“From Monolith to Microservices: A Developer’s Survival Guide in 2026”——这个标题里没有一个词是多余的。它不是在讲“如何把一个Spring Boot应用拆成十个服务”,也不是在教“…

2026/7/19 19:34:15阅读更多 →
ngx_output_chain_get_buf

ngx_output_chain_get_buf

1 定义 ngx_output_chain_get_buf 函数 定义在 src/core/ngx_output_chain.cstatic ngx_int_t ngx_output_chain_get_buf(ngx_output_chain_ctx_t *ctx, off_t bsize) {size_t size;ngx_buf_t *b, *in;ngx_uint_t recycled;in ctx->in->buf;size ctx->buf…

2026/7/20 0:15:05阅读更多 →
互联网大厂常见Java面试题及答案汇总(2026持续更新)

互联网大厂常见Java面试题及答案汇总(2026持续更新)

金九银十即将来袭,又是一个跳槽的好季节,准备跳槽的同学都摩拳擦掌准备大面好几场,今天为大家准备了互联网面试必备的 1 到 5 年 Java 面试者都需要掌握的面试题,分别 JVM,并发编程,MySQL,Tomca…

2026/7/20 0:15:05阅读更多 →
python数据可视化技巧的100个练习 -- 31. 类别数据的点图

python数据可视化技巧的100个练习 -- 31. 类别数据的点图

重要性★★★☆☆ 难度★★☆☆☆ 你是一家零售公司的数据分析师。你的经理要求你可视化最近产品发布的客户满意度评级分布。评级是分类的,范围从“非常不满意”到“非常满意”。创建一个点图以显示每个评级类别的频率。使用 Python 进行数据处理和可视化。在代码中生成输入…

2026/7/20 0:13:05阅读更多 →
智能体走进物理世界,千里科技携舱驾协同成果亮相WAIC 2026

智能体走进物理世界,千里科技携舱驾协同成果亮相WAIC 2026

在2026世界人工智能大会(WAIC 2026)举办期间,千里科技董事长、阶跃星辰董事长印奇作为特邀嘉宾出席大会开幕式并在大会主论坛(上午场)发表主题演讲《当智能体进入物理世界》。在印奇看来,"智能体"…

2026/7/20 0:13:05阅读更多 →
商汤大装置发布“技术-生态-商业”闭环布局,共启“国产AI基础设施规模化商用元年”

商汤大装置发布“技术-生态-商业”闭环布局,共启“国产AI基础设施规模化商用元年”

7月18日,在WAIC 2026商汤科技 “基座大模型架构创新与生态合作论坛”上,商汤科技联合创始人、大装置事业群总裁杨帆发表《智变共生——加速AI基础设施持续升级》主题演讲,系统呈现了商汤大装置国产AI基础设施“技术-生态-商业”闭环布局&…

2026/7/20 0:13:05阅读更多 →
2026郑州美发学校避坑指南:拆解5种教学方式,谁在“流水线”谁在“真传技”?

2026郑州美发学校避坑指南:拆解5种教学方式,谁在“流水线”谁在“真传技”?

2026年想在郑州学美发,很多零基础学员最先搜索的问题就是:郑州美发学校哪家好?这个问题没有一个只看学校名字就能得出的答案。因为不同学校的课程方向、学习周期、教学方式和适合人群并不一样。有的更适合零基础,有的偏向发型师进修,还有的只做某一项短期技术培训。对于完全没…

2026/7/20 0:11:05阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/20 0:50:54阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/20 0:50:54阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/20 0:50:54阅读更多 →
2026 WAIC:努比亚二代“豆包手机”NaviX Ultra亮相,智能体验全面升级!

2026 WAIC:努比亚二代“豆包手机”NaviX Ultra亮相,智能体验全面升级!

7月18日智东西消息,在2026 WAIC期间,努比亚联合字节豆包打造的二代“豆包手机”努比亚NaviX Ultra首次亮相,相比一代有诸多升级。智能体手机理念中兴通讯终端事业部总裁、努比亚总裁倪飞表示,智能体手机要从人操作手机变为手机帮人…

2026/7/20 0:01:04阅读更多 →
努比亚NaviX Ultra亮相WAIC,智能体手机能否让用户生活更简单?

努比亚NaviX Ultra亮相WAIC,智能体手机能否让用户生活更简单?

努比亚NaviX Ultra:外观与功能双升级在2026 WAIC期间,首次亮相的努比亚NaviX Ultra吸引了众多目光。它是努比亚联合字节豆包打造的二代“豆包手机”,与一代努比亚M153相比,外观设计变化较大。其机身背部搭载横向排布的大尺寸影像模…

2026/7/20 0:01:04阅读更多 →
C# 将逗号分割的字符串转换为long,并添加到List<long>

C# 将逗号分割的字符串转换为long,并添加到List<long>

目录 方法1:使用Split和Convert.ToInt64 方法2:使用LINQ的Select和ToList 方法3:使用TryParse进行异常安全转换(推荐) 如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天…

2026/7/20 0:01:04阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/19 22:50:49阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/19 14:50:26阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/19 18:50:36阅读更多 →