Введение
В этой статье я разберу базовые приемы работы с новыми (2018-2019) микроконтроллерами компании Microchip серий tinyAVR. Конкретно мне удалось приобрести ATtiny202, ATtiny402 (tinyAVR-0) и ATtiny424 (tinyAVR-2), так как во время заказа месяц назад они стоили 75-88 рублей/штука, что было значительно дешевле старых атмеловских серий ATtiny25-ATtiny85 и ATtiny24-ATtiny84. Что конкретно удастся приобрести вам в связи с санкционной ситуацией я не знаю, поэтому эта статья скорее на будущее. Тем не менее, я считаю важной ее написать по той причине, что в интернете на данный момент отсутствует адекватное и простое описание работы с микроконтроллерами серий tinyAVR и AVR Xmega на русском языке. Ведь фреймворк для tinyAVR-0/tinyAVR-1/tinyAVR-2 и AVR Xmega сильно отличается от классического AVR. Рано или поздно китайцы начнут клонировать новые серии микроконтроллеров, потому что последние обладают несомненными преимуществами перед старыми сериями.
Цоколевка
Все микроконтроллеры tinyAVR-0/tinyAVR-1/tinyAVR-2 имеют первую ножку VDD (питание) и последнюю GND (землю), что очень удобно для взаимозаменяемости. Также все эти микроконтроллеры имеют наиболее распространенный узкий корпус SOIC-8/SOIC-14/SOIC-20 150 mil в отличие от ATtiny25-ATtiny85, имеющих более редкий широкий корпус SOIC-8 208mil. Оба этих решения просто замечательные.
Программатор
Для программирования используется трехпроводной интерфейс UPDI вместо шестипроводного AVR-ICSP. Видно, что Microchip пытается сохранить какую-то преемственность, но не совсем понятно, зачем она нужна, так как UPDI гораздо ближе к UART, чем к AVR-ICSP. Последним умельцы успешно и пользуются, применяя USB-TTL (UART) программаторы для UPDI.

Почему это происходит? Потому что удешевив производство микроконтроллеров Microchip решили заработать на продаже программаторов. Само собой, UPDI поддерживают только их Atmel ICE и PICkit 4, а также другие менее распространенные и еще более дорогие программаторы.
Результат не заставил себя долго ждать.
На основе Arduino Nano:
- DIY Arduino Nano HV UPDI Programmer
- Arduino Nano HV UPDI Programmer
- DIY HV UPDI Programmer
- Using the new ATtiny Processors with Arduino IDE © GPL3+
- DIY UPDI Programmer for Mega 4808
- Программируем в Arduino IDE микроконтроллеры ATtiny417, ATtiny817, ATtiny1604, ATtiny402, ATTiny1614, ATtiny3216 и другие
На основе Pro Micro:
На основе FTDI:
На основе USB/TTL (UART)
- Простой и недорогой способ программирования AVR ATtiny214, ATtiny414, ATtiny814 и Atmega через интерфейс UPDI
- Программатор для нового семейства tinyAVR на базе дешевого китайского конвертера CH340
На мой взгляд последний способ является наиболее рациональным исходя из трудозатрат и стоимости.
Для всех перечисленных самодельных программаторов характерна следующая особенность: пригодны только для припаянного микроконтроллера. То есть или припаиваешь его непосредственно на целевую плату, потом программируешь, или припаиваешь на переходник SOIC-DIP, потом отпаиваешь, или используешь измерительные щупы.
Для самодельных программаторов написано много софта, позволяющего работать с UPDI:
- SpenceKonde / megaTinyCore
- SpenceKonde / jtag2updi
- mraardvark / pyupdi
- Polarisru / updiprog
- microchip-pic-avr-tools / pymcuprog
Я решил сделать свой программатор, который сочетает в себе возможность программирования на плате и с помощью адаптеров для программирования SOIC-8 и SOIC-16 (150 mil).
Электрическая схема и разводка представлены на следующем изображении.
В качестве USB/TTL адаптера использовался удобный и дешевый модуль CH340E BTE17-06. Footprint и библиотеку для этого модуля в KiCad 6 мне пришлось сделать самостоятельно.

