logo
+7 (951) 999-89-94
428003, г. Чебоксары, ул. Федора Гладкова, д.9, оф.319

Работа с памятью M25P40. Часть 7. Read и Write Char array и String

Продолжаем изучать работу с микросхемой памяти M25P40VP, установленной на плате uniSensors nRF24 и в этой статье мы познакомимся с чтением и записью строковых данных, таких, как массивы символов (char array) и String.

Read & Write char array

В среде программирования Ардуино работать со строковыми значениями можно при помощи двух типов данных — это массивы символов (char array) и String. Начнём с char array.

Char array — это набор символов (собственно текстовые строки), упакованные и представленные в виде массивов байтов типа char. Каждая такая строка оканчивается байтом нулевого значения, который означает конец строки. Например, если у вас есть строка «line», состоящая из 4-х символов, то полная длина этой строки будет равна 5-и байтам (плюс завершающий ноль).

Теперь давайте создадим скетч, который позволит записывать тестовую текстовую строку в память микросхемы M25P40VP и считывать её обратно. Скетч будет учитывать все особенности работы в Ардуино с данными типа char array и различные нюансы работы с памятью чипа M25P40VP.

Код скетча M25P40 Read & Write char array:

/*
  M25P40 Read & Write char array
*/

#include <SPI.h>
#include <SPIFlash.h>

#define FLASH_SS 8

#define TEST_ADR 0

char charsValue[] = "TestCharArray";
int len = sizeof(charsValue);

SPIFlash flash(FLASH_SS);

void setup() {
  Serial.begin(115200);
  Serial.println(F("M25P40 Read & Write char array start..."));

  Serial.print(F("Init "));
  if (flash.initialize()) {Serial.println(F("OK"));}
                     else {Serial.println(F("FAIL"));}

  erase();
  read_String(TEST_ADR);
  
  write_String(TEST_ADR);
  read_String(TEST_ADR);
}

void checkBusy() {
  uint32_t stt = millis();
  while (flash.busy()) { }
  uint32_t del = millis() - stt;
  if (del) {
    Serial.print(F(" (")); Serial.print(del); Serial.print(F(" ms)"));
  }
  Serial.println();
}

void erase() {
  Serial.print(F("Full erase..."));
  flash.chipErase();
  checkBusy();
}

void read_String(uint32_t adr) {
  char charArray[len + 1];

  flash.readBytes(adr, charArray, len);
  charArray[len] = 0;
  
  Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(charArray);
}

void write_String(uint32_t adr) {
  flash.writeBytes(adr, charsValue, len);
  
  Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(charsValue);
}

void loop() {
  
}

Вначале мы задаём адрес тестовой ячейки (ячейки для записи первого символа нашей строки) памяти M25P40VP, в нашем случае это нулевая ячейка.

#define TEST_ADR 0

Затем мы создаём массив символов charsValue и присваиваем ему значение «TestCharArray».

char charsValue[] = "TestCharArray";

Далее мы вычисляем количество символов в нашей тестовой строке и присваиваем это значение переменной len.

int len = sizeof(charsValue);

Далее мы полностью стираем содержимое памяти чипа M25P40VP и читаем содержимое ячеек в которых должна быть записана наша строка (чтобы убедиться, что стирание прошло успешно и ячейки готовы для записи в них новой информации).

  erase();
  read_String(TEST_ADR);

Затем производим запись тестовой строки, начиная с нулевой ячейки, читаем её из микросхемы и проверяем результат.

  write_String(TEST_ADR);
  read_String(TEST_ADR);

Чтение производится функцией read_String(), которой мы передаём адрес стартовой ячейки в качестве параметра.

void read_String(uint32_t adr) {
  char charArray[len + 1];

  flash.readBytes(adr, charArray, len);
  charArray[len] = 0;
  
  Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(charArray);
}

Создаём временный массив charArray размера len + 1.

  char charArray[len + 1];

Читаем, начиная с адреса adr, len байтов в массив charArray при помощи функции flash.readBytes().

  flash.readBytes(adr, charArray, len);

И дописываем ограничивающий ноль в позицию len временного массива.

  charArray[len] = 0;

