STM32教程 使用硬件SPI和模拟SPI驱动W25Q64芯片

STM32教程:使用硬件SPI和模拟SPI驱动W25Q64芯片

摘要

本教程详细介绍了如何在STM32微控制器上使用硬件SPI和模拟SPI来驱动W25Q64 Flash存储器。W25Q64是一款8Mbit的串行Flash存储器,适用于存储程序数据和用户数据。本教程将从SPI基本原理讲起,逐步介绍W25Q64特性、硬件连接、SPI初始化、读写操作,以及完整的示例代码。

1. SPI总线原理

SPI是一种高速、全双工、同步的通信协议,通常包含以下信号线:

  • MOSI:主设备数据输出,从设备数据输入。
  • MISO:主设备数据输入,从设备数据输出。
  • SCK:时钟信号,由主设备控制。
  • CS:片选信号,用于选择从设备。

2. W25Q64芯片特性

W25Q64是华邦电子生产的串行Flash存储器,主要特性如下:

  • 容量:8Mbit(1M字节)。
  • 组织:分为128个扇区,每个扇区16个页,每页256字节。
  • 擦除时间:毫秒级别。
  • 擦写周期:100万次。

3. 硬件连接

将W25Q64与STM32连接,需要以下引脚连接:

  • CS接STM32 GPIO(如PA4)。
  • SCK接STM32 SPI时钟引脚(如PA5)。
  • MOSI接STM32 SPI数据发送引脚(如PA7)。
  • MISO接STM32 SPI数据接收引脚(如PA6)。
  • VCC接3.3V。
  • GND接地。

4. SPI初始化

4.1 硬件SPI初始化

硬件SPI初始化代码示例:

void SPI_Hardware_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);
}
4.2 模拟SPI初始化

模拟SPI通过直接操作GPIO实现SPI功能:

void SPI_Software_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOA, &GPIO_InitStructure);
}

5. W25Q64操作

5.1 W25Q64初始化
void W25Q64_Init(void) {SPI_Hardware_Init(); // 硬件SPI初始化SPI_Software_Init(); // 模拟SPI初始化
}
5.2 读取W25Q64 ID
uint16_t W25Q64_ReadID(void) {uint16_t id = 0;SPI_CS_Low(); // 片选SPI_SendByte(0x90); // 发送读ID指令id = SPI_ReceiveByte() << 8; // 读取IDid |= SPI_ReceiveByte();SPI_CS_High(); // 取消片选return id;
}
5.3 写入W25Q64
void W25Q64_WriteByte(uint32_t addr, uint8_t data) {SPI_CS_Low(); // 片选SPI_SendByte(0x02); // 发送页编程指令SPI_SendByte(addr >> 16); // 发送地址SPI_SendByte(addr >> 8);SPI_SendByte(addr);SPI_SendByte(data); // 发送数据SPI_CS_High(); // 取消片选// 等待写入完成...
}
5.4 从W25Q64读取数据
uint8_t W25Q64_ReadByte(uint32_t addr) {uint8_t data;SPI_CS_Low(); // 片选SPI_SendByte(0x03); // 发送读数据指令SPI_SendByte(addr >> 16); // 发送地址SPI_SendByte(addr >> 8);SPI_SendByte(addr);data = SPI_ReceiveByte(); // 读取数据SPI_CS_High(); // 取消片选return data;
}

6. 完整示例代码

以下是使用硬件SPI和模拟SPI驱动W25Q64芯片的完整示例代码。

int main(void) {// 系统初始化SystemInit();// 初始化W25Q64W25Q64_Init();// 读取W25Q64 IDuint16_t id = W25Q64_ReadID();printf("W25Q64 ID: 0x%X\r\n", id);// 使用硬件SPI写入数据W25Q64_WriteByte(0x000000, 0xAA);// 使用模拟SPI读取数据uint8_t data = W25Q64_ReadByte(0x000000);printf("Read data: 0x%X\r\n", data);while(1) {// 其他应用代码}
}

7. 结论

本教程提供了使用STM32硬件SPI和模拟SPI驱动W25Q64芯片的详细步骤和示例代码。通过本教程,STM32初学者可以快速掌握SPI通信和W25Q64 Flash存储器的使用。在实际应用中,开发者可能需要根据具体的硬件配置和需求进行适当的调整和优化。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/35120.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第 10 课:PPML入门/基于SPU机器学习建模实践

本讲主要内容是PPML入门&#xff0c;即基于SPU进行隐私保护的机器学习的建模实践。通过本次学习&#xff0c;可以了解隐私保护机器学习以及隐语SPU的架构&#xff0c;通过实战可以了解如何基于隐语进行隐私保护的NN模型建模。 一、隐私保护机器学习背景 机器学习中的数据隐私问…

RK3568平台开发系列讲解(I2C篇)利用逻辑分析仪进行I2C总线的全面分析

🚀返回专栏总目录 文章目录 1. 基础协议1.1. 协议简介1.2. 物理信号1.3. 总线连接沉淀、分享、成长,让自己和他人都能有所收获!😄 1. 基础协议 1.1. 协议简介 IIC-BUS(Inter-IntegratedCircuit Bus)最早是由PHilip半导体(现在被NXP收购)于1982年开发。 主要是用来方…

将深度相机的实时三维坐标数据保存为excel文档(Python+Pyrealsense2+YOLOv8)

一、如何将数据保存为excel文档 1.excel文件库与相关使用 &#xff08;1&#xff09;导入相应的excel文件库&#xff0c;导入前先要进行pip安装&#xff0c;pip install xlwt import xlwt # 导入用于创建和写入Excel文件的库 (2) 建立一个excel文档&#xff0c;并在第0行写…

RabbitMQ中Direct交换机的用法

