Пост про ATtiny13


Мій попередній пост про ATtiny13 був аж надто лаконічним.

Сама по собі ATtiny13 і є надзвичайно лаконі́чною. Та вона заслуговує на чимало слів.

Короткий вступ

Що це взагалі таке? Це один з найменших мікроконтролерів сімейства AVR, маленька мікросхема з 8 конта́ктами, з них 5 контактів вводу-виводу загального призначення.

Контакти ATtiny13, згідно з офіційною документацією

Чим саме вона цікава? Тим що маленька, дешева, мало споживає, живиться напругою від 1.8 до 5.5 В і не потребує додаткових деталей для використання.

У мене є півдюжини чипів ATtiny13A-PU (13A це один з сучасних варіантів, PU це DIP-корпус). Знайшов їх на AliExpress по ціні $0.63 за штуку (і це ще дорого, бо поштучно і у DIP-корпусі). Щодо споживання, то мої ATtiny13A чудово працюють від майже дохлої CR2032.

Які її характеристики? В неї є 5 контактів вводу-виводу, з них три обладнані 10-бітним АЦП. Ще один контакт (RESET) можна використовувати за спеціальних умов.

Всередині у неї є 1 Кб флеш-пам’яті програм, 64 байти оперативної пам’яті та 64 байти EEPROM. Так, це небагато. В такому ж самому корпусі є ATtiny45 та ATtiny85, у них більше пам’яті, але вони і коштують більше.

Що з нею можна зробити? Та дещо можна. Термостат, наприклад. Якийсь таймер. Штуку, що вмика́є світло рівно на 2 хвилини після натискання на кнопку. Штуку, що реагує на світло і рухає сервопри́вод. Ці 5 контактів загального призначення дозволяють зробити чимало.

Чи існує ще щось менше? ATtiny13 одна з найменших, але не найменша.

В сімействі AVR є лінійка ATtiny4/5/9/10. Всі ці мікросхеми ще менше (там корпус на 6 контактів замість 8, тобто доступних контактів вводу-виводу лише 3); теоретично вони дешевше, але з ними суттєво складніше (зокрема, вони інакше програму́ються).

Крім то́го, я ніколи не бачив ATtiny10 у DIP-корпусі, а такому чайнику як я DIP-корпус важливий. Мікросхему в DIP-корпусі легко пая́ти (значно легше ніж SOIC), і її можна просто встромити прямо на безпа́єчну маке́тну плату.

Окрім AVR в цій «ваговій категорії» варто згадати сімейства мікроконтролерів PIC12 та STM8, я чув що вони непогані, але ніколи з ними не працював. То є просто інший всесвіт.

І, нарешті, ось реальний хардкор: існують екзотичні, дуже дешеві мікроконтролери, з документацією переважно китайською мовою.

Програма́тор

ATtiny13 можна програмува́ти по інтерфейсу SPI. Це не єдиний метод, але найзручніший. Для цього зручно використовувати Arduino Uno чи Nano з проши́вкою ArduinoISP. І програмува́ти можна прямо в Arduino IDE.

В офіційній документації по Arduino є цікава стаття про ArduinoISP. Правда, вона більше стосується того, як прошива́ти bootloader в інші Arduino. В нашій ATtiny13 лише 1 Кб флеш-пам’яті програм, тому для bootloader’а там просто нема місця.

Більш суттєво мені допомогла́ стаття про прошивку ATtiny13.

Схема підключення ATtiny13 до Arduino Nano в ролі програма́тора

В цілому, ось що треба зробити:

  • завантажити на Arduino Nano скетч ArduinoISP з вбудованих прикладів;
  • встановити у Arduino IDE пакет MicroCore;
  • підключити ATtiny13 до Arduino Nano, як на схемі;
  • сконфігурува́ти Arduino IDE для використання плати ATtiny13;
  • сконфігурува́ти і прошити fuses;
  • завантажити прошивку через програма́тор.

Перші чотири пункти відносно прості. Далі починаються нюанси.

Fuse bits

Що взагалі таке fuses (fuse bits)? Це така низькорі́внева конфігурація мікроконтро́лера AVR, кілька біт дуже особливих параметрів. Зокрема, це частота, на якій він працюватиме (нехай буде внутрішній осцилятор на 1.2 МГц) та Brown-Out Detector, BOD (нехай буде disabled).

Це все можна обрати в меню Arduino IDE, після чого натиснути на «Burn Bootloader». Для MicroCore цей пункт меню лише виставить fuse bits і все. Якщо конфігурація не змінюється, то достатньо виконати це лише один раз.

Власне, прошивка

Ну а потім заванта́жуємо скетч на ATtiny13, тільки через пункт меню «Upload Using Programmer». Нехай для початку це буде дещо просте і дуже знайоме, а саме Blink.

void setup() {
  pinMode(4, OUTPUT);
}

void loop() {
  digitalWrite(4, HIGH);
  delay(500);
  digitalWrite(4, LOW);
  delay(500);
}

Контакт мікросхеми номер 3 відповідає порту́ 4 (PB4), і на цій схемі до нього підключений світлодіо́д. Якщо все зробити правильно, то одразу після завантаження прошивки ATtiny13 почне їм блимати.

Після прошивки

Коли прошивка завантажена, мікроконтро́леру для роботи потрібні тільки земля та живлення. Ну, і що ми там підключили — світлодіо́д?

Схема з ATtiny13 та світлодіо́да

Прикольно, правда? Маленька самодостатня схема.

Оптимізація

Скетч, що наведено вище, в моїй Arduino IDE 2.0.4 нині «важить» 90 байт. Непогано. Але кілька версій тому такий самий Blink з’їдав більше 300 байт з доступних 1024.

Але, на щастя, це можна дещо скоротити.

#include <avr/io.h>
#include <util/delay.h>

int main(void) {
  DDRB = 1<<PB4;
  PORTB = 0x0;

  while (1) {
    PORTB ^= 1<<PB4;
    _delay_ms(250);
  }
}

Так, це вам не звичні pinMode / digitalWrite. Тут треба читати документацію.

В такому варіанті скетч важить 72 байти. Його можна написати і скомпілю́вати безпосередньо в Arduino IDE. Можливо, з використанням асе́мблеру можна скоротити Blink ще сильніше, але то для ме́не занадто.

Те саме, тільки без Arduino IDE

Мені якось потрапив у руки приклад, як прошива́ти ATtiny13 з avr-gcc та avrdude.

avr-gcc -g -DF_CPU=1200000 -Wall -Os -mmcu=attiny13a -c -o blink.o blink.c
avr-gcc -g -DF_CPU=1200000 -Wall -Os -mmcu=attiny13a -o blink.elf blink.o
avr-size blink.elf
avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex

Встановлення fuses досить небезпечне і потребує спеціального калькулятора fuse bits. Пам’ятайте головне: біт RSTDISBL має бути вимкненим, а SPIEN має бути уві́мкненим, інакше мікроконтро́лер перетвориться на цегли́ну.

avrdude -p attiny13 -P /dev/ttyUSB0 -c stk500v1 -b 19200 -q -U hfuse:w:0xff:m -U lfuse:w:0x6a:m

І, власне, прошивка.

avrdude -p attiny13 -c stk500v1 -P /dev/ttyUSB0 -b 19200 -q -U flash:w:blink.hex

TL;DR:

Опанувати крихітний простий мікроконтро́лер значно складніше, ніж потужний монстр з MicroPython’ом.