Не получается читать из / писать в EEPROM

В настоящее время я пытаюсь писать и читать с 25LC256-E EEPROM с помощью Arduino Uno через SPI. Я сделал программу, которая должна сделать это, но я получаю только странные ответы.

Я посылаю Последовательную строку. Эта строка должна начинаться с 'w', 'r' или 'e', в зависимости от того, какое действие я хочу выполнить. Второй символ должен быть int между 0 и 3, чтобы определить, что я должен использовать в качестве раба (в настоящее время я использую только 1 раба, поэтому int всегда должен быть 0). Остальная часть строки записывается в EEPROM, один байт/символ в то время.

Что я упускаю?

КОД:

    #include <SPI.h>

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

    // Multiple slaves for future project
    const int CHANNELS[4] = {10, 8, 7, 4};
    String readResult;

    void setup() {

      Serial.begin(9600);
      channelSetup(); // Установите все подчиненные контакты в КАНАЛАХ на OUTPUT и HIGH

      SPI.begin();
      SPI.setDataMode(SPI_MODE3);
      SPI.setClockDivider(SPI_CLOCK_DIV2);
      SPI.setBitOrder(MSBFIRST);

    }

    void loop() {

      Serial.println("START");

      while(!Serial.available());
      delay(20);

      // Получить все доступные байты/символы
      String serialInput = getSerialStream(Serial.available());

      // Второй символ в serialInput - это int от 0 до 3
      int channel = makeValidChannel(serialInput[1]);

      // "канал" должен быть между 0 и 3
      // чтобы иметь возможность указывать на КАНАЛЫ
      if (channel >= 0 && channel <= 3) {

        // Первый символ решает, что делать
        switch (serialInput[0]) {

          case 'w':
            writeToChannel(channel, serialInput.substring(2));
            break;

          case 'r':
            readResult = "EMPTY";
            readResult = readFromChannel(channel);
            Serial.print("Result: ");
            Serial.println(readResult);
            break;

          case 'e':
            overWriteEEPROM(channel);
            break;

          default:
            Serial.println("INVALID FIRST OPERATION");

        }

      }

      else
        Serial.print("INVALID CHANNEL: ");
        Serial.println(channel);

    }

    void channelSetup() {

      for (int i = 0; i < sizeof(CHANNELS); i++) {

        pinMode(CHANNELS[i], OUTPUT);
        digitalWrite(CHANNELS[i], HIGH);

      }

    }

    String getSerialStream(int numOfChars) {

      char serialStream[numOfChars + 1];
      int i;

      for (i = 0; i < numOfChars; i++) {

        serialStream[i] = char(Serial.read());
        delay(5);

      }

      serialStream[i] = '\0';
      return String(serialStream);

    }

    int makeValidChannel(char chIn) {

      int channel = chIn - '0';
      //channel -= 48;

      if (channel >= 0 && channel <= 3)
        return channel;
      else
        return -1;

    }

    void writeToChannel(int channel, String message) {

      int slaveselect = CHANNELS[channel];
      int i;

      // Write enabled
      digitalWrite(slaveselect, LOW);
      SPI.transfer(WREN);
      digitalWrite(slaveselect, HIGH);
      delay(5);

      // Отключить Защиту От Записи
      digitalWrite(slaveselect, LOW);
      SPI.transfer(WRSR);
      SPI.transfer(0);
      digitalWrite(slaveselect, HIGH);
      delay(5);

      for (i = 0; i < message.length(); i++) {

        digitalWrite(slaveselect, LOW);
        SPI.transfer(WRITE);
        SPI.transfer(0);
        SPI.transfer(i);
        SPI.transfer(message[i]);
        digitalWrite(slaveselect, HIGH);
        delay(5);

      }

      //  Когда запись "сообщения" завершена,
      // добавьте 0-байт в качестве завершающего символа
      digitalWrite(slaveselect, LOW);
      SPI.transfer(WRITE);
      SPI.transfer(0);
      SPI.transfer(i);
      SPI.transfer(0x00);
      digitalWrite(slaveselect, HIGH);
      delay(5);


      // Включить защиту от записи
      digitalWrite(slaveselect, LOW);
      SPI.transfer(WRSR);
      SPI.transfer(3);
      digitalWrite(slaveselect, HIGH);
      delay(5);

      // Запись отключена
      digitalWrite(slaveselect, LOW);
      SPI.transfer(WRDI);
      digitalWrite(slaveselect, HIGH);
      delay(5);

    }

    String readFromChannel(int channel) {

      Serial.println("Reading started");

      int slaveselect = CHANNELS[channel];
      char outputArr[64];
      int i = 0;

      while (true) {

        digitalWrite(slaveselect, LOW);
        SPI.transfer(READ);
        SPI.transfer(0);
        SPI.transfer(i);
        outputArr[i] = SPI.transfer(0x00);
        digitalWrite(slaveselect, HIGH);
        delay(5);

        if (outputArr[i] == 0x00 || i >= 64) {

          outputArr[i] = '\0';
          return String(outputArr);  

                }

        else
          i++;

      }

    }

    void overWriteEEPROM(int channel) {

      char zeroArr[64];
      for (int i = 0; i < 256; i++) {

        zeroArr[i] = 0;

      }

      writeToChannel(channel, String(zeroArr))

    }

, 👍1

Обсуждение

Не знаю, действительно ли это проблема, но в части "else" вашего оператора if в цикле отсутствуют открывающие и закрывающие фигурные скобки...., @Anonymous Penguin

@AnnonomusPenguin : Нет, но спасибо, что заметили. Это всего лишь незначительная ошибка, которая заставляет Serial.println(channel); работать независимо от if/else., @DoTheGenes

- но я получаю только странные ответы. Это довольно расплывчато, не могли бы вы дать нам несколько примеров результатов?, @Gerben

@Gerben : Я протестировал еще несколько тестов и, кажется, выяснил, что это были за "странные ответы": я заполнил первые 8 адресных полей своей EEPROM (используя рабочий демонстрационный код) значениями int в диапазоне от 59 и выше, а когда позже попытался прочитать значения, которые они распечатали в ASCII. I. E., "59" превратилось в ";"., @DoTheGenes

@DoTheGenes отличная работа. Значит, все решено!, @Gerben

@Gerben : Вроде как. Я разгадал тайну того, какие странные ответы были, но "readFromChannel ()" не остановится, когда строка, которую я написал в EEPROM, будет прочитана, она просто продолжает читать все адреса. В принципе, единственная причина, по которой он останавливается, заключается в том, что я ставлю условие i >= 64в оператор if'. Null`-терминатор не будет работать так, как предполагалось., @DoTheGenes

Это странно. Попробуйте добавить " Serial.print(outputArr[i], BIN)", чтобы увидеть отдельные считываемые биты. Проверьте, действительно ли присутствует `0x00'., @Gerben


1 ответ


0

Тип должен быть БАЙТОВЫМ, а не INT. Значение записи составляет 1 байт 0-255. При необходимости используйте типизацию.

int x;
byte y;
y = byte(x);
EEPROM.write(100, y);
,