前言&#xff1a;比如我们的支付完成之后需要进行修改支付状态还要完成短信通知用户需要同时并发两条指令我们可以使用direct交换机进行指定两个不同的业务去完成这两件事 比如我们现在有direct.queue1/direct.queue2两个消息队列&#xff0c;一个direct交换机 我们创建完成两…

鸿蒙开发之--生命周期

开发官网 开发-HarmonyOS开发者-华为开发者联盟 UIAbility生命周期 1、首先执行onCreate(),用于页面初始化和设置页面逻辑 2、执行onWindowStageCreate()创建一个窗口&#xff0c;在这里可以使windowStage.loadContent(url&#xff0c;&#xff08;&#xff09;>{})打开一…

“拿来主义”学习无限滚动动画(附源码)

欢迎关注&#xff1a;xssy5431 小拾岁月 参考链接&#xff1a;https://mp.weixin.qq.com/s/xVTCwR1ZSn5goWmc2yimVA 动画效果 需求分析 需求中涉及无线滚动&#xff0c;说明需要使用 animation 动画。另外&#xff0c;为了方便用户点击操作&#xff0c;需要给滚动对象添加鼠标…

感谢我的辅导员—敬爱的罗老师

前言&#xff1a;快毕业了&#xff0c;想在毕业季感谢给予我帮助的老师&#xff0c;我的辅导员-罗老师是我最想感谢的大学老师。我不知道应该以什么样的方式去表达罗老师对我大学阶段的帮助&#xff0c;如果是直接发邮件&#xff0c;微信信息留言&#xff0c;可能在之后我和老师…

MySQL索引优化解决方案--索引优化(4)

排序优化 尽量避免使用Using FileSort方式排序。order by语句使用索引最左前列或使用where子句与order by子句条件组合满足索引最左前列。where子句中如果出现索引范围查询会导致order by索引失效。 优化案例 联表查询优化 分组查询优化 慢查询日志

架构是怎样练成的-楼宇监控系统案例

目录 概要 项目背景 原系统设计方案 改进后的设计方案 小结 概要 绝大多数人掌握的架构都是直接学习&#xff0c;慢慢地才能体会到一个架构的好处。架构是一种抽象&#xff0c;是为了复用目的而对代码做的抽象。通过一个项目的改造&#xff0c;理解架构是如何产生的&…

Kubernetes Prometheus 系例 | kubernetes 部署 Kafka exporter监控Kafka集群

prometheus 监控 kafka 常见的有两种开源方案&#xff1b; 部署 exporter 或 jmx 配置监控。 项目地址&#xff1a; kafka_exporter&#xff1a;https://github.com/danielqsj/kafka_exporter jmx_exporter&#xff1a;https://github.com/prometheus/jmx_exporter 本文采用kaf…

Python面试宝典:阿里python内部面试真题第1-5题以及详细答案解析(1000加面试笔试题助你轻松捕获大厂Offer)

Python面试宝典:阿里python内部面试真题第1-5题以及详细答案解析(1000加面试笔试题助你轻松捕获大厂Offer) 题目1: 请解释Python下多线程的限制以及在多进程中传递参数的方式。面试题考点答案或代码答案或代码解析题目2: 请解释Python多线程与多进程的区别。面试题考点答案或…

c++中popen执行linux命令失败,如何打印出错原因?

在C中&#xff0c;如果你使用popen函数执行Linux命令失败&#xff0c;并且想要打印出失败的原因&#xff0c;你可以通过检查popen的返回值&#xff08;一个FILE*指针&#xff09;来实现。如果popen返回NULL&#xff0c;那么你可以使用perror函数或strerror函数来获取并打印出具…

【日常记录】【JS】优雅检测用户是否在指定元素的外部点击

文章目录 1、界面基本布局2、代码实现3、参考链接 1、界面基本布局 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

【华为OD机试B卷】阿里巴巴找黄金宝箱(II)(C++/Java/Python)

题目 题目描述 一贫如洗的樵夫阿里巴巴去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0-N的箱子,每个箱子上面贴有箱子中藏有金币的数量。 从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小…

搜索python包的说明

当我发现bug时&#xff0c;就怀疑是sns包的版本问题了&#xff08;原代码是原作者以前成功运行的代码&#xff09;&#xff0c;于是直接到网上搜&#xff0c;找到对应的说明文档 根据该示例代码进行改写&#xff1a; 达成目的。

【漏洞复现】用友 UFIDA saveDoc.ajax 任意文件上传漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

ONLYOFFICE 8.1版本桌面编辑器测评

https://www.onlyoffice.com/zh/ 随着工作方式的不断演变&#xff0c;文档编辑软件成为了我们日常工作中不可或缺的一部分。而ONLYOFFICE作为一款开源且功能丰富的办公套件&#xff0c;其最新推出的8.1版本在原有基础上进行了大量的优化与更新&#xff0c;旨在提供更流畅、更安…

后端返回base64文件流下载

后端返回base64文件流: 前端处理&#xff1a; downloadTemplate () {this.$API.downloadTemplate().then(({ data }) > {const binaryString atob(data) // 解码base64字符串const byteArray new Uint8Array(binaryString.length) // 创建一个Uint8Arrayfor (let i 0; i…

2.优化算法之滑动窗口1

1.长度最小的子数组 . - 力扣&#xff08;LeetCode&#xff09; &#xff08;1&#xff09;题目描述 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;…

代码随想录day15

第六章 二叉树****part03 迭代法&#xff0c;大家可以直接过&#xff0c;二刷有精力的时候 再去掌握迭代法。 110.平衡二叉树 &#xff08;优先掌握递归&#xff09; 再一次涉及到&#xff0c;什么是高度&#xff0c;什么是深度&#xff0c;可以巩固一下。 题目链接/文章讲…