В статье рассмотрен частный случай ремонта платы Arduino Uno R3 - выявление дефектов, замена вышедших из строя электронных компонентов, программирование загрузчика с помощью платы на основе микроконтроллера LGT8F328, скетча ArduinoISP и ArduinoIDE, использование программы Avrdudeprog (GUI avrdude) с программатором ArduinoISP, применение преобразователя USBtoTTL. Материал может быть полезен тем радиолюбителям, кто впервые столкнулся с программированием "чистого" микроконтроллера.
Обратился за помощью в ремонте платы Arduino Uno сосед - юный радиолюбитель. Вывел из строя плату во время экспериментов по созданию простого измерителя RLC и тестера транзисторов на базе Ардуино. И даже рассказал как всё произошло - решил проверить "большой" конденсатор, предварительно его не разрядив. Увеличение цены на платы Ардуино делает актуальным проведение ремонта.
Плата Arduino Uno R3, соответственно клон оригинальной платы.
Краткий состав основных компонентов: микроконтроллер atmega328P (корпус TQFT32, документация), преобразователь интерфейса CH340G (корпус so16, документация), стабилизатор напряжения AMS1117 5V (корпус sot223, документация), стабилизатор напряжения XC6206 3.3V (корпус sot23, smd маркировка "662К", документация), операционный усилитель типа LM358 (корпус so8, документация), диод SMA4007 (или аналог, корпус do-214ac, маркировка smd "M7", документация), MOSFET транзистор типа ASDM2301ZA (или аналог, корпус sot23, маркировка smd "A1SHB", документация). Принципиальная схема приведена на Рисунке 2. Схемотехника плат иногда отличается в части цепей питания 5 вольт, 3.3 вольт и подключения CH340G.
Симптоматика "болезни" платы: при внешнем питании (Uin 7B-12B) платы светодиоды не светятся, корпуса микросхем и других "активных" компонентов не греются. Ток потребления - около 200 мкА. При питании +5В - светятся "ON", "RX", "TX", "L". Сильно греется корпус микроконтроллера. Ток потребления порядка 200 мА, эмуляции COM порта нет.
При питании от внешнего источника постоянного тока проверяем напряжение на входе AMS1117 (должно быть меньше напряжения питания на напряжение "падения" на диоде "М7" - то есть ниже на 0.4В - 1.1В, если значения другие - меняем диод), проверяем 5В на выходе - если нет напряжения - заменяем AMS1117 (в нашем случае стабилизатор "сгорел").
При питании +5В (от USB порта или источника постоянного тока напряжением 5В) на выходе стабилизатора XC6206 напряжение 3.3 В есть, на выводах (7,8) микроконтроллера, подключаемых к кварцевому резонатору - "тишина" (смотреть осциллографом, 16 МГц). Так же и на преобразователе интерфейса - на выводах микросхемы предназначенных для подключения кварцевого резонатора нет сигнала (12 МГц). Вывод (с учетом того, что микроконтроллер решил поработать преобразователем электрической энергии в тепловую - "капитан очевидность") - микроконтроллер "мертв".
Итого под замену, как минимум - стабилизатор 5В и микроконтроллер ATmega328P. Демонтируем поврежденные компоненты, впаиваем новые компоненты (использовал LM1117 - в параметрах разницы практически нет между AMS и LM).
Ток потребления вернулся к "разумным" значениям - порядка 30 мА при напряжении питания 5В. Но остались светится светодиоды "TX" и "L". При подключении по USB появилась эмуляция COM порта. Теперь нужно выполнить следующий шаг - запрограммировать в "чистый" микроконтроллер загрузчик - иначе все "прелести ардуиновода" пропадут (Вы не сможете программировать микроконтроллер любимым способом через COM из ArduinoIDE). Для загрузки "на прямую" при работе с микроконтроллером предполагается использовать программатор ISP (In-System Programmer) для непосредственного программирования флеш памяти через интерфейс SPI. Здесь можно применить уже готовый программатор (usbasp, stk500, и т.д.), или использовать скетч ArduinoISP, превращающий плату ардуино в программатор ISP ("обрезанная" эмуляция stk500v1). Скетч находится в разделе "примеры" ArduinoIDE (я использую версию 1.8.16). Отдельный интерфейс для внутрисистемного программирования называют ICSP (in-circuit serial programming), в данном случае для atmega в интерфейс ICSP "вытащили" SPI (MOSI, MISO, SCK), питание (+5В, GND), и RESET. У платы на базе микроконтроллера LGT, например, в разъём ICSP "вытащен" интерфейс SWD (Serial Wire Debug). Возможность "заливать" прошивку в микроконтроллер ATmega328P через UART как раз и обеспечивает загрузчик (bootloader, расположен в самом "конце" флеш памяти)
Так получилось, что второй Arduino нет, программатора ISP по SPI нет. Есть "зеленка" (от названия фирмы - logic green) - плата в формате Arduino Nano на базе микроконтроллера LGT8F328P (почитать об отличии от ATmega328P, где взять документацию, и как работать с этим микроконтроллером можно здесь и здесь).
В продаже плата, как на Рисунке 4, появляется под разными названиями - alpha nano 3.1, просто nano и тому подобное. Отличительная особенность - на корпусе микроконтроллера отсутствует маркировка (ни разу не видел маркированного микроконтроллера от logicgreen - такой фирменный стиль экономии?). "Фирменное" программное обеспечение можно глянуть здесь.
Краткий "курс" по работе с LGT8F328P в ArduinoIDE:
ArduinoIDE: "Файл" - "Настройки" - "Дополнительные ссылки для менеджера плат" добавить дополнительные адреса репозиториев программного обеспечения:
https://raw.githubusercontent.com/dbuezas/lgt8fx/master/package_lgt8fx_index.json
(параметры конфигурации можно менять "по горячему" - частоту, eeprom, pll делитель, скорость UART) или (и)
https://raw.githubusercontent.com/nulllaborg/arduino_nulllab/master/package_nulllab_boards_index.json
- от nulllab.
Далее в менеджере плат устанавливаем необходимые пакеты (поиск по ключевым словам lgt8f или nulllab). Не забываем, что у нас внутренний тактовый генератор и корпус 32 вывода. При работе замечено, что некоторые платы корректно работают только на скорости UART 115200 - видимо дело в версии загрузчика - но перепрограммирование загрузчика на микроконтроллере LGT8F328P - другая история (программатор ISP через интерфейс SWD на базе Arduino - здесь).
"Заливаем" пример AnalogReadSerial - если в мониторе COM порта видим корректный вывод - всё работает.
Далее в "Файл"-"Примеры" берём скетч ArduinoISP, компилируем и загружаем в плату на основе LGT8F328P. Соединяем с целевой Arduino Uno (это, так называемая "старого стиля" схема подключения, подробнее здесь):
LGT8F - ArduinoUno
D10 --> RESET (сигнал сброса)
D11 --> D11 (сигнал MOSI)
D12 --> D12 (сигнал MISO)
D13 --> D13 (сигнал SCK)
GND --> GND
5V --> 5V
"Целевая" плата будет питаться от "программатора". Если Вы программируете "голый" микроконтроллер, то для корректной работы "программатора" следует "подтянуть" вывод RESET к выводу питания 5В через резистор, на плате Arduino "подтяжка" уже есть.
Теперь для записи загрузчика в микроконтроллер, установленный на плату Arduino Uno необходимо в ArduinoIDE в менеджере плат выбрать плату ArduinoUno - конфигурация IDE изменится - во флеш за программируется нужный загрузчик для ArduinoUno. В разделе "Инструменты" - "Программатор" выбираем "Arduino as ISP". Нажимаем "Записать Загрузчик". При удачном исходе дела, увидим сообщение, как на Рисунке 6.
Если, что-то пошло не так - в первую очередь смотрим на сигнатуру микроконтроллера. На Рисунке 8 - результат плохо собранной схемы - сигнатура меняется случайным образом.
На форумах иногда советуют добавить к существующему резистору "подтяжки" RESET ещё один, порядка 100 Ом, или поставить электролитический конденсатор ёмкостью около 10 мкф между RESET и GND.
Вернёмся к нашей плате. "Заливка" загрузчика не изменило поведение: горят светодиоды "TX" и "L", происходит эмуляция COM порта (!!!), через UART микроконтроллер не доступен.... Беглый "осмотр" осциллографом преобразователя интерфейса CH340G выявило отсутствие сигнала на выводах 7,8 (подключение кварцевого резонатора), дифференциальная пара (USB) D- и D+ тоже ведет себя неправильно, на D+ нормальный сигнал, D- постоянные 1В. CH340G отправился, видимо в далёкую страну вечно счастливого состояния битов и тритов. Ну, что же - это не катастрофа, и даже не беда. Демонтируем корпус - и, опс - нет в хозяйстве CH340G, а ведь когда-то закупал.... На этот случай есть два выхода - программировать с использованием ArduinoISP, используя "Скетч"-"Загрузить через программатор", или использовать внешний преобразователь USB-UART.
В первом случае при программировании микроконтроллера будет затёрт загрузчик. Это и не плохо - загрузчик занимает ресурсы контроллера. С другой стороны нет возможности вывода нужной информации в COM порт - и если это нужно, всё равно придётся "цеплять" внешний USB-UART.
Во втором случае получаем полный аналог рабочей платы Arduino (в том случае, если на преобразователе USB-TTL есть сигнал DTR, в противном случае перед прошивкой нужно будет нажимать RESET), с небольшими неудобствами в виде лишних проводов, сойдёт, как вариант, до покупки корпуса CH340G.
Вернёмся к варианту работы с ArduinoISP. Если внимательно посмотреть вывод лога программирования в ArduinoIDE, нетрудно заметить, что используется программа avrdude (документация, последние версии на github). Командная строка выглядит так:
C:\путь_до программы\avrdude -C C:\путь_до_конфигурационного_файла\avrdude.conf -v -p atmega328p -c stk500v1 -P COM3 -b 19200 -U flash:w:C:\путь_до_прошивки\прошивка.hex:i
Видно, что используется программатор skt500v1, битрейт 19200, включена верификация, а вот микроконтроллер - atmega328p, хотя в официальной версии конфигурации avrdude.conf есть только m328p (или недосмотрел?). Для упрощения работы можно просто написать пакетный файл (bat).
Неправильно было бы пройти мимо графического интерфейса avrdude - программы avrdudeprog, написанной Боднар Сергеем (сайт). Простой интерфейс, возможность гибко создавать командную строку для avrdude, делает эту программу ценной для начинающего пользователя микроконтроллеров. Для работы с программатором ArduinoISP нужно добавить программатор в конфигурационный файл programm.ini (в поле progisp после наименования программатора можно добавить ключи для avrdude):
[STK500v1]
progisp=stk500v1 -b 19200 -v
portprog=COM1
portenabled=1
После выбора в меню микроконтроллера ATmega328P и программатора STK500v1, установив порт можно пользоваться программой (осторожно с fusebits (фьюзами)! В статье намеренно обходятся вопросы по установке значения fusebits - необходимые значения fusebits устанавливает ArduinoIDE)
Для того, чтобы использовать интерфейс UART микроконтроллера применим преобразователь USB to TTL (Рисунок 10), основанный все на той же CH340G.
Перемычку надо переставить в положение Vcc-5В (стандартный уровень для Arduino). На фотографии перемычка стоит в положении 3.3В. На преобразователе отсутствует сигнал DTR (сброс), в связи с этим, в момент загрузки hex нужно нажимать RESET на плате (Рисунок 11, времени предостаточно - avrdude по умолчанию 10 раз "пинает" плату).
Соединение тоже не должно вызвать сложностей: "RXout" --> "TXin", "TXout" --> "RXin", GND -- GND (правда один раз попалась "поделка", где надписи RX и TX были "попутаны"), главное, чтобы "земля" соединялась у плат надёжно. Ну и соблюдение "гигиены" по питанию - не замыкать источники тока, если используются разные источники тока для питания платы Arduino и USB-TTL.
В таком виде можно обычным способом для пользователей Arduino загружать скетчи и иметь доступ к микроконтроллеру посредством UART интерфейса.
Плата была вручена счастливому пользователю - поставлена задача "добыть" корпус CH340G.
Спасибо за внимание к моему скромному труду. С уважением.