Подключил и написал небольшую библиотеку для работы с памятью. ----------------------------------------------------------------- Пытаюсь подключить EEPROM память по SPI к Arduino но ничего не получатся Подключал по следующей схеме: Как подключать и обращаться брал отсюда :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 } В ответ получаю одни нули, подскажите как правильно работать с памятью.
Поторопился пробовать не изучив даташит- у них питание существенно отличается 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 .
Изменив программу на работу с хардварным 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-х байт, но в какой последовательности отправлять биты я не понял.
С адресом вроде разобрался, но запись на флеш не производится, в чем может быть причина? Код (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() { }
Выполняю Код (Text): digitalWrite(SLAVESELECT, LOW); SPI.transfer(0x20); SPI.transfer((address >> 16)); SPI.transfer(((address & 0xFFFF) >> 8)); SPI.transfer((address & 0xFF)); digitalWrite(SLAVESELECT, HIGH); Считанные данные после этого не меняются(
Спасибо, пауза в 1 сек и Unprotect Sector помогло)) Получается надо один раз стереть блок памяти и после в него можно записывать))
Есть другие типы памяти, у которых нет такого недостатка. Но у них объем маленький по сравнению с flash.
Создал небольшую библиотеку для работы с этой памятью, может кому пригодится Пример: Код (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,