Arduino SPI + SPI Flash芯片W25Q80BV

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)

功能调试

  1. 与I2C不同,利用SPI库操作时,读和写都用同一个函数SPI.transfer()实现。

  2. 读取时,可以任意地址、任意长度进行读取。

  3. 与EEPROM不同,SPI Flash写入前,需要对写入的存储空间进行擦除(Erase)操作,否则写入不成功。芯片支持Chip Erase(整片擦除)、Block Erase(32K bytes/64K bytes块擦除)和Sector Erase(4K bytes扇区擦除)。

  4. 当写操作对应的地址空间到达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

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. W25Q80 (8M-bit)、W25Q16 (16M-bit)和W25Q32 (32M-bit)串行闪存为空间、引脚和电源有限的系统提供了存储解决方案。25Q系列提供的灵活性和性能远远超过普通的串行闪存设备。他们是理想的代码隐藏到RAM,执行代码直接从双/四SPI (XIP)和存储声音,文本和数据。设备运行在单一2.7V至3.6V的电源上,电流消耗低至5mA有源,断电1a。所有的设备都提供节省空间的包装。W25Q80/16/32数组被组织成4,096/8,192/16,384个可编程页,每个页有256个字节。多达256字节可以被编程一次使用页程序指令。页面可以按16组(扇区擦除)、128组(32KB块擦除)、256组(64KB块擦除)或整个芯片(芯片擦除)擦除。W25Q80/16/32分别有256/512/1024个可擦除扇区和16/32/64个可擦除块。小的4KB扇区为需要数据和参数存储的应用程序提供了更大的灵活性。(见图2)。W25Q80/16/32支持标准串行外围接口(SPI),和高性能双/四输出以及双/四I/O SPI使用SPI引脚:串行时钟,芯片选择,串行数据I/O0 (DI), I/O1 (DO), I/O2 (/WP),和I/O3 (/HOLD)。SPI时钟频率高达80MHz的支持允许等效时钟率160MHz的双输出和320MHz的四次输出时,使用快速读双/四次输出指令。这些传输速率可与8位和16位并行闪存存储器相媲美。一个保持针,写保护针和可编程写保护,顶部或底部阵列控制,提供进一步的控制灵活性。此外,该设备支持JEDEC标准制造商和设备识别64位唯一序列号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值