Відповісти

Введіть повідомлення і натисніть Надіслати
Параметри

Назад

Огляд теми (нові повідомленні вгорі)

trackball
2021-03-23 16:24:35

Здравствуйте. Никак не могу побороть работу с Flash-памятью на Arduino UNO. Подключил через преобразователь уровней. SS пин на 9 пин UNO. (На 10-ом подключен W5500). С библиотекой SPIMemory читать флешку получается, а писать в нее - нет. Взял за основу эту библиотеку, выкинул все лишнее и получился такой код:

#define BAUD_RATE 2400

#define Flash_CS 9

#include <SPI.h>

// WinBond flash commands
#define WB_WRITE_ENABLE       0x06
#define WB_WRITE_DISABLE      0x04
#define WB_CHIP_ERASE         0xc7
#define WB_READ_STATUS_REG_1  0x05
#define WB_READ_DATA          0x03
#define WB_PAGE_PROGRAM       0x02
#define WB_JEDEC_ID           0x9f

#define SPI_PAGESIZE 256

void not_busy(void) {
  PORTB |= 4; // digitalWrite(W5500_CS, HIGH);
  PORTB &= 253; //  digitalWrite(Flash_CS, LOW);
  SPI.transfer(WB_READ_STATUS_REG_1);
  while (SPI.transfer(0) & 1) {};
  PORTB |= 2; // digitalWrite(Flash_CS, HIGH);
}

void _get_jedec_id(byte *b1, byte *b2, byte *b3) {
  PORTB |= 4; // digitalWrite(W5500_CS, HIGH);
  PORTB &= 253; //  digitalWrite(Flash_CS, LOW);
  SPI.transfer(WB_JEDEC_ID);
  *b1 = SPI.transfer(0); // manufacturer id
  *b2 = SPI.transfer(0); // memory type
  *b3 = SPI.transfer(0); // capacity
  PORTB |= 2; // digitalWrite(Flash_CS, HIGH);
  not_busy();
}  

void _read_page(word page_number, byte *page_buffer) {
  PORTB |= 4; // digitalWrite(W5500_CS, HIGH);
  PORTB &= 253; //  digitalWrite(Flash_CS, LOW);
  SPI.transfer(WB_READ_DATA);
  SPI.transfer((page_number >> 8) & 0xFF);
  SPI.transfer((page_number >> 0) & 0xFF);
  SPI.transfer(0);
  for (int i = 0; i < SPI_PAGESIZE; ++i) {
    page_buffer[i] = SPI.transfer(0);
  }
  PORTB |= 2; // digitalWrite(Flash_CS, HIGH);
  not_busy();
}

void _write_page(word page_number, byte *page_buffer) {
  PORTB |= 4; // digitalWrite(W5500_CS, HIGH);
  PORTB &= 253; //  digitalWrite(Flash_CS, LOW);
  SPI.transfer(WB_WRITE_ENABLE);
  PORTB |= 2; // digitalWrite(Flash_CS, HIGH);
  PORTB &= 253; //  digitalWrite(Flash_CS, LOW);
  SPI.transfer(WB_PAGE_PROGRAM);
  SPI.transfer((page_number >>  8) & 0xFF);
  SPI.transfer((page_number >>  0) & 0xFF);
  SPI.transfer(0);
  for (int i = 0; i < SPI_PAGESIZE; ++i) SPI.transfer((byte)page_buffer[i]);
  PORTB |= 2; // digitalWrite(Flash_CS, HIGH);
  not_busy();
}

void setup() {
  Serial.begin(BAUD_RATE);
  Serial.println("");
  Serial.println("=====================");
  Serial.println("START");
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  SPI.begin();
  SPI.setDataMode(0);
  SPI.setBitOrder(MSBFIRST);
  digitalWrite(10, HIGH);

//  flash.begin();

}

void startTest() {
  byte data_buffer[SPI_PAGESIZE];

  int startAddress = 32;
  int i4 = 0;

      uint8_t b1, b2, b3;
/*
      uint64_t UNIQ = getUniqueID();
      byte* ptrB = (byte*)&UNIQ;
      Serial.print("UniqueID: ");
      for(b1=0;b1<8;b1++) {
        b2 = (byte*)(ptrB + b1);
        Serial.print(b2,HEX);
        Serial.print(" ");
      }
      Serial.println("");
*/

      _get_jedec_id(b1,b2,b3);
      Serial.print("Manufacturer ID: ");
      Serial.print(b1,HEX);
      Serial.print(" Memory Type: ");
      Serial.print(b2,HEX);
      Serial.print(" Capacity: ");
      Serial.println(b3,HEX);


    _read_page(startAddress, &data_buffer[0]);
Serial.print(" startAddress: ");
Serial.print(startAddress);
Serial.print(" old: ");
Serial.print(data_buffer[i4],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+1],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+2],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+3],HEX);
        data_buffer[i4]=0xFF;
        data_buffer[i4+1]=0xFF;
        data_buffer[i4+2]=0x12;
        data_buffer[i4+3]=0xFF;
Serial.print(" new: ");
Serial.print(data_buffer[i4],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+1],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+2],HEX);
Serial.print(" ");
Serial.println(data_buffer[i4+3],HEX);
  delay(1000);
    _write_page(startAddress, &data_buffer[0]);
Serial.print(" test: ");
Serial.print(data_buffer[i4],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+1],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+2],HEX);
Serial.print(" ");
Serial.println(data_buffer[i4+3],HEX);
  delay(1000);
    _read_page(startAddress, &data_buffer[0]);
Serial.print(" result: ");
Serial.print(data_buffer[i4],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+1],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+2],HEX);
Serial.print(" ");
Serial.print(data_buffer[i4+3],HEX);

}

void loop() {
  if(Serial.available() > 0) { // Пришли данные от считывателя
    char _tempRS232 = Serial.read();
    Serial.print(_tempRS232);
    if(_tempRS232=='0') {
      Serial.println("");
      Serial.print("START TEST");
      startTest();
    }
  }
}

Вроде все работает, но есть одно НО: при попытке записи байта 0xFF ячейка памяти не обновляется. Любой другой байт записывается нормально.

Вот результат в терминале:

=====================
START
10
START TESTManufacturer ID: 0 Memory Type: 0 Capacity: 0
 startAddress: 32 old: 0 0 FF F0 new: FF FF 12 FF
 test: FF FF 12 FF
 result: 0 0 12 F0

Подскажите, что не так делаю.

Підвал форуму