Использование AT26df161 EEPROM SPI помогите разобраться (Разобрался)

Тема в разделе "Arduino & Shields", создана пользователем SNAK84, 5 июл 2015.

  1. SNAK84

    SNAK84 Нерд

    Подключил и написал небольшую библиотеку для работы с памятью.


    -----------------------------------------------------------------
    Пытаюсь подключить EEPROM память по SPI к Arduino но ничего не получатся

    Подключал по следующей схеме:
    [​IMG]

    Как подключать и обращаться брал отсюда :https://www.arduino.cc/en/Tutorial/SPIEEPROM

    Код использовал следующий:
    Код (Text):
    #define DATAOUT 11//MOSI
    #define DATAIN  12//MISO
    #define SPICLOCK  13//sck
    #define SLAVESELECT 10//ss

    //opcodes
    #define WREN  6
    #define WRDI  4
    #define RDSR  5
    #define WRSR  1
    #define READ  3
    #define WRITE 2

    byte eeprom_output_data;
    byte eeprom_input_data=0;
    byte clr;
    int address=0;
    //data buffer
    char buffer [128];

    void fill_buffer()
    {
      for (int I=0;I<128;I++)
      {
        buffer[I]=I;
      }
    }

    char spi_transfer(volatile char data)
    {
      SPDR = data;                    // Start the transmission
      while (!(SPSR & (1<<SPIF)))    // Wait the end of the transmission
      {
      };
      return SPDR;                    // return the received byte
    }

    void setup()
    {
      Serial.begin(9600);

      pinMode(DATAOUT, OUTPUT);
      pinMode(DATAIN, INPUT);
      pinMode(SPICLOCK,OUTPUT);
      pinMode(SLAVESELECT,OUTPUT);
      digitalWrite(SLAVESELECT,HIGH); //disable device
      // SPCR = 01010000
      //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
      //sample on leading edge of clk,system clock/4 rate (fastest)
      SPCR = (1<<SPE)|(1<<MSTR);
      clr=SPSR;
      clr=SPDR;
      delay(10);
      //fill buffer with data
      fill_buffer();
      //fill eeprom w/ buffer
      digitalWrite(SLAVESELECT,LOW);
      spi_transfer(WREN); //write enable
      digitalWrite(SLAVESELECT,HIGH);
      delay(10);
      digitalWrite(SLAVESELECT,LOW);
      spi_transfer(WRITE); //write instruction
      address=0;
      spi_transfer((char)(address>>8));  //send MSByte address first
      spi_transfer((char)(address));      //send LSByte address
      //write 128 bytes
      for (int I=0;I<128;I++)
      {
        spi_transfer(buffer[I]); //write data byte
      }
      digitalWrite(SLAVESELECT,HIGH); //release chip
      //wait for eeprom to finish writing
      delay(3000);
      Serial.print('h',BYTE);
      Serial.print('i',BYTE);
      Serial.print('\n',BYTE);//debug
      delay(1000);
    }

    byte read_eeprom(int EEPROM_address)
    {
      //READ EEPROM
      int data;
      digitalWrite(SLAVESELECT,LOW);
      spi_transfer(READ); //transmit read opcode
      spi_transfer((char)(EEPROM_address>>8));  //send MSByte address first
      spi_transfer((char)(EEPROM_address));      //send LSByte address
      data = spi_transfer(0xFF); //get data byte
      digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
      return data;
    }

    void loop()
    {
      eeprom_output_data = read_eeprom(address);
      Serial.print(eeprom_output_data,DEC);
      Serial.print('\n',BYTE);
      address++;
      if (address == 128)
        address = 0;
      delay(500); //pause for readability
    }
    В ответ получаю одни нули, подскажите как правильно работать с памятью.
     

    Вложения:

    • DataFlash.zip
      Размер файла:
      3,6 КБ
      Просмотров:
      267
    Последнее редактирование: 10 июл 2015
  2. DrProg

    DrProg Вечный нерд

    Первое что пришло в голову: 3,3V достаточно ли? В первоисточнике указано 5V.
     
  3. SNAK84

    SNAK84 Нерд

    Пробывал давать 5в, никакой разници
     
  4. 9xA59kK

    9xA59kK Гик

    Поторопился пробовать не изучив даташит- у них питание существенно отличается
    AT26DF161
    Single 2.7V - 3.6V Supply
    а вот тот, что в примере по твоей ссылки
    AT25HP256.
    – 2.7 (VCC = 2.7V to 5.5V)
    – 1.8 (VCC = 1.8V to 5.5V)
    Возможны ты спалил память подав на нее 5v, у нее максимум 3.6v .
     
  5. SNAK84

    SNAK84 Нерд

    Изменив программу на работу с хардварным SPI стал получать стабильные данные с памяти.
    Но не могу в нее ничего записать и не пойму как правильно посылать адрес чтения/записи.

    Код (Text):
    #include <SPI.h>

    #define DATAOUT 11//MOSI
    #define DATAIN  12//MISO
    #define SPICLOCK  13//sck
    #define SLAVESELECT 10//ss

    //opcodes
    #define WREN  6
    #define WRDI  4
    #define RDSR  5
    #define WRSR  1
    #define READ  3
    #define WRITE 2

    byte eeprom_output_data;
    byte eeprom_input_data = 0;
    byte clr;
    int address = 0;
    //data buffer
    char buffer [128];

    void fill_buffer()
    {
      for (int I = 0; I < 128; I++)
      {
        buffer[I] = I;
      }
    }

    void setup()
    {
      Serial.begin(9600);
      SPI.begin();

      pinMode(SLAVESELECT, OUTPUT);
      digitalWrite(SLAVESELECT, HIGH); //disable device


      delay(10);
      //fill buffer with data
      fill_buffer();
      //fill eeprom w/ buffer
      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(WREN); //write enable
      digitalWrite(SLAVESELECT, HIGH);
      delay(10);
      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(WRITE); //write instruction
      address = 0x008000;

      SPI.transfer(0);
      SPI.transfer((address >> 8));
      SPI.transfer((address));
      //write 128 bytes
      for (int I = 0; I < 128; I++)
      {
        SPI.transfer(I); //write data byte
      }
      digitalWrite(SLAVESELECT, HIGH); //release chip
      //wait for eeprom to finish writing
      delay(3000);
      Serial.println("hi");
      delay(1000);

      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(READ); //transmit read opcode

      SPI.transfer(0);
      SPI.transfer((address >> 8));
      SPI.transfer((address));
      for (int I = 0; I < 128; I++)
      {
        Serial.print(SPI.transfer(I)); //write data byte
        Serial.print(", ");
      }
      Serial.println("");
      digitalWrite(SLAVESELECT, HIGH); //release chip, signal end transfer
    }
    Из datasheet понял что адрес должен состоять из 3-х байт, но в какой последовательности отправлять биты я не понял.
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    В даташите должны быть диаграммы сигналов для всех операций, найдите их и все станет понятно.
     
  7. SNAK84

    SNAK84 Нерд

    Я в них не смог разобраться(((
     
  8. SNAK84

    SNAK84 Нерд

    С адресом вроде разобрался, но запись на флеш не производится, в чем может быть причина?
    Код (Text):
    #include <SPI.h>

    //opcodes

    #define READ  3
    #define WRITE 2

    long int address = 0x1024;
    //data buffer
    char buffer [128];

    void fill_buffer()
    {
      for (int I = 0; I < 128; I++) buffer[I] = I;
    }

    void setup()
    {
      Serial.begin(9600);
      SPI.begin();
      Serial.println("-=Start=-");
      pinMode(SLAVESELECT, OUTPUT);

      //fill buffer with data
      fill_buffer();
      //fill eeprom w/ buffer
      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(WREN); //write enable
      digitalWrite(SLAVESELECT, HIGH);
      delay(10);

      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(0x05);
      Serial.println(SPI.transfer(0), HEX);
      digitalWrite(SLAVESELECT, HIGH); //disable device
      delay(10);
      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(WRITE);

      SPI.transfer((address >> 16));
      SPI.transfer(((address & 0xFFFF) >> 8));
      SPI.transfer((address & 0xFF));

      //write 128 bytes
      Serial.println("Write Start");
      for (int I = 0; I < 16; I++)
      {
        Serial.print(SPI.transfer(128),HEX);
      }
      Serial.println("");
      Serial.println("Write End");
      digitalWrite(SLAVESELECT, HIGH);
      delay(3000);
      Serial.println("hi");
      delay(1000);

      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(READ);

      SPI.transfer((address >> 16));
      SPI.transfer(((address & 0xFFFF) >> 8));
      SPI.transfer((address & 0xFF));

      for (int I = 0; I < 16; I++)
      {
        int data = SPI.transfer(I);
        if (data < 16) Serial.print("0");
        Serial.print(data, HEX); //write data byte
        Serial.print(", ");
      }
      Serial.println("");
      digitalWrite(SLAVESELECT, HIGH);

      delay(1000);

      digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(READ); //transmit read opcode

      address += 8;

      SPI.transfer((address >> 16));
      SPI.transfer(((address & 0xFFFF) >> 8));
      SPI.transfer((address & 0xFF));

      for (int I = 0; I < 16; I++)
      {
        int data = SPI.transfer(I);
        if (data < 16) Serial.print("0");
        Serial.print(data, HEX); //write data byte
        Serial.print(", ");
      }
      Serial.println("");
      digitalWrite(SLAVESELECT, HIGH);
    }

    void loop()
    {


    }
     
     
  9. Megakoteyka

    Megakoteyka Оракул Модератор

    Младшим разрядом вперед.
     
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    Сперва нужно стереть блок, только потом можно записывать.
     
    SNAK84 нравится это.
  11. SNAK84

    SNAK84 Нерд

    Выполняю
    Код (Text):
    digitalWrite(SLAVESELECT, LOW);
      SPI.transfer(0x20);

      SPI.transfer((address >> 16));
      SPI.transfer(((address & 0xFFFF) >> 8));
      SPI.transfer((address & 0xFF));

      digitalWrite(SLAVESELECT, HIGH);
    Считанные данные после этого не меняются(
     
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Стирание блока занимает время tBLKE, указанное в таблице 12.5 даташита.
     
  13. SNAK84

    SNAK84 Нерд

    Спасибо, пауза в 1 сек и Unprotect Sector помогло))
    Получается надо один раз стереть блок памяти и после в него можно записывать))
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    Да, все флэшки так работают, насколько я знаю.
     
  15. SNAK84

    SNAK84 Нерд

    Получается что бы изменить 16 байт нужно перезаписать 4096 байт.
    Неудобно(
     
  16. Megakoteyka

    Megakoteyka Оракул Модератор

    Есть другие типы памяти, у которых нет такого недостатка. Но у них объем маленький по сравнению с flash.
     
  17. SNAK84

    SNAK84 Нерд

    Ну эта мне досталось бесплатно))
    Хочу на нею записать wav файлы и сделать говорящие часы.
     
  18. Megakoteyka

    Megakoteyka Оракул Модератор

    Ну если один раз записать и потом только читать, то вполне сгодится.
     
  19. SNAK84

    SNAK84 Нерд

    Создал небольшую библиотеку для работы с этой памятью, может кому пригодится
    Пример:
    Код (Text):
    #include <SPI.h>
    #include "DataFlash.h"

    DataFlash Flash;

    byte buffer[256];

    uint8_t Length = 64;
    uint32_t address = 0x000000; // максимум 0x1fffff

    void setup() {

      Serial.begin(9600);

      Flash.begin(10);
      uint8_t status = Flash.status();
      Serial.println(status, HEX);

      for (uint16_t n = 0; n < 256; n++) {
        buffer[n] = n;
      }

      Flash.PageErase(address);
      Flash.WriteArray(address, buffer, 32);

    }

    void loop() {
      if (Length > 8) {
        Serial.print("Length: ");
        Serial.println(Length);

        Flash.ReadArray(address, buffer, Length);
        for (uint16_t i = 0; i < Length; i++) {
          uint8_t data = buffer[i];
          if (data < 16) Serial.print("0");
          Serial.print(data, HEX); //write data byte
          Serial.print(", ");
        }
        Serial.println("");
        Length = Length / 2;
      }

    }
    Результат работы программы:
    Код (Text):
    14
    Length: 64
    00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF,
    Length: 32
    00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F,
    Length: 16
    00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F,
     
     

    Вложения:

    • DataFlash.zip
      Размер файла:
      3,6 КБ
      Просмотров:
      337
    Megakoteyka нравится это.