Далее выводим на печать полученный результат при помощи функции Serial.println().

  Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(charArray);

Запись тестовой строки осуществляется при помощи функции write_String().

void write_String(uint32_t adr) {
  flash.writeBytes(adr, charsValue, len);
  
  Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(charsValue);
}

Здесь мы при помощи функции flash.writeBytes() записываем в память микросхемы M25P40VP массив charsValue по адресу adr и длинной len.

  flash.writeBytes(adr, charsValue, len);

Далее выводим в Serial информационное сообщение о наших действиях.

  Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(charsValue);

И вот результат работы нашего скетча:

Первая строка

Read #0:яяяяяяяяяяяяяя

которую вывел контроллер на печать и состоящая из нескольких символов «я» — это текстовое представление очищенных ячеек памяти микросхемы M25P40VP, которые после процедуры очистки содержат значения 255 (11111111 в двоичном представлении).

Далее мы видим записываемую строку символов

Write #0: TestCharArray

и успешно прочитанную из памяти M25P40VP строку после проведённой операции записи.

Read #0: TestCharArray

Отлично! Теперь переходим к работе со стандартным для Ардуино представлением текстовых строк — типу String.

Read & Write String

Работа по записи и чтению строковых данных типа String похожа на работу с данными типа char array, правда тут есть ряд нюансов, связанных с организацией этих типов данных в Ардуино и далее мы подробно разберём работу со строковыми данными типа String.

String — это объектный тип данных (подробно описанный в документации Ардуино), предназначенный для хранения и работы со строковыми данными. Кроме собственно хранения строковых значений, этот тип данных имеет множество функций предназначенных для удобной работы со строками текста.

Далее мы создадим и разберём работу скетча для записи и чтения данных типа String из памяти микросхемы M25P40VP. Код скетча M25P40 Read & Write String:

/*
  M25P40 Read & Write String
*/

#include <SPI.h>
#include <SPIFlash.h>

#define FLASH_SS 8

#define TEST_ADR 0

String StringValue = "TestString";
int len = StringValue.length();

SPIFlash flash(FLASH_SS);

void setup() {
  Serial.begin(115200);
  Serial.println(F("M25P40 Read & Write String start..."));

  Serial.print(F("Init "));
  if (flash.initialize()) {Serial.println(F("OK"));}
                     else {Serial.println(F("FAIL"));}

  erase();
  read_String(TEST_ADR);
  
  write_String(TEST_ADR);
  read_String(TEST_ADR);
}

void checkBusy() {
  uint32_t stt = millis();
  while (flash.busy()) { }
  uint32_t del = millis() - stt;
  if (del) {
    Serial.print(F(" (")); Serial.print(del); Serial.print(F(" ms)"));
  }
  Serial.println();
}

void erase() {
  Serial.print(F("Full erase..."));
  flash.chipErase();
  checkBusy();
}

void read_String(uint32_t adr) {
  String s = "";
  char charArray[len];
  
  flash.readBytes(adr, charArray, len);
  
  for (int i = 0; i < len; i++) {
    s += charArray[i];
  }
  
  Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(s);
}

void write_String(uint32_t adr) {
  char char_array[len];
  
  strcpy(char_array, StringValue.c_str()); 
  flash.writeBytes(adr, char_array, len);
  
  Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(StringValue);
}

void loop() {
  
}

Вначале, как и в случае работы с char array, мы задаём адрес тестовой ячейки (ячейки для записи первого символа нашей строки) памяти M25P40VP, в нашем случае это нулевая ячейка.

#define TEST_ADR 0

Затем мы создаём тестовую строку и присваиваем ей значение «TestString».

String StringValue = "TestString";

Далее мы вычисляем количество символов в нашей тестовой строке при помощи функции length() и присваиваем это значение переменной len.

int len = StringValue.length();

Далее мы полностью стираем содержимое памяти чипа M25P40VP и читаем содержимое ячеек в которых должна быть записана наша строка (чтобы убедиться, что стирание прошло успешно и ячейки готовы для записи в них новой информации).

  erase();
  read_String(TEST_ADR);

