W25Q80BV是台湾华邦电子(Winbond)生产的8M-bit串行flash芯片。主要特性有:
- 工作电压:2.5 ~ 3.6 V
- 功耗:读写(active)时4mA,低功耗(power-down)时<1μA
- 容量:8M-bit/1M-byte,包含4096个页(每页大小256字节)
- 接口:Standard/Dual/Quad SPI,支持时钟频率最高104MHz
- 支持以4/32/64k-bytes为单位进行Sector/Block擦除
- 一次写入最多256字节
- 软件/硬件写保护功能
- 大于10万次擦除/编程寿命
- 大于20年的数据保存时间
- 封装:SOIC/USON/WSON/PDIP
管脚定义
与Arduino的连接
采用工作于3.3V的Pro Mini版本进行简单调试,接法如下。
其中HOLD脚须上拉接到3.3V,否则器件无法正常工作;WP脚可以浮空。
W25Q80BV Pro Mini (3.3V/8MHz)
VCC <------> 3.3V
GND <------> GND
/CS <------> SS (D10)
DI <------> MOSI (D11)
DO <------> MISO (D12)
CLK <------> SCK (D13)
功能调试
-
与I2C不同,利用SPI库操作时,读和写都用同一个函数SPI.transfer()实现。
-
读取时,可以任意地址、任意长度进行读取。
-
与EEPROM不同,SPI Flash写入前,需要对写入的存储空间进行擦除(Erase)操作,否则写入不成功。芯片支持Chip Erase(整片擦除)、Block Erase(32K bytes/64K bytes块擦除)和Sector Erase(4K bytes扇区擦除)。
-
当写操作对应的地址空间到达page的边界,再继续写入时目的地址会自动roll over到本页的起始位置。
测试代码
1 /*
2 communication with W25Q80BV (1 MBYTE SPI FLASH) using Arduino Pro Mini 3.3V/8MHz
3 Reference: http://www.instructables.com/id/How-to-Design-with-Discrete-SPI-Flash-Memory/?ALLSTEPS
4 */
5
6 // the SPI bus uses pins 10 (SS), 11 (MOSI), 12 (MISO), and 13 (SCK)
7
8 #include <SPI.h>
9
10 #define READ_JEDEC_ID 0x9F
11 #define READ_STATUS_1 0x05
12 #define READ_DATA 0x03
13 #define WRITE_ENABLE 0x06
14 #define PAGE_PROGRAM 0x02
15 #define CHIP_ERASE 0xC7
16
17 byte pageBuffer[256];
18 char str[] = "An apple a day keeps the doctor away."; //short than 256
19
20 void setup()
21 {
22 SPI.begin();
23 SPI.setDataMode(SPI_MODE0);
24 SPI.setBitOrder(MSBFIRST);
25 Serial.begin(9600);
26
27 ReadID();
28 EraseChip();
29 WritePage(0x1234, str, sizeof(str));
30 }
31
32 void loop()
33 {
34 ReadPage(0x1234, pageBuffer, sizeof(str));
35
36 for(int i = 0; i < sizeof(str); i++)
37 {
38 Serial.print(char(pageBuffer[i]));
39 }
40 Serial.println();
41
42 delay(2000);
43 }
44
45 void CheckBusy()
46 {
47 digitalWrite(SS, HIGH);
48 digitalWrite(SS, LOW);
49 SPI.transfer(READ_STATUS_1);
50 while(SPI.transfer(0) & 0x01);
51 digitalWrite(SS, HIGH);
52 }
53
54 void ReadID()
55 {
56 digitalWrite(SS, HIGH);
57 digitalWrite(SS, LOW);
58 SPI.transfer(READ_JEDEC_ID);
59 byte manuID = SPI.transfer(0);
60 byte memoType = SPI.transfer(0);
61 byte capa = SPI.transfer(0);
62 digitalWrite(SS, HIGH);
63
64 Serial.print("Manufacturer ID: "); Serial.println(manuID, HEX);
65 Serial.print("Memory Type: "); Serial.println(memoType, HEX);
66 Serial.print("Capacity : "); Serial.println(capa, HEX);
67
68 CheckBusy();
69 }
70
71 void ReadPage(word pageNumber, byte pageBuffer[], int length)
72 {
73 // pageNumber: 16-bit data
74 digitalWrite(SS, HIGH);
75 digitalWrite(SS, LOW);
76 SPI.transfer(READ_DATA);
77 SPI.transfer((pageNumber >> 8) & 0xFF);
78 SPI.transfer(pageNumber & 0xFF);
79 SPI.transfer(0);
80 for(int i = 0; i < length; i++)
81 {
82 pageBuffer[i] = SPI.transfer(0);
83 }
84 digitalWrite(SS, HIGH);
85 CheckBusy();
86 }
87
88 void WritePage(word pageNumber, char pageBuffer[], int length)
89 {
90 digitalWrite(SS, HIGH);
91 digitalWrite(SS, LOW);
92 SPI.transfer(WRITE_ENABLE);
93 digitalWrite(SS, HIGH);
94 digitalWrite(SS, LOW);
95 SPI.transfer(PAGE_PROGRAM);
96 SPI.transfer((pageNumber >> 8) & 0xFF);
97 SPI.transfer(pageNumber & 0xFF);
98 SPI.transfer(0);
99 for(int i = 0; i < length; i++)
100 {
101 SPI.transfer(byte(pageBuffer[i]));
102 }
103 digitalWrite(SS, HIGH);
104 CheckBusy();
105 }
106
107 void EraseChip()
108 {
109 digitalWrite(SS, HIGH);
110 digitalWrite(SS, LOW);
111 SPI.transfer(WRITE_ENABLE);
112 digitalWrite(SS, HIGH);
113 digitalWrite(SS, LOW);
114 SPI.transfer(CHIP_ERASE);
115 digitalWrite(SS, HIGH);
116 CheckBusy();
117 }
View Code
读取芯片的ID信息,向W25Q80BV写入一段字符串,再将写入的信息反复读出:
参考资料
W25Q80BV datasheet - Winbond
Arduino - SPI
Designing with Discrete SPI Flash Memory - Instructables
Flash芯片硬件特性
转载于:https://www.cnblogs.com/zlbg/p/4246721.html