- PVSM.RU - https://www.pvsm.ru -

Как и зачем читать даташиты, если микроконтроллеры – ваше хобби

Как и зачем читать даташиты, если микроконтроллеры – ваше хобби - 1

Микроэлектроника – модное увлечение последних лет благодаря волшебному Arduino. Но вот беда: при должном интересе перерасти DigitalWrite() получается быстро, а что делать дальше – не совсем ясно. Разработчики Arduino приложили немало усилий для снижения порога вхождения в свою экосистему, но за ее пределами по-прежнему колышется темный лес суровой схемотехники, малодоступный любителю.

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

В этой статье я поделюсь опытом общения гуманитария с даташитами в хобби-целях. Текст предназначен для выросших из штанишек Arduino любителей, он предполагает некоторое представление о принципах работы микроконтроллеров.

Начну с традиционного

Мигаем светодиодом на Ардуино

И сразу код:

void setup() {
DDRB |= (1<<5);
}

void loop() {
PINB = (1<<5);
for (volatile uint32_t k=0; k<100000; k++);
}

«Что это? – Спросит искушенный читатель. – Зачем ты что-то пишешь во входной регистр PINB? Он же только для чтения!» Действительно, документация Arduino [1], как и большинство учебных статей в интернете, утверждает, что этот регистр read-only. Я и сам так думал, пока не перечитал даташит [2] к Atmega328p, готовя это статью. А там:

Как и зачем читать даташиты, если микроконтроллеры – ваше хобби - 2

Это относительно новый функционал, его не было на Atmega8, о нем не все знают или не упоминают из соображений обратной совместимости. Но вполне годный для демонстрации мысли, что даташиты стоит читать, чтобы использовать все возможности чипа, включая малоизвестные. И это не единственная причина.

Зачем еще читать даташиты

Обычно ардуинщики, наигравшись со светодиодами и AnalogWrite'ами, начинают подключать к плате всякие модули и чипы, для которых есть уже написанные библиотеки. Рано или поздно появляется библиотека, работающая не так, как надо. Тогда любитель начинает ее ковырять, чтобы починить, а там...

А там происходит что-то категорически непонятное, поэтому приходится отправляться в гугл, читать многочисленные тьюториалы, дергать по частям чей-то подходящий код и наконец добиваться своего. Это дает мощное ощущение свершения, но на самом деле процесс напоминает изобретение велосипеда путем реверс-инжиниринга мотоцикла. Причем понимания, как работает этот велосипед, не прибавляется. Знаю, поскольку сам этим занимался довольно долго.

Если бы я вместо этого увлекательного занятия потратил пару дней на изучение документации к Atmega328, я бы сэкономил огромное количество времени. В конце концов, это довольно простой микроконтроллер.

Таким образом, читать даташиты надо хотя бы для того, чтобы представлять себе, как вообще устроен микроконтроллер и что он умеет делать. И еще:

  • чтобы проверять и оптимизировать чужие библиотеки. Их часто пишут такие же любители, изобретающие велосипед; или же, напротив, авторы намеренно делают в них избыточную защиту от дурака. Пусть будет в три раза больше и медленнее, зато точно сработает;
  • чтобы иметь возможность использовать в проекте чипы, к которым никто не написал библиотеку;
  • чтобы облегчить себе задачу по миграции с одной линейки МК на другую;
  • чтобы наконец оптимизировать свой старый код, который никак не влезал в Ардуину;
  • чтобы научиться управлять любым чипом напрямую через его регистры, не заморачиваясь изучением устройства его библиотек, если таковые вообще есть.

Зачем писать в регистры напрямую, когда есть HAL и LL?

Словарик
HAL, High Abstraction Layer – библиотека для управления микроконтроллером с высоким уровнем абстракции. Если надо использовать интерфейс SPI1, просто настраиваем и включаем SPI1, не задумываясь, какие регистры за что отвечают.
LL, Low Level API – библиотека, содержащая макросы или структуры с адресами регистров, позволяющая обращаться к ним по имени. DDRx, PORTx, PINx на Атмеге – это LL.

Споры на тему «HAL, LL или регистры» регулярно случаются в комментариях на Хабре. Не претендуя на доступ к астральному знанию, просто поделюсь своим любительским опытом и соображениями.