Некоторые из этапов производства показаны на коллаже.
Результат:
Среды для программирования
К сожалению я не смог найти способа быстро и удобно программировать и загружать код в tinyAVR-0/tinyAVR-1/tinyAVR-2 в одной среде. В используемом мной Code::Blocks просто не было предустановок для этих микроконтроллеров, а загрузка кода требует среды, поддерживающей python.
Поскольку я ранее уже работал с микроконтроллерами PIC, на моем ноутбуке уже была установлена linux-версия MPLAB X IDE. Это одна из двух сред, из коробки поддерживающих микроконтроллеры новых серий. Также вы можете использовать Microchip Studio (ранее Atmel Studio), но она есть только под Windows, поэтому мой выбор был предрешен, хотя Atmel Studio 7 я и пробовал ранее.
Для загрузки кода я использовал PyCharm Community Edition, которая также была у меня установлена в силу наличия 12-летнего опыта общения с питоном.
Здесь есть описание того, как работать с библиотекой mraardvark / pyupdi, но, к сожалению, оно является поверхностным, и для начинающих не подходит, поэтому я напишу подробнее. Вообще говоря, современная работа с питоном стала иметь довольно высокий порог вхождения. Не такой высокий, как у jаvascript, но с ходу все равно не разберешься. И все советы типа "установил и запустил" сейчас являются лукавством. Как минимум, если вы работаете под Linux, вам сам терминал после обновления pip под sudo скажет: "Работай в контейнере, падаван йуный, иначе нарушить работу системы можешь ты". А работа в контейнере это, извините, уже...
Особенности программирования микроконтроллеров tinyAVR-0/tinyAVR-1/tinyAVR-2 и AVR Xmega
Здесь необходимо ненадолго отвлечься и описать базовые принципы программирования новых серий микроконтроллеров Microchip, иначе просто невозможно будет написать код.
Я нашел по сути всего одну статью, в которой просто и адекватно описаны основные отличия от классического AVR. Здесь я приведу выдержки из нее. Также воспользуемся официальным гайдом Microchip.
Итак, разберем на примере имеющегося микроконтроллера ATtiny402. Мы имеем вывод PA6 и хотим использовать его для мигания светодиодом. Сначала мы должны его перевести в режим OUTPUT. Так бы мы это сделали в классическом AVR (сверху) и в tinyAVR-0/tinyAVR-1/tinyAVR-2 (снизу).
bp - это bit positions, bm - это bit masks. Здесь и далее вместо символов побитового сдвига (две открывающие треугольные скобки) будет kk, потому что первые рушат разметку на этом ресурсе.
DDRA |= (1 kk 6); или DDRA |= _BV(PA6);
PORTA.DIRSET = PIN6_bm;
Установка в режим INPUT:
DDRA &= ~ (1 kk 6); или DDRA &= ~ _BV(PA6);
PORTA.DIRCLR = PIN7_bm;
Установка HIGH:
PORTA |= (1 kk 6); или PORTA |= _BV(PA6);
PORTA.OUTSET = PIN6_bm;
Установка LOW:
PORTA &= ~ (1 kk 6); или PORTA &= ~ _BV(PA6);
PORTA.OUTCLR = PIN6_bm;
Также появились две полезные функции. Первая определяет статус вывода (высокий или низкий):
bool status = PORTA.IN & PIN6_bm;
Вторая переключает состояние исходя из текущего (toggle):
PORTA.OUTTGL = PIN6_bm;
Несомненно, код стал читабельнее, удобнее и человекообразнее, но одна вещь все-таки бесит. PIN6 - это здесь не пин, а просто вывод PA6, а по порядку и в Arduino это физический пин 2.
Также важно упомянуть следующую вещь. Фьюзов, как и в большинстве современных микроконтроллеров (LGT8F, STM32) здесь нет. Вместо этого базовые настройки микроконтроллера устанавливаются с помощью функции _PROTECTED_WRITE(arg1, arg2), в качестве аргументов в которую передается имя регистра и предопределенная установка. Например, установка частоты микроконтроллера 20 МГц на внутреннем осцилляторе выглядит вот так:
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
Создание проекта в MPLAB X IDE
Непосредственно код мы будем писать в MPLAB X IDE, как и договорились ранее. Сначала создаем новый Standalone проект.
Затем выбираем из выпадающего списка наш микроконтроллер ATtiny402.
Выбираем toolchain XC8 (для восьмибитных микроконтроллеров microchip).
Выбираем имя проект и локацию. Имя проекта потом можно изменить, в отличие от KiCad например, а имя локации уже не получится.
Добавляем в Source Files файл main.c.
И помещаем в него следующий код:
/*
* File: main.c
* Author: alex
*
* Created on 6 ????? 2022 ?., 19:00
*/
#include "xc.h"
#ifndef F_CPU
#define F_CPU 3300000UL // 20 MHz clock speed / 6 prescaler
#endif
#include "util/delay.h"
#include "avr/io.h"
int main(void)
{
/* Set the Main clock to internal 20MHz oscillator*/
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
/* Set the Main clock division factor to 6X and keep the Main clock */
/* prescaler enabled. */
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_6X_gc | CLKCTRL_PEN_bm);
/* Configure Port A, Pin 6 as an output (remember to connect LED to PB6 */
/* and use a resistor in series to GND)*/
PORTA.DIRSET = PIN6_bm;
while(1){
PORTA.OUTTGL = PIN6_bm; // toggle PA6 output
_delay_ms(1000); // wait for 1000 milliseconds
}
}
Кавычки в include замените на треугольные скобки. Комментировать в этом коде, в общем-то, нечего. Это blink ногой PA6 на частоте 20 МГц с делителем 6.
После нажатия на кнопку "Build Main Project" получаем следующий вывод:
Скомпилированный файл у меня оказался в:
/home/alex/MPLABXProjects/attinyAVR0/attiny402.X/dist/default/production/attiny402.X.production.hex
Подготовка USB-порта
Сначала подключаем программатор и смотрим название нашего USB-порта. Проще всего его посмотреть в Arduino IDE. Если он называется /dev/ttyUSB0 или /dev/ttyUSB1, то значит все в порядке. А если /dev/ttyS0, то значит беда, и вы при попытке писать в USB-порт от своего имени будете получать что-то типа:
SerialException: Could not open port /dev/ttyS0 [Errno 13] Permission denied: '/dev/ttyS0'
Для исправления этой несправедливости следует выполнить следующую команду в терминале, где $USER - это ваше имя пользователя. Эта команда добавляет вас в группу dialout, нахождение в которой дает доступ к USB-порту (в том числе). После этого необходимо перезагрузить компьютер.
sudo usermod -a -G dialout $USER
Также у вас в
/etc/udev/rules.d/
должен находиться файл 99-platformio-udev.rules или 70-snap.core.rules или любой другой *.rules, в котором должна быть строчка типа такой:
# QinHeng Electronics HL-340 USB-Serial adapter
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
Если такого файла нет, то создайте его, иначе наш программатор не получит прав доступа.
Если у вас другой TTL/USB преобразователь, то idVendor и idProduct к нему можно посмотреть с помощью команды lsusb.
Создание проекта в PyCharm Community Edition и загрузка кода
Предупреждение: далее у меня папка pyupdi-master находится в папке attiny204. Это просто потому, что я сначала ошибся с названием папки.
Итак, наши действия по подготовке проекта pyupdi для обеспечения работоспособности программатора. Скачиваем проект pyupdi-master.zip с гитхаба и распаковываем в любую папку с обычными правами доступа. Открываем PyCharm и создаем проект на основе этой папки. Виртуальное окружение выбираем pipenv.
Если вылезает какое-то такое сообщение, то выбираем интерпретатор (например, python3.9) еще раз.
В итоге мы должны увидеть что-то типа этого
После этого в свойствах проекта устанавливаем три библиотеки: pylint, intelhex и pyserial (из requirements.txt).
Далее из папки pyupdi-master/updi/ переносим в папку pyupdi-master файлы pyupdi.py и __init__.py. Видимо они не в корне, потому что автор подготовил проект к установке в виде библиотеки, что нам совершенно не нужно. Иначе мы получим что-то типа такого:
В эту же папку мы копируем файл attiny402.X.production.hex. После этого проект можно считать подготовленным к тому, чтобы выполнить команду для загрузки файла в микроконтроллер через программатор. Если вы выполняете команды через IDE, то первые две команды выполнять не нужно, потому что IDE и так работает в рабочем каталоге и виртуальном окружении.
cd ~/MPLABXProjects/attinyAVR0/pyupdi-master/
pipenv shell
python pyupdi.py -d attiny402 -c /dev/ttyUSB0 -b 9600 -f attiny402.X.production.hex

