Главная » Микроконтроллеры
Призовой фонд
на декабрь 2022 г.
1. 1000 руб
Сайт Паяльник
2. Мультиметр ANENG M118A
Сайт Паяльник
3. 50 руб.
От пользователей

Программатор SPI Flash, I2C EEPROM из Arduino или почти любого микроконтроллера

Иногда при разработке своих радиолюбительских устройств или при ремонте цифровой электроники возникает необходимость прошивки микросхем памяти, наиболее распространённые из них - это I2C EEPROM 24 серии и SPI FLASH 25 серии. Казалось бы, что может быть проще, купить копеечный программатор с известного китайского сайта или спаять несколько проводков и деталек под COM-Port? Но что, если прошить микросхему надо прямо сейчас, а паять или ждать посылки из Китая некогда/лень? На самом деле более-менее современные и не очень микроконтроллеры (далее - МК) в большинстве своём поддерживают необходимые протоколы обмена (SPI, I2C, UART) на аппаратном уровне и могут сами выступать в роли программатора. Дело лишь за программным обеспечением. Микроконтроллер ATMEGA328P не исключение. Он, как известно, используется, наверное, в самых известных в мире платах - Arduino в связке с USB-UART мостом - то есть всё, что нужно для создания программатора "на скорую руку". 

Мне нравится тема программаторов, я давно занимаюсь их разработкой (в развлекательных целях). Возможно вы уже видели мои предыдущие статьи. Первые мои поделки были очень сырые и медленные (вообще, удивляюсь, как они работали, глядя на свой старый код). В этот раз я решил поэкспериментировать с протоколом обмена между МК и компьютером по COM порту, а если точнее, я решил попробовать пакеты переменной длины. Я хотел посмотреть, насколько можно увеличить скорость обмена по сравнению с пакетами фиксированной длины. И вот эти эксперименты вылились в очередное устройство, которое, надеюсь, будет полезным как новичкам, так и более опытным радиолюбителям. Поехали....

Для начала хочу объяснить принцип обмена данными в моём устройстве между ПК и МК. Пакет данных - это последовательность байт, который (в моём случае) состоит из заголовка (1 байт - 0xFE), размера "полезных" байт (1- байт), маркера пакета (1 байт) и полезных данных (1 - 255 байт). Как ПК, так и МК при получении данных по UART последовательно "разбирают" пакет и обрабатывают данные. Принцип разборки пакета данных примерно одинаковый как в ПК, так и в МК. МК в прерывании, а ПК в событии по приходу байта в UART сначала ожидают первые три байта пакета, первым проверяется заголовок (1-й байт), если он неверный (не 0xFE), то пакет сразу отбрасывается и считается битым. Затем высчитывается размер "полезных" данных (2-й байт) и маркер пакета ( 3-й байт). А после дочитываются "полезные данные" согласно рассчитанному количеству (для корректной работы размер полезных данных в пакете не может быть меньше единицы). Затем пакеты обрабатываются в соответствующих функциях согласно их маркеру (используется конструкция switch-case). Такой формат пакета данных позволяет производить минимальную проверку на ошибки и ускоряет обмен за счет минимизации пакетов запрос/подтверждение в сравнении с пакетами фиксированной длины. В принципе, подобный протокол обмена может использоваться и в любых других радиолюбительских конструкциях, где нужен обмен между ПК и МК.

Как я писал вначале, программатор можно сделать практически на любом микроконтроллере (с небольшими ограничениями: SRAM - не менее 1кБ, хотя, если постараться, то можно и в 512 байт уложиться, FLASH не менее 4 кБ, наличие UART, SPI, I2C). Для этого необходимо переписать всего три драйвера: UART с прерыванием по приёму байта, SPI и I2C. Лично я опробовал работу устройства сначала на STM32F030, затем переписал код на 1T MCS-51 МК (Nuvoton N76E003), atmega328 (arduino nano) и STM8S103F3, просто изменив инициализацию периферии, практически не изменяя основной код (хотя, с атмегой были "танцы с бубном", GCC как-то по своему интерпретирует Си код). В конце статьи приведу результаты "замеров скорости" работы программатора на разных МК при одинаковой скорости UART и на "максималках". 

