MX25L8005 представляет собой последовательную флэш-память CMOS размером 8 388 608 бит, которая содержит адресное пространство от 0 до 1 048 576 байт. Управление памятью осуществляется при помощи шины SPI.
На платформе Arduino использую флэш-память можно использовать для хранения больших массивов данных которые периодически запрашиваются при работе контроллера, для сбора информации с различных датчиков с последующей сортировкой и выводом информации.
Подключение флэш-памяти к плате Arduino Nano (Uno), LGT8F328p:
Флэш-память содержит 256 секторов по 4 кБ или 16 блоков по 64 кБ. Перед записью данных в память необходимо ее стереть. Стирание памяти осуществляется по секторам или по блокам, запись и чтение данных производится побайтно.
Помимо стиранием памяти по секторам или по блокам возможна полное стирание памяти.
Перед стиранием памяти необходимо дать команду разрешения записи, а после стирания памяти дать команду запрета записи. Аналогично нужно поступать при записи или чтении памяти.
Разрешение записи
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(0x06); digitalWrite(SС, HIGH); SPI.endTransaction();
Запрет записи
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(0x04); digitalWrite(SС, HIGH); SPI.endTransaction();
Отправка команды стирания сектора
Отправляем команду 0х20 для стирания сектора и указываем номер сектора 1. При этом номер сектора содержит адресацию в 24 бита, а так как секторов всего 256 (0…255), то отправляем три байта адреса 0x00 0x00 0x01.
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(0x20); SPI.transfer(0x00); SPI.transfer(0x00); SPI.transfer(0x01); digitalWrite(SС, HIGH); SPI.endTransaction();
Отправка команды стирания блока
Отправляем команду 0х52 для стирания блока и указываем номер блока 1. При этом номер блока содержит адресацию в 24 бита, а так как блоков всего 16 (0…15), то отправляем три байта адреса 0x00 0x00 0x01.
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(52); SPI.transfer(0x00); SPI.transfer(0x00); SPI.transfer(0x01); digitalWrite(SС, HIGH); SPI.endTransaction();
Запись данных
Запись данных осуществляется побайтно, отправляем команду для записи 0x02, далее указываем начальный адрес ячейки памяти с которого будет осуществляться запись, для примера для записи возьмем ячейку под номером 16500 или 0x004074 в шеснадцатиричной системе. Адрес должен так же быть 24-х битным, поэтому отправляем три байта 0x00 0x40 0x74.
Далее отправляем три байта data_0… data_2. Соответственно запись будет осуществлена по адресам 16500…16502.
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(0x02); SPI.transfer(0x00); SPI.transfer(0x40); SPI.transfer(0x74); SPI.transfer(data_0); SPI.transfer(data_1); SPI.transfer(data_2); digitalWrite(SС, HIGH); SPI.endTransaction();
Чтение данных
Чтение данных осуществляется побайтно, отправляем команду для чтения 0x03, далее указываем начальный адрес ячейки памяти с которого будет осуществляться чтение, для примера для записи возьмем ячейку под номером 16500 или 0x004074 в шеснадцатиричной системе. Адрес должен так же быть 24-х битным, поэтому отправляем три байта 0x00 0x40 0x74.
Далее отправляем ноль и получаем значение байта data_0, снова отправляем ноль и получаем значение байта data_1 и тд. Соответственно чтение будет осуществлено по адресам 16500…16502.
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(0x03); SPI.transfer(0x00); SPI.transfer(0x40); SPI.transfer(0x74); byte data_0 = SPI.transfer(0); byte data_1 = SPI.transfer(0); byte data_2 = SPI.transfer(0); digitalWrite(SС, HIGH); SPI.endTransaction();
Чтение как и запись может осуществляться по одному байту, например прочтем ячейку памяти под номером 0x18.
SPI.beginTransaction(mySet); digitalWrite(SС, LOW); SPI.transfer(0x03); SPI.transfer(0x00); SPI.transfer(0x00); SPI.transfer(0x18); byte data = SPI.transfer(0); digitalWrite(SС, HIGH); SPI.endTransaction();
Ниже показан пример скетча в котором стирается сектор 0, далее записывается массив из шести чисел, а в цикле loop() записанные в память значения выводятся в монитор порта. Запись и чтение осуществляет начиная с адреса 400 и по одному байту:
#include <SPI.h> const int SSPin = 10; SPISettings mySet(500000, MSBFIRST, SPI_MODE0); byte arr[]={0x18, 0x22, 0xA0, 0xAF, 0x20, 0xA8}; void setup() { Serial.begin(9600); pinMode(SSPin, OUTPUT); SPI.begin(); sector_clean(0);delay(1000);// 0...255 sectors (1sector=4k_byte) // block_clean(0);delay(2000);// 0...15 block (1block=64k_byte) // chip_clean();delay(20000); for(int i=0;i<6;i++){ write_flash(i+400,arr[i]); } } void loop() { for(int i=0;i<6;i++){ Serial.print(read_flash(i+400),HEX);Serial.print(" "); } Serial.println(); delay(1000); } byte read_flash(long addr){ byte addr_2 = (addr >> 16) & 0xFF; byte addr_1 = (addr >> 8) & 0x00FF; byte addr_0 = addr & 0x0000FF; SPI.beginTransaction(mySet); digitalWrite(SSPin, LOW); SPI.transfer(0x03); SPI.transfer(addr_2); SPI.transfer(addr_1); SPI.transfer(addr_0); byte data = SPI.transfer(0); digitalWrite(SSPin, HIGH); SPI.endTransaction(); return data; } void write_flash(long addr, byte data_byte){ spi_rw(0x06); byte addr_2 = (addr >> 16) & 0xFF; byte addr_1 = (addr >> 8) & 0x00FF; byte addr_0 = addr & 0x0000FF; SPI.beginTransaction(mySet); digitalWrite(SSPin, LOW); SPI.transfer(0x02); SPI.transfer(addr_2); SPI.transfer(addr_1); SPI.transfer(addr_0); SPI.transfer(data_byte); digitalWrite(SSPin, HIGH); SPI.endTransaction(); spi_rw(0x04); } void sector_clean(byte addr){ spi_rw(0x06); spi_command(0x20,0); spi_rw(0x04); } void block_clean(byte addr){ spi_rw(0x06); spi_command(0x52,0); spi_rw(0x04); } void chip_clean(){ spi_rw(0x06); spi_rw(0x60); spi_rw(0x04); } //////////////////////////////////////////////////////////////////// void spi_rw(byte data_rw){ SPI.beginTransaction(mySet); digitalWrite(SSPin, LOW); SPI.transfer(data_rw); digitalWrite(SSPin, HIGH); SPI.endTransaction(); } void spi_command(byte data_command,byte addr){ SPI.beginTransaction(mySet); digitalWrite(SSPin, LOW); SPI.transfer(data_command); SPI.transfer(0); SPI.transfer(0); SPI.transfer(addr); digitalWrite(SSPin, HIGH); SPI.endTransaction(); }
http://rcl-radio.ru/wp-content/uploads/2023/04/MX25L8005, 3V, 8Mb.pdf