Более-менее разобравшись с Атмегой и начитавшись статей про прекрасности STM32, я накупил полдюжины разных плат – и Discovery, и «Синие Таблетки», и даже просто чипы под свои самоделки. Все они два года пылились в коробке. Иногда я говорил себе: «все, с этих выходных осваиваю STM», запускал CubeMX, генерил сетап для SPI, смотрел на получившуюся стену текста, обильно сдобренную копирайтами STM, и решал, что это как-то уж слишком.

Как и зачем читать даташиты, если микроконтроллеры – ваше хобби - 3

Разобраться, что тут понаписал CubeMX, конечно, можно. Но одновременно понятно, что запомнить все формулировки, чтобы потом писать их руками, нереально. А уж дебажить это, если я случайно забуду в Кубе поставить какую-нибудь галочку, – совсем привет.

Прошло два года, я по-прежнему облизывался в ST MCU Finder [3] на всякие вкусные, но недоступные моему пониманию чипы, и случайно наткнулся на замечательную статью [4], пусть и про STM8. И внезапно понял, что все это время стучался в открытую дверь: регистры у STM устроены так же, как у любого другого МК, и для работы с ними Куб необязателен. А что, так можно было?..

HAL и конкретно STM32CubeMX – инструмент для профессиональных инженеров, плотно работающих с чипами STM32. Главная фишка – высокий уровень абстракции, возможность быстро мигрировать с одного МК на другой и даже с одного ядра на другое, оставаясь в рамках линейки STM32. Любители с такими задачами сталкиваются редко – наш выбор МК, как правило, ограничен ассортиментом AliExpress, и мы чаще мигрируем между кардинально разными чипами – переезжаем с Атмеги на STM, с STM на ESP, ну или что там нам новенького подкинут китайские друзья. HAL здесь не поможет, а времени его изучение съест немало.

Остается LL – но от него до регистров полшага. Лично я нахожу написание своих макросов с адресами регистров полезным: я внимательнее изучаю даташит, думаю, что мне потребуется в будущем, а что точно нет, лучше структурирую свои программы, ну и вообще преодоление способствует запоминанию.

Кроме того, есть нюанс с популярным STM32F103 – для него существуют две несовместимые версии LL, одна официальная от STM, вторая – от Leaf Labs, используемая в проекте STM32duino. Если писать open-source библиотеку (а у меня была именно такая задача [5]), надо либо делать две версии, либо обращаться к регистрам напрямую.

Наконец, отказ от LL, на мой взгляд, упрощает миграцию, особенно если закладываться на нее с самого начала работы над проектом. Утрированный пример: напишем ардуиновский blink в Atmel Studio без LL:

#include <stdint.h>

#define _REG(addr) (*(volatile uint8_t*)(addr))

#define DDR_B 0x24
#define OUT_B 0x25

int main(void)
{
    volatile uint32_t k;

    _REG(DDR_B) |= (1<<5);

    while(1)
    {
        _REG(OUT_B) |= (1<<5);
        for (k=0; k<50000; k++);
        _REG(OUT_B) &= ~(1<<5);
        for (k=0; k<50000; k++);
    } 
}

Чтобы этот код замигал светодиодом на китайской платке с STM8 (из ST Visual Desktop), в нем достаточно поменять два адреса:

#define DDR_B 0x5007
#define OUT_B 0x5005

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

Какие бывают даташиты

В статьях и на форумах, и русско-, и англоязычных, под «даташитами» понимают любую техническую документацию к чипам, так же поступаю и я в этом тексте. Формально они – лишь один из видов такой документации:

Datasheet – ТТХ, тактико- технические характеристики. Обязательно имеется у любого электронного компонента. Справочная информация, полезно держать под рукой, но вдумчиво читать в нем особо нечего. Впрочем, чипы попроще часто ограничиваются даташитом, чтобы не плодить лишних документов; в этом случае Reference Manual включается сюда же.

Reference Manual – собственно инструкция, здоровая книжка на 1000+ страниц. Подробно расписывается работа всего, что понапихано в чип. Главный документ для освоения микроконтроллера. В отличие от datasheet, инструкции пишут для широкой линейки МК, в них содержится много информации о периферии, отсутствующей в вашей конкретной модели.