Код написан на Си (не смотрите на слово arduino в названии статьи), его несложно адаптировать под разные МК. Структура кода следующая: в файле main.c - глобальные переменные, обработчик прерывания, драйверы UART, SPI, I2C в отдельных одноимённых *.h и *.c файлах, основная обработка пакетов и функции чтения/записи происходит в файле progger.c. Свои исходники и HEX-ы для avr, stm32 и n76e003 я прикреплю в конце статьи. В случае arduino HEX файл можно прошить с помощью утилиты X-Loader и подобных, STM шьётся через UART утилитой FLASH_Demonstrator (если мне не изменяет память), остальные из приведённых камней - только программаторами. Проекты для STM32 и AVR, в принципе, завершённые, проекты для Nuvoton и STM8 не полностью, там только реализована работа со SPI FLASH, исключительно для сравнения производительности и вообще, проверки работоспособности на других архитектурах.

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

При подключении к arduino и другим 5-вольтовым платам запитывать SPI FLASH необходимо от пина 3v3, остальные сигналы можно напрямую. Если SPI FLASH на 1,8 вольта, то без преобразователя логических уровней не обойтись. EEPROM можно питать и от 5v и от 3v3. Обратите внимание, что линии SCL и SDA I2C необходимо подтянуть к плюсу питания через резисторы 4,7 кОм. В моих прошивках подключения следующие:

  Arduino(UNO/NANO) STM32F030K6 N76E003
SPI MISO    D12(PB4)    PA6   P0.1
SPI MOSI    D11(PB3)    PA7   P0.0
SPI SCK    D13(PB5)    PA5   P1.0
SPI SS    D9(PB1)    PB1   P1.1
I2C SCL    A5(PC5)    PA9   P1.3
I2C SDA    A4(PC4)    PA10   P1.4

У STM задействован UART1 (PA2,PA3), у N76E003 UART на P0.6, P0.7, у arduino - на своём месте)))

Со стороны ПК - простая программка с графическим интерфейсом, написанная на C# буквально за несколько часов (так как у меня уже были приличные наработки по этой теме). Для работы нужен пакет .net framework. В программе реализованы минимально необходимые функции (чтение, запись, стирание, проверка записанного, получение ID и немного других). В список поддерживаемых устройств я не вносил никакой экзотики: большинство I2C EEPROM шьются и читаются однотипно, поэтому список состоит устройств без учёта производителя, только по объёму памяти; список SPI FLASH состоит только из чипов Winbond почти всех возможных размеров, но шьются большинство флешек тоже однотипно и размер блока у них почти всегда 256 байт (за исключением экзотики), так что должны работать флешки и других вендоров. 

Интерфейс программы:

Интерфейс программы интуитивно понятный. Для начала работы необходимо выбрать COM порт, к которому подключен программатор, скорость передачи (стандартные запрограммированные в моих прошивках скорости для arduino и N76E003 - 57600, для STM32 - 921600, STM8S - 38400, скорость можно изменить в исходниках, даже установить нестандартные скорости, например для STM8 я ставил 50000, что порядком ускоряет работу). Нажимаем кнопку "OPEN" (вверху). Если всё подключено правильно, нажимаем кнопку "Check Progger", в консольном окошке должна появиться надпись "Программатор подключен", значит можно работать. Кнопка "Verify" работает несколько необычно - она сравнивает прочитанную прошивку с загруженной для записи (т.е. сначала записываем, затем читаем, а только потом - сравниваем). Остальные кнопки в комментариях не нуждаются. Все функции в программе не блокирующие, то есть, пока идёт запись или чтение - ничего не нажимаем. Также при работе с I2C EEPROM, если микросхема не подключена к программатору, чтение и запись будут "висеть", так как необходим ответ от EEPROM.

А теперь - самое интересное. Тесты скорости. Будем проверять скорость чтения SPI FLASH объёмом один Мегабайт. Будем проверять на скорости UART 57600 бод для всех плат, кроме STM8 (её максималка - 38400 бод), а потом запустим STM32F030 на 921600 бод. Флешка будет W25Q16 на 2 Мегабайта, но читать будем только 1 мегабайт (как будто это W25Q80). Поехали!

1. ARDUINO NANO (Atmega328p 16 MHz 57600 бод) - мегабайт за 3 минуты 4 секунды.

2. STM32F030 (48 MHz 57600 бод) - 3 минуты 34 секунды, что?!

3. STM8F103 (16 MHz 38400 бод) - 5 минут 16 секунд

4. Nuvoton N76E003 (16 MHz 57600 бод) - 5 минут 49 секунд

И вне конкурса:

5. STM32F030 (48 MHz 921600бод, так сказать - на максималках) - 32 секунды!!!

