Arduino与Flash芯片

卫斯理
发布于 2021-1-22 10:35
浏览
0收藏

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与Flash芯片-鸿蒙开发者社区

Arduino与Flash芯片-鸿蒙开发者社区

与Arduino的连接

采用工作于3.3V的Pro Mini版本进行简单调试,接法如下。

Arduino与Flash芯片-鸿蒙开发者社区

其中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到本页的起始位置。

 

测试代码:

/*
    communication with W25Q80BV (1 MBYTE SPI FLASH) using Arduino Pro Mini 3.3V/8MHz
    Reference: http://www.instructables.com/id/How-to-Design-with-Discrete-SPI-Flash-Memory/?ALLSTEPS
*/

// the SPI bus uses pins 10 (SS), 11 (MOSI), 12 (MISO), and 13 (SCK)

#include <SPI.h>

#define READ_JEDEC_ID 0x9F
#define READ_STATUS_1 0x05
#define READ_DATA 0x03
#define WRITE_ENABLE 0x06
#define PAGE_PROGRAM 0x02
#define CHIP_ERASE 0xC7

byte pageBuffer[256];
char str[] = "An apple a day keeps the doctor away."; //short than 256

void setup()
{
    SPI.begin();
    SPI.setDataMode(SPI_MODE0);
    SPI.setBitOrder(MSBFIRST);
    Serial.begin(9600);

    ReadID();
    EraseChip();
    WritePage(0x1234, str, sizeof(str));
}

void loop()
{
    ReadPage(0x1234, pageBuffer, sizeof(str));

    for(int i = 0; i < sizeof(str); i++)
    {
        Serial.print(char(pageBuffer[i]));
    }
    Serial.println();

    delay(2000);
}

void CheckBusy()
{
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(READ_STATUS_1);
    while(SPI.transfer(0) & 0x01);
    digitalWrite(SS, HIGH);
}

void ReadID()
{
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(READ_JEDEC_ID);
    byte manuID = SPI.transfer(0);
    byte memoType = SPI.transfer(0);
    byte capa = SPI.transfer(0);
    digitalWrite(SS, HIGH);

    Serial.print("Manufacturer ID: "); Serial.println(manuID, HEX);
    Serial.print("Memory Type: "); Serial.println(memoType, HEX);
    Serial.print("Capacity : "); Serial.println(capa, HEX);

    CheckBusy();
}

void ReadPage(word pageNumber, byte pageBuffer[], int length)
{
    // pageNumber: 16-bit data
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(READ_DATA);
    SPI.transfer((pageNumber >> 8) & 0xFF);
    SPI.transfer(pageNumber & 0xFF);
    SPI.transfer(0);
    for(int i = 0; i < length; i++)
    {
        pageBuffer[i] = SPI.transfer(0);
    }
    digitalWrite(SS, HIGH);
    CheckBusy();
}

void WritePage(word pageNumber, char pageBuffer[], int length)
{
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(WRITE_ENABLE);
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(PAGE_PROGRAM);
    SPI.transfer((pageNumber >>  8) & 0xFF);
    SPI.transfer(pageNumber & 0xFF);
    SPI.transfer(0);
    for(int i = 0; i < length; i++)
    {
        SPI.transfer(byte(pageBuffer[i]));
    }
    digitalWrite(SS, HIGH);
    CheckBusy();
}

void EraseChip()
{
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(WRITE_ENABLE);
    digitalWrite(SS, HIGH);
    digitalWrite(SS, LOW);
    SPI.transfer(CHIP_ERASE);
    digitalWrite(SS, HIGH);
    CheckBusy();
}
  • 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.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.

 

读取芯片的ID信息,向W25Q80BV写入一段字符串,再将写入的信息反复读出:Arduino与Flash芯片-鸿蒙开发者社区

参考资料


W25Q80BV datasheet - Winbond
Arduino - SPI
Designing with Discrete SPI Flash Memory - Instructables
Flash芯片硬件特性

分类
已于2021-1-22 10:35:27修改
收藏
回复
举报


回复
    相关推荐