Не получается читать из / писать в 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))
}
@DoTheGenes, 👍1
Обсуждение1 ответ
▲ 0
Тип должен быть БАЙТОВЫМ, а не INT. Значение записи составляет 1 байт 0-255. При необходимости используйте типизацию.
int x;
byte y;
y = byte(x);
EEPROM.write(100, y);
,
@Duino
Смотрите также:
- Последовательная связь между несколькими устройствами (или ардуино)
- Отправлять строки через SPI в обе стороны, используя два Arduino UNO (ведущий к ведомому и ведомый к ведущему)
- о том, как разделить один внешний последовательный EEprom с помощью двух микроконтроллеров?
- Serial.println не будет форматировать DEC
- Проблема с записью и чтением при подключении 93LC46B EEPROM через SPI
- использование EEPROM Arduino
- NeoICSerial и SPI на Uno — контакт 10
- Ардуино получает данные датчиков от других arduino SPI
Не знаю, действительно ли это проблема, но в части "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