【雕爷学编程】Arduino动手做(50)---W25Q64存储模块

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐一做做实验,不管能否成功,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。 

【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)

实验五十:W25Q64 64Mbit FLASH外扩存储模块 (DataFlash SPI接口 )

 

W25X64 
该系列是华邦公司推出的大容量SPI  FLASH 产品,W25X64 的容量为 64Mbit(8M),该系列还有 W25Q80/16/32 等W25X16、W25X32、W25X64分别有8192、16384、32768个可编程页,每页256字节,用扇区擦除指令每次可以擦除16页,用块擦除指令每次可以擦除256页,用整片擦除指令既可以擦除整个芯片,W25X16、W25X32、W25X64分别有512、1024、2048个可擦除扇区,或者32、64、128个可擦除的块。W25Q64 的擦写周期多达 10W 次,具有 20 年的数据保存期限,支持电压为 2.7~3.6V,W25Q64 支持标准的 SPI,还支持双输出/四输出的 SPI,最大 SPI 时钟可以到 80Mhz(双输出时相当于 160Mhz,四输出时相当于 320M)。

SPI总线
SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。上升沿发送、下降沿接收、高位先发送。上升沿到来的时候,sdo上的电平将被发送到从设备的寄存器中。下降沿到来的时候,sdi上的电平将被接收到主设备的寄存器中。

SPI总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。

SPI 数据速率一般在1到70MHz的范围内,字长为从8位及12位到这两个值的倍数。数据传输一般由数据交换构成。在主控制器向从设备发送数据时,从设备也向主控制器发送数据。因此主控制器的内部移位寄存器和从设备都采用环形设置。在数据交换之前,主控制器和从设备会将存储器数据加载至它们的内部移位寄存器。收到时钟信号后,主控制器先通过MOSI线路时钟输出其移位寄存器的MSB。同时从设备会读取位于SIMO的主控器第一位元,将其存储在存储器中,然后通过SOMI时钟输出其MSB。主控制器可读取位于MISO的从设备第一位元,并将其存储在存储器中,以便后续处理。整个过程将一直持续到所有位元完成交换,而主控器则可让时钟空闲并通过/SS 禁用从设备。

在 SPI 中,主控制器可与单个或多个从设备通信。如果是一个单从设备,从设备选择信号可连接至从设备的本地接地电位,实现永久接入。对使用多个从设备的应用,可使用两种配置:独立从设备与菊花链从设备。要与从设备单独通信,主控制器必须提供多重从设备选择信号。该配置通常用于必须单独访问多个模数转换器 (ADC) 及数模转换器 (DAC) 的数据采集系统中。菊花链从设备只需要主控制器提供一个从设备选择信号,因为这种配置要求所有从设备同时启用,以确保数据不间断地流经该链路中的所有移位寄存器。典型应用是工业 I/O 模块中的级联多通道输入串行器与输出驱动器。注意,菊花链连接不一定适用于所有的SPI设备,特别是要求多字节传输的(比如存储器芯片)设备。另外,要对外设芯片的数据表进行仔细分析,确定能对它做什么而不能做什么。如果芯片的数据表中没有明确提到菊花链连接,那么该芯片不支持这种连接的几率为50%。

W25Q64FWSSIG参数
功能数量        1 端子数量        8 
最大工作温度        85 Cel 
最小工作温度        -40 Cel
最大供电/工作电压        1.95 V 
最小供电/工作电压        1.65 V 
额定供电电压        1.8 V
最大时钟频率        104 MHz 
加工封装描述        0.208 INCH, GREEN, SOIC-8 状态        ACTIVE 工艺        CMOS 
包装形状 SQUARE
包装尺寸        SMALL OUTLINE 
表面贴装        Yes 
端子形式        GULL WING 
端子间距        1.27 mm 
端子位置        DUAL 
包装材料 PLASTIC/EPOXY 
温度等级        INDUSTRIAL 
内存宽度        1 组织        64M X 1 
存储密度        6.41E7 deg 
操作模式        SYNCHRONOUS 
位数 6.41E7 words 
位数        64M 
内存IC类型        FLASH 1.8V PROM 
串行并行        SERIAL

W25Q64引脚

CS:CS为片选管脚,低电平有效。上电之后,在执行一条新的指令之前,必须让/CS管脚先有一个下降沿。 

DO(MISO):DO为串行数据输出引脚,在CLK(串行时钟)管脚的下降沿输出数据。

WP:WP为写保护管脚,有效电平为低电平。高电平可读可写,低电平仅仅可读。

DI(MOSI):DI为串行数据输入引脚,数据、地址和命令从DI引脚输入到芯片内部,在CLK(串行时钟)管脚的上升沿捕获捕获数据。

CLK(SLCK):CLK为串行时钟引脚。SPI时钟引脚,为输入输出提供时钟脉冲。

HOLD:HOLD为保持管脚,低电平有效。当CS为低电平,并且把HOLD拉低时,数据输出管脚将保持高阻态,并且会忽略数据输入管脚和时钟管脚上的信号。把HOLD管脚拉高,器件恢复正常工作。

VCC:电源2.7V~3.6V。

GND:地。

 

W25Q64内部框架图

W25Q64操作原理

通过SPI接口,用标准的SPI协议发送相应指令给flash,然后flash根据命令进行各种相关操作。

 

W25Q64常用操作命令

模块电原理图

模块接口定义
CS:为片选信号脚---D10
DI(MOSI):为串行数据输入引脚----D11
DO(MISO):为串行数据输出引脚---D12
CLK(SLCK):SPI总线---D13
VCC:  电源3.3V
GND:接地

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
 
【Arduino】168种传感器模块系列实验(50)
 
实验五十:W25Q64 64Mbit FLASH外扩存储模块 (SPI接口 )
 
Arduino 的 uno 引脚
 
CS----------10
 
MOSI(DI)---11
 
MISO(DO)---12
 
CLK---------13
 
VCC 3.3V
 
*/
 
 
 
#include <SerialFlash.h>
 
#include <SPI.h>
 
// 文件大小
 
#define FSIZE 256
 
// 文件名
 
const char *filename = "Eagler8.txt";
 
// 文件内容
 
const char *contents = "The groundbreaking Intel Curie module expands the possibilities of what tech can do.";
 
// 片选引脚
 
const int FlashChipSelect = 10;
 
void setup() {
 
  Serial.begin(9600);
 
  while (!Serial) ;
 
  delay(500);
 
  // 初始化SPI Flash芯片
 
  SerialFlash.begin(FlashChipSelect);
 
  // 如果文件已存在,则输出提示
 
  // 如果文件不存在,则创建文件并写入
 
  if(SerialFlash.exists(filename)) {
 
    Serial.println("File " + String(filename) + " already exists");
 
  }
 
  else {
 
    Serial.println("Creating file " + String(filename));
 
    SerialFlash.create(filename, FSIZE);
 
    // 新建SerialFlashFile对象用于文件操作
 
    SerialFlashFile file;
 
    file = SerialFlash.open(filename);
 
    file.write(contents, strlen(contents) + 1);
 
    Serial.println("String \"" + String(contents) + "\" written to file " + String(filename));
 
  }
 
}
 
void loop() {
 
}

  

posted @   行者花雕  阅读(2396)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示