Programming Manual или Instruction Set Manual – инструкция по уникальным командам микроконтроллера. Предназначена для тех, кто программирует на Ассемблере. Авторы компиляторов активно ее используют для оптимизации кода, поэтому в общем случае нам она не потребуется. Но заглядывать сюда полезно для общего понимания, за некоторыми специфическими командами типа выхода из прерывания, а также при активном использовании дебаггера.

Application Note – полезные советы по решению конкретных задач, часто с примерами кода.

Errata Sheet – описание случаев нестандартного поведения чипа с вариантами обхода, если есть.

Что есть в даташитах

Непосредственно в Datasheet нам могут потребоваться такие разделы:

Device Summary – первая страница даташита вкратце рассказывает об устройстве. Очень полезна в ситуациях, когда вы где-то нашли чип (увидели в магазине, выпаяли, встретили упоминание) и хотите понять, что это.

General Description – более подробное описание возможностей чипов из линейки.

Pinouts – схемы распиновки для всех возможных корпусов чипа (на какой ноге какой пин).

Pin Description – описание назначения и возможностей каждого пина.

Memory Map – карта адресов в памяти нам вряд ли потребуется, но иногда в нее включается также таблица адресов блоков регистров.

Register Map – таблица адресов блоков регистров, как правило, находится именно в даташите, а в Ref Manual – только сдвиги (address offsets).

Electrical Characteristics – в этом разделе нас в первую очередь интересуют absolute maximum ratings, перечисляющие максимальные нагрузки на чип. В отличие от неубиваемой Atmega328p, большинство МК не позволяет подключать к пинам серьезные нагрузки, что становится неприятным сюрпризом для ардуинщиков.

Package Information – чертежи доступных корпусов, полезные при проектировании своих плат.

Reference Manual структурно состоит из разделов, посвященных конкретной периферии, указанной в их заголовке. Каждую главу можно условно поделить на три части:

Overview, Introduction, Features – обзор возможностей периферии;

Functional Description, Usage Guide или просто основной блок раздела – подробное текстовое описание принципов устройства периферии и способов ее использования;

Registers – описание управляющих регистров. В простых случаях типа GPIO или SPI этого может быть вполне достаточно, чтобы начать использовать периферию, но часто приходится все-таки читать и предыдущие части.

Как читать даташиты

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

Установите хорошую PDF-читалку. Даташиты пишутся в славных традициях бумажных инструкций, их здорово распечатать, проложить пластиковыми закладками и сшить. Гипертекст в них наблюдается в следовых количествах. К счастью, хотя бы структуру документа оформляют закладками, поэтому годная читалка с удобной навигацией очень нужна.

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

Даташиты, особенно Reference Manuals, могут описывать возможности не конкретного чипа, а всей линейки. Это значит, что половина, а то и две трети информации не имеет отношения к вашему чипу. Прежде чем изучать регистры TIM7, проверьте в General Description, есть ли он у вас.

Знать английский достаточно на базовом уровне. Даташиты наполовину состоят из терминов, незнакомых среднестатистическому носителю языка, и наполовину – из простых связующих конструкций. Еще бывают прекрасные китайские даташиты на китайском английском, где половина также термины, а вторая половина – рандомный набор слов.

Если встречаете незнакомое слово, не пытайтесь перевести его с помощью англо-русского словаря. Если вас ставит в тупик hysteresis, то от перевода «гистерезис» теплее вам не станет. Пользуйтесь Гуглом, Stack Overflow, Википедией, форумами, где нужное понятие будет объяснено простыми словами с примерами [6].

Лучший способ понять прочитанное – проверить в деле. Поэтому держите под рукой отладочную плату, с которой знакомитесь, а лучше две – на случай, если все-таки что-то недопоняли и увидели волшебный дымок.

Полезна привычка держать под рукой даташит, когда вы читаете чей-то тьюториал или изучаете чужую библиотеку. Вполне возможно, в нем вы найдете более оптимальное решение своей задачи. И наоборот – если из даташита никак не удается понять, как же все-таки работает регистр, загуглите его: скорее всего, кто-то уже все описал простыми словами или оставил понятный код на ГитХабе.