Затем производим запись тестовой строки, начиная с нулевой ячейки, читаем её из микросхемы и проверяем результат.

  write_String(TEST_ADR);
  read_String(TEST_ADR);

Чтение производится функцией read_String(), которой мы передаём адрес стартовой ячейки в качестве параметра.

void read_String(uint32_t adr) {
  String s = "";
  char charArray[len];
  
  flash.readBytes(adr, charArray, len);
  
  for (int i = 0; i < len; i++) {
    s += charArray[i];
  }
  
  Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(s);
}

Создаём переменную s типа String и присваиваем ей пустое значение. Эта переменная понадобится нам далее для получения и хранения прочитанной из памяти M25P40VP строки.

  String s = "";

Далее создаём временный массив charArray размера len.

  char charArray[len];

Читаем, начиная с адреса adr, len байтов в массив charArray при помощи функции flash.readBytes().

  flash.readBytes(adr, charArray, len);

Далее «собираем» прочитанную тестовую строку в переменную s из временного массива charArray.

  for (int i = 0; i < len; i++) {
    s += charArray[i];
  }

Далее выводим на печать полученный результат при помощи функции Serial.println().

  Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(s);

Запись тестовой строки осуществляется при помощи функции write_String().

void write_String(uint32_t adr) {
  char char_array[len];
  
  strcpy(char_array, StringValue.c_str()); 
  flash.writeBytes(adr, char_array, len);
  
  Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(StringValue);
}

Здесь мы создаём временный массив char_array размера len.

  char char_array[len];

При помощи функции strcpy() копируем содержимое переменной StringValue в массив char_array.

  strcpy(char_array, StringValue.c_str()); 

И далее записываем в память микросхемы M25P40VP массив char_array по адресу adr и длинной len.

  flash.writeBytes(adr, char_array, len);

Далее выводим в Serial информационное сообщение о наших действиях.

  Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(StringValue);

Вот результат работы нашего скетча:

Всё прошло корректно и именно так, как мы и ожидали — тестовая строка типа String была записана в память микросхемы M25P40VP и успешно считана из неё.

Заключение

На этом уроке мы научились читать и записывать в память микросхемы M25P40VP, установленной на беспроводном контроллере uniSensors nRF24, строковые типы данных char array и String. В следующей статье мы продолжим увлекательное знакомство с чипом M25P40VP и разберём работу с секторами памяти этой микросхемы.

Ссылки по теме

Обзор контроллера uniSensors nRF24

Спецификации uniSensors nRF24

Программирование uniSensors nRF24

Работа с памятью M25P40. Часть 1. Спецификации и библиотека

Работа с памятью M25P40. Часть 2. Sleep, Wakeup, Erase и Busy

Работа с памятью M25P40. Часть 3. Read и Write Byte и Arrays

Работа с памятью M25P40. Часть 4. Работа с беззнаковыми типами данных

Работа с памятью M25P40. Часть 5. Работа со знаковыми типами данных

Работа с памятью M25P40. Часть 6. Read и Write Float

Работа с памятью M25P40. Часть 7. Read и Write Char array и String

Работа с памятью M25P40. Часть 8. Работа с секторами

Работа с памятью M25P40. Часть 9. Выборочное стирание секторов

Работа с памятью M25P40. Часть 10. Копирование секторов

Работа с памятью M25P40. Часть 11. Восстановление (backup) секторов

Работа с памятью M25P40. Часть 12. Работа с блоками памяти

Работа с памятью M25P40. Часть 13. Пишем библиотеку для M25P40

Работа с памятью M25P40. Часть 14. Пишем библиотеку для M25P40 (2)

Работа с памятью M25P40. Часть 15. Пишем библиотеку для M25P40 (3)

Где купить?

uniSensors nRF24 в магазине «Electromicro»

Техническая поддержка

Мы внимательно относимся к потребностям наших клиентов и осуществляем техническую поддержку всей выпускаемой продукции. Вы можете написать нам письмо с вашим вопросом или позвонить по телефону и специалист нашей компании проконсультирует вас и поможет решить вашу проблему.

  • Емейл для вопросов по нашей продукции: electromicro@bk.ru
  • Наш телефон: +7 (495) 997-37-74

Аналогичные товары