Проверка работоспособности кода
Ерундой типа подключения лампочек мы заниматься не будем, а просто приложим щупы мультиметра к GND и PA6, чтобы проследить изменение напряжения раз в секунду.
Заключение
Итак, мы узнали, что микроконтроллеры tynyAVR0-2 обладают следующими достоинствами:
- имеют удобные корпуса и цоколевку;
- прошиваются через трехпроводной интерфейс UPDI, что гораздо проще в реализации, чем ICSP;
- несомненно имеют более удобный фреймворк для программирования с человеческими командами по сравнению с AVR;
- имеют более высокую частоту внутреннего осциллятора (20 МГц по сравнению с 8 МГц).
И имеют два недостатка:
- китайцы их пока не скопировали;
- оригинальные программаторы для них безумно дороги, что вынуждает заниматься художественной самодеятельностью.
В рамках данной статьи я не рассматривал пока непосредственно ATtiny424, потому что ее объем и так получился безумным. Тем не менее, работа с этим микроконтроллером не сильно отличается от уже описанного. ATtiny202 - это тот же ATtiny402, просто с меньшей памятью.
Ссылки на мои проекты, упомянутые в данной статье:
UPDI-Programmer (KiCad 6)
Проекты MPLAB X IDE и PyCharm (pyupdi)