Словарик

Немного полезных слов и обозначений, помогающих быстрее освоиться с даташитами. То, что вспомнилось в последние пару дней, дополнения и исправления приветствуются.

Электричество
Vcc, Vdd – «плюс», питание
Vss, Vee – «минус», земля
current – ток
voltage – напряжение
to sink current – работать «землей» для внешней нагрузки
to source current – питать внешнюю нагрузку
high sink/source pin – пин с повышенной «терпимостью» к нагрузке

IO
H, High – на пине Vcc
L, Low – на пине Vss
High Impedance, Hi-Z, floating – на пине ничего нет, «высокое сопротивление», он фактически невидим внешнему миру.
weak pull up, weak pull down – встроенный подтягивающий/стягивающий резистор, примерный аналог 50 кОм (см. даташит). Используется, например, чтобы входной пин не болтался в воздухе, вызывая ложные срабатывания. Weak – потому что его легко «перебить».
push pull – выходной режим пина, в котором он переключается между High и Low – обычный OUTPUT с Arduino.
open drain – обозначение выходного режима, в котором пин может быть либо Low, либо High Impedance / Floating. При этом почти всегда это не «настоящий» открытый сток, есть защитные диоды, резисторы, еще что. Это просто обозначение режима земля/ничего.
true open drain – а вот это уже настоящий открытый сток: пин напрямую ведет в землю, если открыт, или пребывает в подвешенном состоянии, если закрыт. Это значит, что через него при необходимости можно пускать напряжение больше Vcc, но максимум все равно оговаривается в даташите в разделе Absolute Maximum Ratings / Voltage.

Интерфейсы
in series – подключенные последовательно
to chain – собирать чипы в цепочку последовательным подключением, увеличивая количество выходов.
shift – сдвиг, обычно обозначает сдвиг битов. Соответственно, to shift in и to shift out – принимать и передавать данные побитно.
latch – задвижка, прикрывающая буфер, пока через него сдвигаются биты. Когда передача закончена, задвижка открывается, биты начинают работать.
to clock in – выполнить побитную передачу, сдвинуть все биты на нужные места.
double buffer, shadow register, preload register – обозначения истории, когда регистр должен уметь принимать новые данные, но придерживать их до какого-то момента. Например, для корректной работы ШИМ его параметры (скважность, частота) не должны меняться, пока не закончится текущий цикл, но новые параметры уже могут быть переданы. Соответственно, текущие держатся в shadow register, а новые попадают в preload register, будучи записанными в соответствующий регистр чипа.

Всякое
prescaler – предделитель частоты
to set a bit – установить бит в 1
to clear/reset a bit – сбросить бит в 0 (reset – фишка даташитов STM)

Что дальше

Вообще тут планировалась практическая часть с демонстрацией трех проектов на STM32 и STM8, выполненных специально для этой статьи при помощи даташитов, с лампочками, SPI, таймерами, ШИМом и прерываниями:

Как и зачем читать даташиты, если микроконтроллеры – ваше хобби - 4

Но текста получается многовато, поэтому проекты отправляются во вторую часть.

Навык чтения даташитов поможет вам с вашим хобби, но едва ли заменит живое общение с коллегами по увлечению на форумах и в чатах. Для него надо все-таки в первую очередь подтягивать английский язык. А потому дочитавшим – специальный приз: два бесплатных урока в Skyeng при первой оплате по коду HABR2.

Автор: Ontaelio

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/arduino/315855

Ссылки в тексте:

[1] документация Arduino: https://www.arduino.cc/en/Reference/PortManipulation

[2] даташит: http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf

[3] ST MCU Finder: https://play.google.com/store/apps/details?id=fr.appsolute.st&hl=ru

[4] замечательную статью: https://lujji.github.io/blog/bare-metal-programming-stm8/

[5] такая задача: https://github.com/Ontaelio/DMdriverSTM32F1

[6] объяснено простыми словами с примерами: https://stackoverflow.com/questions/5357918/what-does-hysteresis-mean-and-how-does-it-apply-to-computer-science-or-programmi

[7] Источник: https://habr.com/ru/post/449624/?utm_campaign=449624