ESP32 Урок 9. SPI. FLASH память W25Q. Получение информации из микросхемы

 

 

 

На прошлом уроке мы научились работать с шиной SPI только на передачу данных, а сегодня мы уже попытаемся что-нибудь по данной шине принять от подключаемого устройства.

Как нельзя лучше для этой цели подойдёт микросхема FLASH-памяти семейства W25Q. Есть много других вариантов работы с шиной SPI на приём, но с данной микросхемой мы уже работали с применением контроллера STM32 и поэтому я считаю, что лучше идти уже по изученному, чем сталкиваться с кучей проблем.

Повторю некоторые характеристики данной микросхемы FLASH-памяти.

Потребляемая мощность и температурный диапазон:

  • Напряжение питания 2.7…3.6 В
  • Типичный потребляемый ток: 4 мА (активный режим), <1 мкА (в режиме снижения мощности)
  • Рабочий температурный диапазон -40°C…+85°C.

Гибкая архитектура с секторами размером 4 кбайт:

  • Посекторное стирание (размер каждого сектора 4 кбайт)
  • Блочное стирание (32кбайт и 64 кбайт)
  • Программирование от 1 до 256 байт
  • До 100 тыс. циклов стирания/записи
  • 20-летнее хранение данных

Максимальная частота работы микросхемы:

  • 104 МГц в режиме SPI
  • 208/416 МГц — Dual / Quad SPI

Есть ещё много различных возможностей, но это самые основные.

Также микросхема существует в различных корпусах, но в большинстве случаев распространён корпус SMD SO8.

Распиновка микросхемы следующая

 

 

Назначение каждого вывода:

 