6. CH341 заводской программатор USB 2.0 FS - 8 секунд 236 миллисекунды

Прежде чем делать окончательные выводы, хочу сказать сразу, что atmega328 немного жульничает. Дело в том, что атмега наотрез отказывалась выходить из цикла ожидания подтверждения от хоста перед отправкой очередного пакета при чтении (то есть, в цикле чтения МК перед отправкой пакета с очередной порцией прочитанного ждёт от хоста короткий пакет подтверждения, чтобы убедиться, что хост успел обработать предыдущий пакет). Но так как SPI в атмеге работает не очень быстро, я вообще отключил ожидание подтверждения, оказалось, что хост и так успевает. А в остальных МК эта функция работает штатно и немного притормаживает работу. Также я не уверен, что в Nuvoton SPI работает на максимальной скорости (просто, я их не так хорошо знаю и сильно не вникал в модуль SPI).

Какие можно сделать выводы из полученных результатов? Восьмибитные микроконтроллеры в своей нише всё еще востребованы и достаточно хорошо справляются с адекватными задачами, даже имея на борту древнее немного "освежённое"  ядро 1Т MCS-51. И при прочих равных условиях достаточно достойно показывают себя в сравнении с 32 битными. Но, учитывая более высокие частоты ядра и периферии 32 битных микроконтроллеров, в задачах, где требуется высокая скорость обработки данных и работы периферических модулей они оставляют восьмибитные МК далеко позади.

Что касается программатора, то даже на arduino (atmega328) он может быть полезен при отсутствии заводского. Ведь достаточно просто залить прошивку через обычный USB кабель, накинуть несколько проводов и программатор готов. А потом можно вернуть ардуину в исходное состояние и использовать её по любому другому назначению. Даже при такой скорости записи/чтения (~ 3 минуты на мегабайт) можно прошить даже 8-мегабайтную флешку. А EEPROM вообще шьются считанные секунды. А при желании можно взять 20-ногий STM32F030F3 и CH340 (даже в 8-ногом корпусе) и сделать себе отдельный программатор с уже приличными скоростями чтения/записи. Тем более, все исходники, в том числе и самой программы я оставлю в конце статьи. Есть даже поле для творчества, можно подправить мой код, добавить поддержку других устройств. 

PS: на досуге скомпилировал проект под синюю и чёрную таблетки (stm32f103c8t6 и stm32f411ceu соответственно) только на аппаратном USB (CDC) под тот же софт. Скорость работы просто впечатляет, чтение 1 мегабайта - за 4 секунды чёрная таблетка на частоте ядра 96 MHz и около 5 секунд - синяя таблетка на частоте ядра 72 MHz. Нервно курят в сторонке даже CH341 и EZP20хх (который я тоже протестировал на скорость чтения 1 мегабайта, результат приблизительно как и у CH341).

У таблеток реализовал только работу со SPI FLASH ради замера скорости. Функции EEPROM могу добавить, если кому-то будет интересно. Подключение у обеих таблеток к SPI1 (PA5,PA6,PA7), CS - на PA4. У чёрной таблетки на пузе имеется место под пайку микросхемы SPI FLASH, к ней тоже подходят нужные сигналы. 

Также подправил обнаруженные ошибки в софте. С софтом с платами-таблетками работать точно также, только скорость COM порта не имеет значения, так как физического UART там уже нет и обмен всегда на максимальной скорости. При подключении платы по USB к ПК появится виртуальный COM порт. Драйвера на Win 10 станут автоматом. EXE-файл находится в архиве с проектом по пути "../debug/bin".

На этом, пожалуй, всё. Желаю всем удачи. Конструктивная критика приветствуется.

Прикрепленные файлы:

Теги:

Опубликована: 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (3) | Я собрал (0) | Подписаться

0
Публикатор #
На форуме автоматически создана тема для обсуждения статьи.
Ответить
0
Shida #
ПИКи программирует? PIC16F628A например.
Отредактирован 24.11.2022 13:47
Ответить
0

[Автор]
AndrejChoo #
Читайте внимательно. Только еепром и spi flash. Пики это очень страшное г в плане прошивки, у них нет единого алгоритма программирования, одинаково программируются только 2-3 чипа в рамках подсемейства. Поэтому сделать программатор для pic очень сложная задача. Я как-то пытался сделать для pic16f73, получилось только прочитать id не более.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Набор 4WD Kit Bluetooth USB-реле (2 канала)
вверх