Номер вывода Название Ввод/вывод (I/O) Назначение
1 /CS I Выбор чипа
2 DO (IO1) I/O Вывод данных (Ввод/вывод данных #1 для режимов S-SPI и D-SPI)
3 /WP (IO2) I/O Вход защиты записи (Ввод/вывод данных #2 для режима Q-SPI)
4 GND   Общий провод
5 DI(IO0 ) I/O Ввод данных (Ввод/вывод данных #0 для режимов S-SPI и D-SPI)
6 CLK I Ввод тактовых импульсов
7 /HOLD or /RESET (IO3 ) I/O Ввод/вывод данных #3 для режима Q-SPI
8 VCC   Напряжение питания

 

Согласно распиновке схема у нас получится вот такая

 

Следует отметить, что микросхема W25Q устроена так же как FLASH-память у stm32, то есть память у неё разбита на страницы по 256 байт, страницы объединены в секторы по 4096 байт, а секторы в блоки по 65536 байт. Организацию памяти микросхемы можно посмотреть на схеме

 

 

Перед тем как что-то записать, нужно стереть сектор (4096 байт) или блок (65536 байт). Можно стереть несколько секторов или блоков, или весь чип полностью. Во время стирания ячейки заполняются значениями 0xFF.

Каким образом организован процесс стирания, а также чтения и записи микросхемы, мы разберём в дальнейших занятиях, а сегодня наша задача — подключить микросхему к контроллеру, настроить проект для организации кода работы контроллера с микросхемой и в качестве испытания считать некоторые данные из неё.

Поэтому мы пока не будем забивать себе голову изучением всех регистров и их битов данной микросхемы W25Q, так как их там очень много, а будем их изучать по мере их использования.

Я буду использовать микросхему 25Q32FVSIG в корпусе SMD SO8, в которой 32 мегабита памяти, которую я припаял на переходник SO8-DIP, а также распаял штырьевые линейки для удобства подключения к контроллеру, получилась вот такая табуреточка

 

 

Подключим нашу микросхему к отладочной плате, также для большего контроля за передачей данных подключим логический анализатор и в результате получим получим вот такую схему

 

 

Проект урока был сделан из проекта прошлого урока с именем  и назван был SPI_25Q_INFO.

Прежде, чем открыть наш проект в среде программирования, в файл Kconfig.projbuild каталога main мы добавим ещё один пункт для ножки MISO

 

 

Файлы max7219.h и max7219.c переименуем соответственно в w25q_spi.h и w25q_spi.c, очистим их и пока они будут такого содержания:

 

 

 

Мы пока частоту большую не будем использовать, чтобы не думать, что у нас ошибки из за слишком большой скорости.

В файле CMakeLists.txt также внесём соответствующее исправление

 

set(COMPONENT_SRCS "main.c w25q_spi.c")

 

Откроем проект в Espressif IDE и в файле main.h вместо max7219.h подключим файл w25q_spi.h

 

#include "w25q_spi.h"

 

В функции app_main удалим локальную переменную

 

volatile long cnt;

 

В заполнении полей структуры инициализации модуля SPI вместо -1 добавим ножку MISO

 

      .miso_io_num = CONFIG_PIN_NUM_MISO,

 

В самом начале тела функции зададим направление для ножек GPIO

 

 

В третьем параметре функции инициализации модуля зададим автоматическое определения канала DMA

 

  ret = spi_bus_initialize(HSPI_HOST, &cfg, SPI_DMA_CH_AUTO);

 

Вот это всё удалим

 

max7219_t dev;
Init_7219(&dev, HSPI_HOST, CONFIG_PIN_NUM_CS);
Number_7219(&dev, 12345678);
vTaskDelay(2000 / portTICK_PERIOD_MS);

 

В бесконечном цикле счётчик нам также не нужен, так что код, предназначенный для него, тоже удалим

 

Clear_7219(&dev);
Number_7219(&dev, cnt);
cnt++;
if(cnt>99999999) cnt = 0;

 

Теперь у нас проект должен собраться.

В файле w25q_spi.h объявим структуру для нашего устройства

 

 

А в файле w25q_spi.c добавим функцию инициализации микросхемы

 

 

 

Объявим на данную функцию прототип в заголовочном файле и вызовем её в функции app_main файла main.c, объявив перед этим делом переменную структуры

 

 

Вернёмся в функцию инициализации w25_ini в файл w25q_spi.c, объявим там переменную для отслеживания кода ошибки, также объявим переменную структуры устройства и заполним её поля

 

 

Также добавим глобальный символьный массив для информации в логах

 

 

Вернёмся в функцию w25_ini, объявим указатель для переменной типа структуры устройства и вызовем функцию инициализации нашего устройства, проверив затем код ошибки с помощью лога

 

 

Соберём код, прошьём контроллер и убедимся, что обе наши функции инициализации отработали без ошибок

 

Присвоим указатель полю нашей структуры

 

 

В файле w25q_spi.h добавим несколько макросов с адресами регистров микросхемы

 

 

Вернёмся в файл w25q_spi.c и выше функции w25_ini  добавим функцию перезагрузки микросхемы

 

 

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

В функции w25_ini вызовем нашу функцию, добавив задержку до и после вызова функции.

 

 

Соберём код, прошьём контроллер и посмотрим, передались ли данные

 

Всё передалось.

Выше функции w25_ini добавим функцию чтения идентификатора нашей микросхемы

 

 

Здесь практически тот же самый код, так как данные, прочитанные из шины, пишутся в тот же массив, указатель на который мы присваиваем переменной структуры. поэтому мы просто забираем эти данные и возвращаем.

Вызовем нашу функцию в w25_ini и отобразим наш идентификатор в терминале

 

 

Соберём код, прошьём контроллер и посмотрим результат

 

В заголовочном файле w25q_spi.h объявим структуру для информации о микросхеме согласно считанного идентификатора

 

 

Вернёмся в файл w25q_spi.c и в функции w25_ini объявим переменную типа данной структуры

 

 

Ниже определим тип микросхемы и выведем о ней информацию в терминал

 

Соберём код, прошьём контроллер и посмотрим результат

 

Также посмотрим в программе логического анализа, как происходит процесс чтения

 

 

Всё хорошо, без пропусков.

Теперь прибавим немного скорость

 

#define CLOCK_SPEED_HZ (10000000) // 10 MHz

 

Посмотрим результат

 

 

Всё также отлично обменивается.

Итак, на данном уроке мы получили информацию из микросхемы W25Q. Также мы научились работать с модулем SPI на чтение.

Спасибо за внимание!

 

Данная статья в Дзен.

 

Предыдущий урок Программирование МК ESP32 Следующий урок

 

Исходный код

 

Недорогие отладочные платы ESP32 можно купить здесь: Недорогие отладочные платы ESP32

Логический анализатор 16 каналов можно приобрести здесь

Микросхему FLASH-памяти W25Q32FVSSIG SOP8 (5 штук)можно приобрести здесь W25Q32FVSSIG

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP32 STM32F4. FLASH память W25Q. Получение информации из микросхемы

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

ESP32 STM32F4. FLASH память W25Q. Получение информации из микросхемы

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*