Tamper rtc что это

STM32 fast start. Часть 1 ПО, материалы, Cube MX

В последнее время все чаще сталкиваюсь с холиварами на тему Cube MX и HAL, применительно к контроллерам STM32.

С одной стороны — стоят защитники, которым нравится удобство конфигурирования и читаемость кода.

С другой — приверженцы писать все руками, которым важна скорость работы и бережное использование ресурсов.

Для того, чтобы расставить все точки над i — попробуем написать «Hello world» тремя наиболее часто используемыми путями CMSIS, LL, HAL. Оценим затраты (ресурсы контроллера, объем исполняемого файла, и конечно же время работы разработчика).

Статья будет состоять из нескольких частей:

STM32 fast start. Часть 1 ПО, материалы, Cube MX.
STM32 fast start. Часть 2 Hello World на HAL, настройка отладки в Atollic TrueSTUDIO
STM32 fast start. Часть 3 Hello World на LL
STM32 fast start. Часть 4 Hello World на CMSIS
STM32 fast start. Часть 5 Подведение итогов, сравнение HAL, LL, CMSIS.

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

Идеальным вариантом будет бюджетная плата на STM32F103C8T6 микроконтроллере.

image

Данную плату можно найти на всем известном сайте по цене от 100 российских рублей.

Искать по ключевым словам: STM32F103C8T6 ARM STM32 Minimum

Для того, чтобы залить прошивку и поиграть с отладкой — так же потребуется программатор
Для начала, да и для дальнейшего использования идеально подойдет китайский клон программатора ST-LINK V2.

Купить можно на том же сайте по цене от 120 российских рублей.

image

Искать по ключевым словам ST LINK Stlink ST 252dLink V2 Mini STM8 STM32:

Для разработки ПО под STM32 можно использовать различные IDE.

Самые популярные — IAR, Keil, Coocox (Eclipse).

Мы же пойдем по пути, который с недавних пор абсолютно бесплатно и в полном объеме предоставляет сама ST.

Будем использовать Atollic TrueSTUDIO for STM32 или в простонародии «Толик».

Какие плюсы у данного ПО: абсолютно бесплатно, нет ограничения по размеру кода, есть неплохой отладчик, простая установка и настройка.

Минусы: нет авто дополнения кода.

Доступны версии под windows и linux.

Качаем здесь https://atollic.com/resources/download/
С установкой данного ПО проблем возникнуть не должно, все интуитивно понятно, выбираем куда ставить и жмем все время «далее».

После установки можно не запускать, так как помимо самой IDE нужно еще кое что.

Если все таки запустили — просто закрываем.

Так как TrueSTUDIO — это средство разработки и отладки, хотелось бы не собирать проект руками (подключая требуемые библиотеки и прописывая пути), а получить некий преднастроенный файл, в котором можно без лишних заморочек сразу же писать код.

Для этого применяется программа генератор кода Cube MX или в простонародии «Калокуб».
Данное ПО является первым камнем преткновения в холиварах на чем же писать под STM: на регистрах и CMSIS или на HAL.

Защитники первой идеологии приводят такие аргументы: Cube MX генерирует огромный, ненужный объем кода, который к тому же замедляет работу МК.

Защитники второй — заявляют, что автоматически сгенерированный код сокращает время разработки, позволяя разработчику быстрее переключится к сутевой части устройства (к основной логике), отдав рутинную настройку периферии на откуп специализированному ПО (Cube MX).

Как ни странно — обе эти идеологии правдивы и применимы на практике, но только каждая в своих условиях.

Давайте рассмотрим пару примеров:

Пример №1: Требуется разработать устройство, максимально дешевое, так как планируется производство партиями по 100500 шт ежегодно. Естественно, каждый лишний рубль цены устройства — выльется в сотни тысяч рублей затрат на финальном устройстве. При этом в планируемой разработке есть пара тяжелых расчетов и работа с периферией (ADC, SPI, UART) на максимальных скоростях.

Устройство является полностью автономным продуктом, в дальнейшем планируется минимальные изменения за весь срок производства данного оборудования. Срок разработки до получения готового образца — 1-2 года.

Пример №2: Требуется прототип устройства, который возможно заинтересует заказчика и он закажет 100 шт аналогичных устройств для переоборудования своего объекта. Первая планируемая партия должна быть отгружена заказчику через 2 месяца. Размер первой тестовой партии 10 шт.

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

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

Во втором примере — выбор контроллера обусловлен имеющимся в наличии железом, а так же затратами времени для написания функционала требуемого заказчиком. Поэтому скорость работы и оптимизированность самого ПО отходит на второй план. Времени на ручную инициализацию нет, как нет времени и на проработку аппаратных зависимостей.

В таком случае выбирается контроллер, который можно быстро поставить в производство в текущем регионе, на нем делается инициализация с помощью Cube MX, пишется прикладная логика на HAL и прототип передается заказчику для тестирования. Такой проект может вести любой средний разработчик, который постиг навыки работы с целевым языком программирования. Вникание в тонкости работы периферии — практически не требуются.

Как бы это не печально звучало — в реалиях современной разработки устройств в России — пример №1 встречается все реже, передавая эстафету примеру №2.

К обсуждению примеров №1 и №2 вернемся в самом конце цикла статей, а сейчас продолжим с подготовкой рабочего пространства.

На данном этапе сделаем небольшую паузу, зайдем на сайт my.st.com и зарегистрируем на нем учетную запись, так как политика компании ST не позволяет скачивать необходимые материалы без регистрации.

После того, как у нас появился доступ к сайту — скачиваем STM32 Cube MX.

В самом низу страницы есть кнопка выбора версии, нам нужна версия 5.0.0

image

Попутно, пока мы не ушли отсюда, качаем еще две вещи, которые пригодятся в дальнейшем
https://www.st.com/en/development-tools/stsw-link008.html

Драйвер ST-LINK V2

image

image

Установка драйвера, прошивальщика и самого Cub’a не вызывают затруднений, просто соглашаемся со всем и жмем далее.

После полной установки необходимого ПО — можем приступать к созданию проекта.
Для этого запустим Cube MX.

В появившемся окне нажмем на кнопку «ACCESS TO MCU SELECTOR».

image

На нашей целевой плате установлен микроконтроллер STM32F103C8T6.

Введем его название в строке поиска и двойным щелчком выберем единственный найденный вариант.

В этой же таблице видно основную начинку нашего МК (64 килобайт флеша, 20 килобайт оперативы и пр).

image

Перед нами появился схематически изображенный корпус контроллера с разведенными в разные стороны ножками.

На данном этапе необходимо обязательно выбрать способ подключения отладчика.

Для этого на вкладке Pinout & Configuration в левом меню выбираем пункт SYS а в нем в выпадающем списке под названием «Debug» устанавливаем значение Serial Wire.

При этом краем глаза замечаем, что программа зарезервировала для отладочных целей два пина на мнемосхеме контроллера.

image

Еще раз вспоминаем, что мы хотим помигать светодиодом на нашей плате.

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

В этом нам поможет схема электрическая принципиальная:

image

или более красочная и простая для понимания распиновка платы

image

Искомый светодиод находится на ножке PC13.

Соответственно, необходимо настроить данный вывод для работы в режиме выхода.

  1. Находим вывод на мнемосхеме
  2. Нажимаем на него правой кнопкой мыши, из выпадающего меню выбираем пункт «GPIO_Output»
  3. Переходим в меню GPIO,
  4. В списке выбираем PC13
  5. Заполняем таблицу PC13-TAMPER-RTC Configuration в соответствии со скриншотом, особенно нас интересуют параметры GPIO mode и User Label

Продолжаем настройку проекта, переходим к вкладке Clock Configuration.

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

image

Переходим к вкладке Project Manager, под вкладка Project.

Обязательно заполняем следующие параметры:

  1. Имя проекта (лучше использовать только латинские буквы)
  2. Директорию, в которой будет создан проект (так же лучше использовать только латиницу)
  3. IDE, в которой планируется работа над проектом (мы планируем использовать TrueSTUDIO)

Спускаемся ниже, под вкладка Code Generator.

Здесь обязательно отмечаем опцию Generate peripheral initialization as pair…

Таким образом получим более структурированный проект, в котором для каждого типа периферии имеется своя пара C и H файлов.

image

Остался последний шаг. Подвкладка Advanced Settings.

  1. Выбираем тип библиотеки HAL для всех периферийных модулей
  2. Собираем проект с текущими настройками

При первоначальном запуске возможно потребуется загрузить актуальную версию библиотеки для выбранного семейства МК.

Даем свое согласие на скачивание файлов:

image

Идем греть чайник или готовить кофе:

image

После окончания работы кодо-генератора — сразу же открываем его:

image

Выбираем любую папку, где Atollic будет хранить рабочее пространство:

image

При успешном открытии — перед нами предстанет главное окно Atollic TrueSTUDIO for STM.

Общая информация нас мало интересует, поэтому сразу перейдем к дереву файлов.

RTC HAL stm32

Речь пойдёт о программировании RTC (встроенных часов) в микроконтроллере stm32.

Описание сделано для F103 и F303, но так как у них много общих функций, то читать нужно всё.

Первым делом нужно указать источник тактирования для часов. Указываем внешний кварцевый резонатор, он есть на многих платах…

В CubeMX выбираем RCC и указываем — Low Speed External (LSE) ⇨ Crystal/Ceramic Resonator

В мультиплексоре RTC Clock Mux нужно указать источник LSE…

Если внешнего кварца нет, тогда в мультиплексоре укажите LSI, а Low Speed External (LSE) ⇨ Disable.

Переходим в раздел RTC и делаем так…

Для F103

Data Format ⇨ Binary data format .

Со временем и календарём всё понятно. Формат 24-х часовой.

Auto Predivider Calcalation ⇨ Enabled — активирован автоматический расчёт предделителя.

Asynchronous Predivider value — предделитель часового кварца. С его помощью достигается тактирование в 1Гц (один тик в одну секунду). Если отключить автоматический режим, то нужно будет ввести число от 0 до 127.

Для F303

Здесь два предделителя для настройки частоты — Asynchronous Predivider value и Synchronous Predivider value . Для внешнего кварца укажите 127 и 255.

Если у Вас LSI 40kHz, тогда во втором предделителе укажите 311. Если частота другая, тогда смотрите ниже.

Настройка предделителей для разных источников тактирования…

У нас тактируется от LSE = 32.768кГц, тогда исходя из формулы получается следующее: 128 * 256 = 32768 / 32.768кГц = 1Гц (один тик в секунду). Если уменьшить или увеличить какое-нибудь значение, то часы пойдут быстрее или медленнее.

Hour Format — можно изменить формат времени 12/24.

Day Light Saving: value of hour adjustment — зимнее/летнее время (добавляет/вычитает один час из текущего времени).

Пишем код. В функции static void MX_RTC_Init(void) есть две структуры, их надо объявить как глобальные…

И заодно объявим массив для вывода данных в UART.

У F303 структура даты называется sDate.

В бесконечном цикле будем читать дату и время:

Если на пин Vbat подключить батерейку или просто подать 3 вольта, тогда после ресета данные будут сохраняться. Предварительно нужно в функции static void MX_RTC_Init(void) закомментировать установку времени и даты…

Эти же функции можно использовать где-нибудь в программе для изменения времени/даты на лету.

Теперь можно прошить ещё раз и понажимать ресет. Данные должны сохраняться.

Помните о том, что при повторной генерации проекта в CubeMX комментарии удалятся!

У микроконтроллера F103, дата не сохраняется. Это связано с тем, что F103 всего один 32-х битный регистр, см. спойлер…

Вот так выглядит схема RTC в F103…

От батарейки работает только регистр со временем и будильником, ну и ещё предделитель. То есть дату сохранить нельзя.

Но, дату сохранить нельзя только если пользоваться HAL, если же написать свой костыль, тогда в RTC_CNT можно сохранять дату/время в UNIX-формате, то есть количество секунд прошедшее с 1970 года. А потом средствами СИ вытаскивать из этого числа дату и время.

У более «жирных» камней сохраняется и дата и время.

Если используется LSI, то данные сохранятся, но время идти не будет.

Если у вас микроконтроллер F4xx или F7xx, и вы хотите считывать только время (без даты), то в любом случае нужно после функции HAL_RTC_GetTime(. ) вызывать HAL_RTC_GetDate(. ) , в противном случае время не будет обновляться.

Будильник (Alarm) для F103


Будильник сработает через пять секунд после старта.

RTC OUT ⇨ RTC Output on the Tamper pin — во время срабатывания будильника на tamper-пин (РС13) будет подан кратковременный импульс. Можно подключить светодиод и посмотреть. На плате BluePill увидеть что-либо трудно так как импульс очень уж слабенький (я подключал через транзистор).

Output ⇨ Alarm pulse signal on the TAMPER pin — во время срабатывания будильника подаётся импульс. При выборе этого режима появляется пункт с настройкой будильника — Alarm A .

Можно сгенерировать проект, прошить и посмотреть как мигнёт светодиод.

Output ⇨ RTC clock with a frequency divided by 64 on the TAMPER pin — на tamper-пин будет подана частота с часового кварца поделённая на 64. Можно осциллографом проверять точность кварца.

Output ⇨ Second pulse signal on the TAMPER pin — на tamper-пин будет подаваться импульс раз в секунду.

После того как попробуете эти режимы верните всё как на картинке.

Включите прерывание от будильника…


Будильник соединён с линией EXTI17 – RTC Alert event.

Добавьте колбек будильника:

Прошивайте и смотрите результат.

Чтобы посмотреть настройки будильника из программы, нужно вызвать функцию HAL_RTC_GetAlarm() …

Структуру будильника объявим как глобальную:

Для программной установки будильника нужно воспользоваться функцией HAL_RTC_SetAlarm_IT() , она есть в функции инициализации — static void MX_RTC_Init(void) .

Помимо прерывания от будильника, есть ещё прерывание, которое может вызываться раз в секунду.

Включите глобальное прерывание…

Добавьте ещё один колбек:

Перед бесконечным циклом добавьте функцию:

Прошейте и смотрите.

Как использовать этот функционал — например можно сделать так: в колбеке будильника запускаем это прерывание, после чего оно вызовется 10 раз и выключится. В прерывании можно делать что угодно, например подавать импульс на какой-нибудь пин с подключённой пищалкой.

Если установить RTC OUT ⇨ Disable …

… то режимы Output ⇨ RTC clock with a frequency divided by 64 on the TAMPER pin и Output ⇨ Second pulse signal on the TAMPER pin будут работать, а если RTC OUT ⇨ No RTC Output , то на tamper-пин ничего нельзя подать.

Tamper для F103 и F303


В RTC OUT указывайте что хотите. Calendar можно включить, а можно и не включать.

До этого мы использовали tamper-пин для вывода сигнала, а сейчас он будет выполнять обратную функцию.

У F103 есть десять 16-ти битных регистров для хранения пользовательских данных (backup registers). Если подключена батарейка, то данные в этих регистрах не обнуляются ни при нажатии Reset, ни при выходе из спящего режима, ни при отключении основного питания.

Если в эти регистры записать какие-то данные, то их можно будет стереть подав на tamper-пин кратковременный импульс.
В Reference manual предлагается использовать этот функционал в качестве контроля несанкционированного доступа к устройству. Видимо поэтому это назвали Tamper (вмешательство).

Какой именно сигнал послужит триггером, настраивается в пункте Tamper Trigger .

Rising Edge — с LOW на HIGH.
Falling Edge — с HIGH на LOW.

Внутренняя подтяжка такая слабенькая, что срабатывает от прикосновения пальца, поэтому желательно подтянуть пин к «плюсу» резистором (10КОм).

Запишем в первые два регистра данные:

В бесконечном цикле читаем эти данные:

Прошейте эту программу и коротните пин на «землю» — данные обнулятся.

Теперь если нажать Reset, то по идее данные должны будут записаться заново, но этого не случится. Дело в том, что после подачи сигнала запись в эти регистры будет запрещена. Чтобы восстановить возможность записи нужно полностью обесточить плату (батарейку тоже нужно отключить). Так происходит только в режиме Tamper, если его отключить, то эти регистры можно перезаписывать как угодно.

Помимо обнуления регистров этот сигнал может вызывать прерывание…

В программе нужно добавить только колбек:

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

Для работы без прерываний можно воспользоваться функцией ожидания сигнала.

Структуру тампера объявляем глобально:

В бесконечном цикле делаем так:

Опять же, при нажатии Reset регистры с данными будут перезаписываться.

У F303 15 пользовательских регистров и три tamper-пина.

Прерывания включаются так…

У каждого пина свой колбек:

Всё остальное как у F103.

Я когда ковырялся с этим функционалом, время от времени возникало ощущение что что-то «глючит» (регистры то записываются, то не записываются, то обнуляются, то не обнуляются), но потом стало понятно что это всего лишь следствие неправильных действий. Это к тому, что нужно проявить терпение и разобраться.

Будильник (Alarm) для F303

У этого микроконтроллера два будильника А и В

У них есть два варианта настроек:

Internal Alarm — просто будильник, может вызывать прерывание.

Routed to OUT — во время срабатывания будильника можно вызвать прерывание и/или подать кратковременный импульс на пин РС13 .

Сейчас укажите Internal Alarm А .

Настройте всё как на картинке…


Время у нас установлено 10:34:00, а будильник сработает в 10:34:10.

Sub Seconds — это миллисекунды.

Следующие пункты, это различные комбинации настроек времени/даты срабатывания будильника. Например пункт Alarm Mask Date Week day ⇨ Enable говорит о том, что будильник должен срабатывать каждый день.

Если активировать пункт Alarm Mask Minutes ⇨ Enable , то будильник будет срабатывать каждую минуту в течении часа. Срабатывания будут происходить не ровно в минуту, а минута + 10сек.

Если активировать пункт Alarm Mask Seconds ⇨ Enable , то срабатывать будет каждую секунду в течении минуты.

Этих комбинаций достаточно много, поэтому надеюсь что вы разберётесь самостоятельно.

Активируйте прерывание от будильника…

В код добавьте колбек:

У Alarm B свой колбек:

В бесконечном цикле будем выводить инфу:

Чтобы будильник подавал импульс на пин РС13, надо указать Routed to OUT …

В настройках появятся два дополнительных пункта…

Output Polarity — на ножку будет подаваться «плюс».
Output Type — почитайте здесь.

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

Подключите светодиод к пину РС13 и смотрите как он мигнёт во время срабатывания будильника.

WakeUp

WakeUp может выводить МК из спящего режима, вызывать прерывание и подавать сигнал на пин РС13.

WakeUp это простой 16-ти битный (от 0 до 65535) счётчик. Тактирование можно настроить с помощью предделителей часового генератора.

Например если сделать так…

Тогда счётчик будет увеличиваться со скоростью 2048 единиц в секунду и достигнет 10000 примерно через 5 секунд (32.768кГц / 16 = 2048, 10000 / 2048 = 4.88 сек). То есть WakeUp будет срабатывать каждые

Можно не заморачиваться с предделителями, а просто указать 1Hz…


Счётчик будет увеличиваться со скоростью 1 единица в секунду и срабатывать через каждые 5 сек.

Таким образом можно настроить пробуждение МК на достаточно большой интервал. Например если указать 65000, то WakeUp будет срабатывать каждые 18 часов.


Если включено прерывание, то на пин РС13 подаётся кратковременный импульс, а если отключено, то подаётся постоянный сигнал.

И добавьте соответствующий колбек:

Прошивайте и смотрите что получилось.

Посмотреть значение счётчика можно так:

TimeStamp

Прикольная функция. Если на пин РС13 подать внешний импульс, тогда в специальные регистры будут записаны текущие время и дата. Настройка только одна и она ничем не отличается от того, что написано в главе «Tamper для F103 и F303». То есть нужно указать фронт сигнала и подтянуть пин.

В бесконечном цикле сделайте так:

Прошейте МК и коротните РС13 на «землю».

Данные из регистров записываются в структуры времени и даты (чтоб не создавать дополнительные структуры).

Обратите внимание на то, что регистры обнуляются после чтения.

Прерывание то же что и у Tamper…

Calibration

В мануале про этот выход сказано так:

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

Есть два варианты частоты — 1Гц и 512Гц…

Запускается и останавливается этот сигнал функциями…

Можно помигать или попищать при срабатывании будильника.

Для калибровки часов этот выход нужно подключить к осциллографу и добиваться необходимой частоты двумя способами:

1. Манипулировать предделителями — грубая калибровка.
2. С помощью пропусков (маскировки) или добавления тактов — мягкая калибровка.

Осциллографа у меня нет поэтому я особо в этом не разбирался. За мягкую калибровку отвечает функция HAL_RTCEx_SetSmoothCalib() . Все подробности смотрите в AN3371, глава 1.4, стр. 17.

Reference clock detection — на это пин можно подать опорную частоту (50 Гц) из розетки. Проводить эксперименты я не решился

В мануале есть такая картика…

В статье не описаны некоторые функции — посмотреть их можно в файлах stm32f3xx_hal_rtc.c и stm32f3xx_hal_rtc_ex.c.

На этом всё.

Всем спасибо

STM32

Регистры часов реального времени в микроконтроллерах STM32F2xx

Регистры часов реального времени используются для настройки и работы модуля RTC . Для доступа к регистрам необходимо установить бит разрешения записи PWR_CR.DBP и разрешить запись путем последовательного занесения в регистр RTC_WPR чисел 0xCA и 0x53.

Регистр времени RTC _ TR

Регистр времени содержит значение текущего времени в BCD -формате. Доступен для записи только в режиме инициализации

Бит 22. PM: AM/PM – значение (0: AM или 24-часовой формат, 1:PM)

Биты 21:20 HT [1:0] Десятки часов в BCD формате

Биты 19:16 HU [3:0] Единицы часов в BCD формате

Биты 14:12 MNT [2:0] Десятки минут в BCD формате

Биты 11:8 MNU [3:0] Единицы минут в BCD формате

Биты 6:4 ST [2:0] Десятки секунд в BCD формате

Биты 3:0 SU [3:0] Единицы секунд в BCD формате

Регистр даты RTC _ DR

Регистр времени содержит значение текущей даты в BCD -формате. Доступен для записи только в режиме инициализации

Биты 23:20 YT[3:0] Десятки лет в BCD формате

Биты 19:16 YU [3:0] Единицы лет в BCD формате

Биты 15:13 WDU [2:0] День недели

— 000: не используется

Бит 12 MT Десятки месяца в BCD формате

Биты 11:8 MU [3:0] Единицы месяца в BCD формате

Биты 5:4 DT [1:0] Десятки даты в BCD формате

Биты 3:0 DU [3:0] Единицы даты в BCD формате

Регистр управления часами RTC _ CR

Бит 23 COE Разрешение подачи сигнала калибровки на выход. Данный бит включает выход AFO _ CALIB RTC . (0: не разрешено, 1: разрешено)

Биты 22:21 OSEL [1:0] Выбор функции выхода для AFO _ CALIB RTC .

11: Сигнал выхода из спящего режима

Бит 20 POL Полярность выхода AFO _ CALIB RTC (0: положительная, 1: отрицательная)

Бит 18 BKP Сохранение. При записи единицы сохраняет переход на летнее или зимнее время

Бит 17 SUB 1 H Вычитание 1 часа. При установке в 1 производится вычитание одного часа для перевода на зимнее время. Если текущий час равен 0, то установка бита не даст результата.

Бит 16 ADD 1 H Добавление 1 часа. Перевод на летнее время производится при установке бита в 1.

Бит 15 TSIE Разрешение прерывания по внешнему событию. (0: не разрешено, 1: разрешено)

Бит 14 WUTIE Разрешение прерывания по событию выхода из спящего режима. (0: не разрешено, 1: разрешено)

Бит 13 ALRBIE Разрешение прерывания по событию B . (0: не разрешено, 1: разрешено)

Бит 12 ALRAIE Разрешение прерывания по событию A . (0: не разрешено, 1: разрешено)

Бит 11 TSE Разрешение сохранения времени по внешнему событию. (0: не разрешено, 1: разрешено)

Бит 10 WUTE Разрешение выхода из спящего режима по результатам счета. (0: не разрешено, 1: разрешено)

Бит 9 ALRBE Разрешение события B . (0: не разрешено, 1: разрешено)

Бит 8 ALRAE Разрешение события A . (0: не разрешено, 1: разрешено)

Бит 7 DCE Разрешение калибровки. Значение предделителя PREDIV _ A должно быть больше 6.

Бит 6 FMT Формат времени (0: 24 часовой, 1: 12 часовой)

Бит 4 REFCKON Разрешение определения опорной частоты. (0: не разрешено, 1: разрешено)

Бит 3 TSEDGE Установка фронта срабатывания для внешнего события. (0: передний, 1: задний). При смене фронта, TSE должен быть сброшен.

Биты 2:0 WUCKSEL [2:0] Источник частоты для счетчика выхода из спящего режима.

10 x : ck _ spre (обычно 1 Гц)

11 x : ck _ spre (обычно 1 Гц) и добавление одного бита в счетчик WUT

Биты 7,6,4 регистра управления доступны для записи только в режиме инициализации. Биты 2:0 могут быть изменены при RTC_CR WUTE = 0 и RTC_ISR WUTWF = 1

Регистр инициализации и состояния часов RTC _ ISR

Бит 13 TAMP 1 F Флаг обнаружения несанкционированного доступа

Бит 12 TSOVF Переполнение буфера внешних событий. Флаг устанавливается, когда TSF уже установлен. Рекомендуется проверять и очищать данный флаг одновременно с TSF .

Бит 11 TSF Флаг внешнего события.

Бит 10 WUTF Флаг выхода из спящего режима.

Бит 9 ALRBF Флаг события B . Устанавливается, когда значение счетного регистра совпадает с R TC_ALRMBR

Бит 8 ALRAF Флаг события A . Устанавливается, когда значение счетного регистра совпадает с R TC_ALRM A R

Бит 7 INIT Режим инициализации (0: рабочий режим, 1: режим инициализации). При установке 1, счетчик времени останавливается, доступна запись в счетные регистры и предделитель. Счет возобновляется после сброса данного бита.

Бит 6 INITF Флаг инициализации. (0: рабочий режим, 1: режим инициализации)

Бит 5 RSF Флаг синхронизации. Устанавливается аппаратно, когда счетные регистры копируется в теневые регистры (RTC_TRx и RTC_DRx). (0: регистры не синхронизированы, 1: регистры синхронизированы)

Бит 4 INITS Флаг состояния инициализации. Устанавливается аппаратно, когда происходит инициализация счетного регистра. (0: счетный регистр не инициализирован, 1: счетный регистр инициализирован)

Бит 2 WUTWF Флаг установки значения таймера пробуждения (0: рабочий режим , 1: режим установки)

Бит 1 ALRBWF Флаг установки времени события B (0: рабочий режим, 1: режим установки)

Бит 0 ALRAWF Флаг установки времени события A (0: рабочий режим, 1: режим установки)

STM32G4. Периферия и таймеры

Математический сопроцессор CORDIC (Coordinate Rotation Digital Computer) выполняет вычисление некоторых математических функций, широко используемых при расчете параметров движения электродвигателей, в измерительных приборах, при цифровой обработке сигналов и так далее.

CORDIC обеспечивает более высокую скорость вычисления по сравнению с программными расчетами. С одной стороны, это позволяет уменьшить тактовую частоту процессорного ядра и, следовательно, снизить потребление микроконтроллера, а с другой – освободить его от проведения рутинных расчетов.

Данный сопроцессор является ведомым на шине AHB и может добавлять циклы ожидания в тех случаях, когда процессор запрашивает результаты еще до окончания расчета. Таким образом, для обмена с CORDIC не нужен какой-либо специальный программный драйвер.

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

Для дополнительной автоматизации работы CORDIC можно использовать DMA-контроллер, который позволяет считывать исходные аргументы из памяти и пересылать результаты расчетов обратно в память.

CORDIC поддерживает конвейерные операции – допускается загрузка новых аргументов в CORDIC, в то время как сам CORDIC выполняет расчеты с текущими аргументами.

CORDIC буквально расшифровывается как «цифровой компьютер для вращения координат». Это аппаратный блок, предназначенный для расчета методом последовательного приближения. В тригонометрическом режиме работы значения синуса и косинуса заданного угла θ определяются путем последовательного дискретного вращения единичного вектора [1, 0] до тех пор, пока суммарный поворот не будет равен значению исходного угла θ. После выполнения вращения координаты X и Y единичного вектора будут соответствовать значениям синуса и косинуса угла θ. И наоборот, расчет угла вектора [x, y] определяется путем вращения этого вектора до тех пор, пока он не совпадет с единичным вектором [1, 0]. Сумма углов поворота будет равна углу исходного вектора.

Сопроцессор CORDIC также позволяет рассчитывать гиперболические функции sinh, cosh, atanh, при этом вычисления ведутся не в тригонометрическом режиме, а с пошаговым приближением по гиперболе.

Перед запуском вычислений пользователь должен выбрать тип рассчитываемой функции. Для этого необходимо заполнить поле FUNC в регистре CORDIC_CSR.

CORDIC выполняет расчет следующих стандартных функций:

  • косинус;
  • синус;
  • фаза;
  • модуль;
  • арктангенс;
  • гиперболический косинус;
  • гиперболический синус;
  • гиперболический арктангенс;
  • натуральный логарифм;
  • квадратный корень.

Функции используют один или два аргумента (таблица 1). Кроме того, некоторые функции рассчитывают сразу два выходных значения. Например, при расчете синуса (RES1) автоматически рассчитывается косинус (RES2), и наоборот.

Таблица 1. Функции, поддерживаемые математическим сопроцессором CORDIC

Функция Первый
аргумент (ARG1)
Второй
аргумент (ARG2)
Основной
результат (RES1)
Дополнительный
результат (RES2)
Косинус Угол θ Модуль m m × cos θ m × sin θ
Синус Угол θ Модуль m m × sin θ m × cos θ
Фаза x y atan2(y,x) √x 2 +y 2
Модуль x y √x 2 +y 2 atan2(y,x)
Арктангенс x tan -1 x
Гиперболический косинус x cosh x sinh x
Гиперболический синус x sinh x cosh x
Гиперболический арктангенс x tanh -1 x
Натуральный логарифм x ln x
Квадратный корень x √x

CORDIC поддерживает работу с двумя форматами чисел: q1.31 и q1.15. В формате q1.31 числа представлены в виде 30 значащих бит и бита знака. Диапазон значений составляет от -1 (0x80000000) до 1…2 -31 (0x7FFFFFFF). Точность составляет 2 -31 или 5 × 10 -10 .

В формате q1.15 числа представлены в виде 14 значащих бит и бита знака. Диапазон значений составляет от -1 (0x8000) до 1…2 -15 (0x7FFF). Преимущество этого формата заключается в том, что в одно 32-битное слово можно упаковать сразу два аргумента или результата. То есть запись двух аргументов или чтение двух результатов выполняется за один такт. Но, разумеется, точность расчетов уменьшается до 2 -15 или 3 × 10 -5 .

Для оптимального использования форматов чисел углы в расчетах представлены в радианах, деленных на π. Таким образом, интервал составляет [-1, 1], где -1 соответствует – π, а 1 соответствует π.

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

CORDIC ведет расчеты методом последовательного приближения. Чем больше будет число шагов вычислений (итераций), тем выше будет точность расчетов. Для тригонометрических функций скорость расчета постоянна – за одну итерацию рассчитывается один бит результата. Для гиперболических функций скорость расчета не является постоянной и составляет менее одного бита результата за итерацию. При вычислении квадратного корня скорость расчетов в два раза выше чем при вычислении гиперболических функций.

Формат аргументов и результатов задается пользователем в полях ARGSIZE и RESSIZE регистра CORDIC_CSR: q1.31 или q1.15. Однако при выполнении расчетов CORDIC использует формат q1.23. Это значит, что ошибки округления становятся значительными для расчетов с точностью от 2 -19 . Таким образом, для получения максимальной точности необходимо использовать формат q1.31, однако даже в этом случае максимальная точность будет соответствовать 20-битной разрядности.

Точность расчетов определяется числом итераций. Количество итераций задается в поле PRECISION регистра CORDIC_CSR (реальное число итераций составляет PRECISION × 4). Очевидно, что чем выше число итераций, тем больше времени потребуется для вычислений до заданной точности. То есть, для обеспечения максимальной скорости вычислений требуется задавать минимально возможное (для заданной точности) число итераций. Для большинства случаев рекомендуется использовать значения 3…6 поля PRECISION.

После запуска вычислений пользовательской программе не требуется проверять флаг окончания расчета, чтобы определить, что вычисления закончены. Вместо этого программа просто запрашивает чтение регистра RDATA по шине AHB. Пока результат не готов, CORDIC формирует циклы ожидания, а процессор ожидает. Однако при необходимости можно работать по классической схеме и опрашивать флаг RRDY регистра CORDIC_CSR или ожидать прерывания от CORDIC.

CORDIC использует конвейерную систему работы (рисунок 1). Это значит, что вместо ожидания окончания текущей операции вычислений программа может загружать в CORDIC новые аргументы или параметры (регистр CORDIC_CSR). Таким образом, при потоковых вычислениях CORDIC никогда не простаивает.

Рис. 1. Конвейерная работа CORDIC

Рис. 1. Конвейерная работа CORDIC

Существует несколько сценариев работы CORDIC. Порядок работы с CORDIC при однократных вычислениях имеет следующий вид:

  1. запись параметров в регистр CORDIC_CSR;
  2. запись аргументов в регистр CORDIC_WDATA (автоматический запуск вычислений);
  3. чтение результатов из регистров CORDIC_RDATA.

Порядок работы с CORDIC при потоковых вычислениях имеет следующий вид:

  1. запись параметров в регистр CORDIC_CSR;
  2. запись аргументов для первой операции в регистр CORDIC_WDATA (автоматический запуск первой операции);
  3. запись новых параметров в CORDIC_CSR;
  4. запись аргументов для следующей операции в регистр CORDIC_WDATA;
  5. чтение результатов из регистров CORDIC_RDATA. Далее следует автоматический запуск следующей операции;
  6. повторение шагов 3…5 необходимое число раз;
  7. чтение результатов последней операции.

Порядок работы с CORDIC при потоковых вычислениях с поллингом флага готовности имеет следующий вид:

  1. запись параметров в регистр CORDIC_CSR;
  2. запись аргументов для первой операции в регистр CORDIC_WDATA (автоматический запуск первой операции);
  3. проверка флага готовности RRDY регистра CORDIC_CSR;
  4. чтение результатов из регистров CORDIC_RDATA.

Для разрешения прерывания требуется установить бит IEN регистра CORDIC_CSR. Порядок работы CORDIC с прерыванием по готовности имеет следующий вид:

  1. запись параметров в регистр CORDIC_CSR;
  2. запись аргументов для первой операции в регистр CORDIC_WDATA (автоматический запуск первой операции);
  3. прерывание по готовности результата;
  4. чтение результатов из регистров CORDIC_RDATA (чтение автоматически сбрасывает флаг прерывания).

Использование DMA c CORDIC является достаточно эффективным, но имеет большой недостаток – невозможность автоматического изменения параметров в регистре CORDIC_CSR. При необходимости изменения параметров следует остановить DMA, записать новые значения CORDIC_CSR и запустить новый цикл вычислений. DMA всегда использует конвейерный режим работы CORDIC. Для активации запросов на чтение DMA необходимо установить бит DMAWEN регистра CORDIC_CSR. Для активации запросов на запись DMA используется бит DMAREN регистра CORDIC_CSR.

Для подтверждения эффективности CORDIC были выполнены различные испытания. Так, например, выполнялся расчет синуса 1 кГц (48 ksps) по таблице углов (3024 значения, формат q1.15). В результате испытания CORDIC без DMA справился с задачей в пять раз быстрее, чем процессорное ядро Cortex-M4. При использовании DMA скорость возросла только в три раза, зато процессор был полностью освобожден от работы.

CORDIC может использоваться только в режимах Run, Low Power Run, Sleep и Low Power Sleep.

Математический ускоритель FMAC

Математический ускоритель FMAC построен на базе умножителя/сумматора (MAC), позволяющего выполнять умножение 16х16 и сложение/вычитание 24-битных чисел (рисунок 2). Благодаря FMAC процессорное ядро освобождается от рутинных операций, связанных с цифровой фильтрацией данных.

С помощью FMAC можно реализовать как КИХ-, так и БИХ-фильтры. Такие фильтры являются обычными элементами аудиоприложений, импульсных источников питания, измерительных приборов, систем управления двигателями и так далее. От пользователя требуется выбрать тип, порядок и коэффициенты фильтра, а также обеспечить поступление исходных данных и считывание результатов. Исходные данные и результаты помещаются в локальную RAM.

В процессе вычислений MAC получает два 16-битных операнда из локальной RAM-памяти размером 256х16 бит и передает результаты вычислений обратно в эту же память. Адресация локальной RAM осуществляется с помощью набора указателей. Указатели могут быть перезаписаны, инкрементированы, декрементированы или сброшены только аппаратно, и пользовательская программа не имеет к ним прямого доступа.

Рис. 2. Структура FMAC

Рис. 2. Структура FMAC

На рисунке 3 представлена архитектура аппаратного модуля MAC. В буфере X хранятся исходные значения, в буфере B хранятся коэффициенты фильтра. Размер обоих буферов составляет N + 1. В буфер Y помещаются отфильтрованные значения. В буфере A хранятся коэффициенты, которые перемножаются с отсчетами Y. Размер буферов A и Y составляет M + 1. Для получения результирующего массива Y необходимо выполнить N + 1 + M операций.

Рис. 3. Архитектура MAC

Рис. 3. Архитектура MAC

FMAC поддерживает работу с форматом чисел q1.15. В этом формате числа представлены в виде 14 значащих бит и бита знака. Диапазон значений составляет от -1 (0x8000) до 1…2 -15 (0x7FFF).

FMAC выполняет арифметические операции с векторами – 16-битными массивами чисел с фиксированной точкой. Эти векторы помещаются в буферы, находящиеся в локальной RAM-памяти (рисунок 4). Перед выполнением расчетов пользовательская программа должна инициализировать массивы X1, X2 и Y с помощью регистров X1BUFCFG, X2BUFCFG и YBUFCFG. Базовые адреса и размеры буферов задаются пользователем. Буферы могут быть размещены в любом месте локальной RAM-памяти и не должны выходить за ее пределы (адреса 0х00…0хFF). При этом X1, X2 и Y могут пересекаться.

Рис. 4. Размещение данных в локальной RAM-памяти

Рис. 4. Размещение данных в локальной RAM-памяти

Перед запуском вычислений процессорное ядро (или DMA) инициализируют содержимое буферов с помощью функций инициализации и записывают данные в регистр WDATA. Пересылка данных в буфер выполняется по указателю с учетом заданных ранее базовых адресов. После каждой записи указатель инкрементируется. Если адрес, хранящийся в указателе, выходит за рамки локальной памяти, он перемещается в начало памяти.

FMAC позволяет контролировать уровень заполнения буфера X1 данными. Для этого служит поле FULL_WM регистра FMAC_X1BUFCFG. При заполнении буфера до заданного порогового значения выставляется соответствующий флаг. Если этот флаг не установлен, FMAC будет автоматически генерировать запрос DMA или прерывание (если они разрешены), чтобы заполнить буфер данными. Наличие программируемой границы позволяет за каждое прерывание пересылать несколько значений данных, не боясь переполнения. В случае переполнения взводится флаг OVFL и новые данные игнорируются.

Что касается буфера выходных значений Y, то для него тоже можно задать граничное значение в поле EMPTY_WM регистра FMAC_YBUFCFG. Если число непрочитанных элементов меньше чем выбранное граничное значение, то будет устанавливаться флаг, сообщающий о том, что буфер пуст. Пока этот флаг не установлен, происходит автоматическая генерация запросов DMA или прерываний (если они разрешены) до тех пор, пока буфер не опустеет. Наличие программируемого порога заполнения буфера позволяет защититься от считывания неверных данных. Если же произошла попытка чтения незаполненных элементов, взводится флаг UNFL. В таких случаях инкремент указателя не производится.

В процессе вычислений FMAC считывает по одному элементу из X1 и X2 и перемножает их. Адреса элементов вычисляются внутри модуля управления FMAC.

На рисунке 5 поясняется принцип работы входного буфера Х1. Фильтр использует N + 1 входных отсчетов для расчета выходного отсчета y[n]. Когда расчет завершен, добавляется один новый элемент x[n + 1], и один старый элемент x[n — N] удаляется из буфера. Новый отсчет записывается по автоматически рассчитываемому указателю. Если указатель выходит за рамки адресного пространства локальной памяти, он перемещается в начало памяти. Если в буфере недостаточно данных для приема следующей порции входных данных — будет устанавливаться флаг заполнения буфера. Если адрес входного набора данных x[n] совпадает с указателем записи – это значит, что новых данных для расчета нет. В таких случаях работа фильтра останавливается до получения следующей порции данных. За подачу новых данных отвечает либо процессор, либо DMA.

Рис. 5. Размещение данных в локальной RAM-памяти

Рис. 5. Размещение данных в локальной RAM-памяти

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

Буфер X2 работает только в векторном режиме и не может использоваться в качестве кольцевого буфера. Он необходим для хранения коэффициентов. Обычно данные в него загружаются один раз при инициализации FMAC.

На рисунке 6 работа входного буфера поясняется на конкретном примере: N = 8, пересылка данных по 4 отсчета с помощью DMA.

На первом шаге фильтр рассчитывает y[n] по первым восьми отсчетам x[n — 7]…x[n]. Далее происходит загрузка следующих четырех отсчетов – x[n + 1]…x[n + 4].

На втором шаге отсчет y[n] готов. Самый старый входной элемент x удаляется. Указатель инкрементируется: n = n + 1. Далее происходит расчет y[n] по следующим восьми отсчетам x[n — 7]…x[n]. Новые данные не загружаются.

На третьем шаге все повторяется: получение y[n], самый старый входной элемент удаляется, указатель инкрементируется n = n + 1. Далее происходит расчет y[n] по следующим восьми отсчетам x[n — 7]…x[n]. Новые данные не загружаются.

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

Рис. 6. Пример работы входного буфера: N = 8, пересылка данных по четыре отсчета с помощью DMA

Рис. 6. Пример работы входного буфера: N = 8, пересылка данных по четыре отсчета с помощью DMA

Работа выходного буфера поясняется на рисунке 7. В этом буфере хранятся выходные отсчеты. Фильтр может использовать часть выходных отсчетов для выполнения вычислений. После получения очередного результата он помещается в буфер. Запись выполняется по указателю. Чтение элементов из буфера выполняется по указателю чтения, который указывает на самый старый невычитанный отсчет. Если считанный отсчет не используется в расчетах, то он удаляется из буфера.

Рис. 7. Размещение данных в локальной RAM-памяти

Рис. 7. Размещение данных в локальной RAM-памяти

На рисунке 8 поясняется работа выходного буфера на конкретном примере: M = 7, пересылка данных по 4 отсчета с помощью DMA.

На первом шаге фильтр рассчитывает y[n] по первым семи отсчетам y[n — 7]…y[n — 1]. Одиннадцать отсчетов остаются непрочитанными.

На втором шаге отсчет y[n] готов. Указатель инкрементируется n = n + 1. Происходит расчет по следующим семи отсчетам y[n — 7]…y[n — 1]. Программа или DMA вычитывают 4 отсчета. Указатель чтения увеличивается на 4.

На третьем шаге все повторяется, однако так как отсчеты y[n — 7]…y[n — 5] используются в расчетах, то они не удаляются.

Рис. 8. Пример работы выходного буфера: M = 7, пересылка данных по четыре отсчета с помощью DMA

Рис. 8. Пример работы выходного буфера: M = 7, пересылка данных по четыре отсчета с помощью DMA

FMAC позволяет реализовывать КИХ-фильтры (рисунок 9). Для этого используется следующая конфигурация:

  • в буфере X1 размещаются входные отсчеты. Буфер настраивается для работы в кольцевом режиме с длиной N + 1 + d;
  • в буфере X2 размещаются коэффициенты фильтра (вектор В). Буфер имеет фиксированную длину N + 1;
  • буфер Y содержит выходные значения. Буфер настраивается для работы в кольцевом режиме с длиной d;
  • парметр P определяет длину вектора В (диапазон 2…127);
  • парметр R отвечает за масштабирование выходных отсчетов. Отсчеты умножаются на 2 R . R может лежать в диапазоне 0…7.

Рис. 9. Реализация КИХ-фильтра с помощью FMAC

Рис. 9. Реализация КИХ-фильтра с помощью FMAC

FMAC позволяет реализовывать БИХ-фильтры (рисунок 10). Для этого используется следующая конфигурация:

  • в буфере X1 размещаются входные отсчеты. Буфер настраивается для работы в кольцевом режиме с длиной N + 1 + d;
  • в буфере X2 размещаются коэффициенты фильтра (вектора В и A). Буфер имеет фиксированную длину M + N + 1;
  • буфер Y содержит выходные значения. Буфер настраивается для работы в кольцевом режиме с длиной M + d;
  • параметр P определяет длину вектора В (диапазон 2…64);
  • параметр Q определяет длину вектора A (диапазон 1…63);
  • параметр R отвечает за масштабирование выходных отсчетов. Отсчеты умножаются на 2 R . R может лежать в диапазоне 0…7.

Рис. 10. Реализация БИХ-фильтра с помощью FMAC

Рис. 10. Реализация БИХ-фильтра с помощью FMAC

Тактирование FMAC производится той же частотой, что и ядро (FCLK). КИХ-фильтр N-ного порядка выполняет N умножений с накоплением для каждого выходного отсчета. Плюс каждая операция требует двух операций чтения. Тогда максимальная частота вычислений составит FCLK/(2 × N). Значение N должно быть меньше чем FCLK/(2 × Fs), где Fs – частота преобразования.

Рассмотрим несколько примеров. Так как максимальная частота ядра составляет 170 МГЦ, то максимальный размер фильтра при частоте преобразования Fs = 2 MSPS будет равен 42 (N<42). Если же порядок фильтра составляет 127, то максимальная частота преобразования будет менее 669 кГц.

Работа FMAC обычно строится с привлечением DMA (рисунок 11). При этом пропускная способность определяется не только тактовой частотой, но и источниками и приемниками данных. Например, если в качестве источника данных выступает АЦП, то его скорость преобразования может быть значительно ниже чем производительность FMAC. В результате скорость работы будет определяться именно производительностью АЦП. Аналогичным образом скорость будет ограничена медленным приемником, например, ЦАП.

Рис. 11. Пример организации потока данных при работе с FMAC

Рис. 11. Пример организации потока данных при работе с FMAC

FMAC может использоваться только в режимах Run, Low Power Run, Sleep и Low Power Sleep.

Аналогово-цифровые преобразователи ADC

Встроенные АЦП позволяют микроконтроллерам STM32G4 принимать аналоговые сигналы, например, от датчиков, и преобразовывать их в цифровую форму для дальнейшей обработки.

В составе STM32G4 может быть до пяти 12-битных АЦП последовательного приближения с общим числом входных каналов, достигающим 42. Кроме того, встроенный аппаратный блок передискретизации позволяет увеличить разрядность измерений до 16 бит без привлечения процессорного ядра. Скорость преобразований при 12-битном разрешении составляет 4 MSPS. Для пересылки результатов преобразования можно использовать DMA. Для управления работой АЦП предлагаются различные запускающие триггеры и прерывания.

В таблице 2 представлены основные параметры АЦП.

Таблица 2. Параметры АЦП микроконтроллеров STM32G4

Параметр Значение
Количество модулей АЦП 5
Число входных каналов 42 внешних + 3 внутренних
Тип АЦП Последовательного приближения
Разрядность, бит 12
Режимы работы Однократный, циклический, сканирующий, с инжектированными каналами
Триггерные сигналы Программные или аппаратные (от таймеров или портов GPIO)
Специальные функции Режим цифрового компаратора, передискретизация, самокалибровка
Обработка данных Поллинг, прерывания и DMA
Собственные режимы пониженного потребления Deep Power Down, Auto-off, Speed Adaptive

На рисунке 12 представлена блок-схема модуля АЦП. Основными функциональными блоками, входящими в состав АЦП, являются:

  • система управления питанием;
  • входные цепи фильтрации и нормирования (AFE);
  • триггерная логика;
  • блоки обработки выходных цифровых данных: цифровой компаратор, схема компенсации усиления и смещения;
  • система тактирования.

Рис. 12. Блок-схема модуля ADC

Рис. 12. Блок-схема модуля ADC

Модуль ADC принимает два тактовых сигнала: системный adc_ker_ck (выход PLL) и adc_hclk (тактовый сигнал шины AHB). AHB-интерфейс АЦП тактируется от adc_hclk, однако ядро АЦП может использовать для тактирования как adc_ker_ck, так и adc_hclk. Если используется adc_ker_ck, тогда тактирование АЦП не зависит от частоты AHB и возможно динамическое управление производительностью. К сожалению, для передачи данных по AHB придется использовать дополнительную синхронизацию. Если же используется adc_hclk, то задержки на синхронизацию отсутствуют.

Для питания АЦП требуются два источника напряжения:

  • VREF+ – источник опорного напряжения;
  • VDDA – источник питания аналоговой части АЦП.

По умолчанию АЦП находится в режиме глубокого сна (Deep Power-down), при этом для уменьшения токов утечки его питание отключено с помощью встроенных ключей. Для дополнительного снижения потребления можно отключить и встроенный регулятор напряжения АЦП. Для этого необходимо записать «0» в бит ADVREG регистра управления. Для выхода из режима сна и включения АЦП необходимо сбросить бит DEEP PowerDown. Для отключения АЦП необходимо записать «1» в бит ADDIS.

Аналоговые ключи, коммутирующие питание, имеют конечное сопротивление. При уменьшении напряжения питания VDDA это сопротивление может оказаться неприемлемо большим. В случае, когда VDDA < 2,4 В, а VDD > 2,4 В, питание АЦП можно переключить на VDD. Если же VDDA < 2,4 В и VDD < 2,4 В, то следует активировать встроенный повышающий преобразователь, который будет питать аналоговые ключи и гарантировать их малое сопротивление.

В качестве опорного напряжения для АЦП может использоваться как внешний ИОН (источник опорного напряжения), подключаемый ко входу Vref, так и встроенный источник VREFBUF. Стоит отметить, что VREFBUF доступен только в корпусных исполнениях, в которых есть вывод Vref. Кроме того, при использовании VREFBUF к выводу Vref должен быть подключен развязывающий конденсатор. VREFBUF позволяет выбрать три уровня опорного напряжения: 2,048 В, 2,5 В и 2,90 В.

В составе STM32G4 может быть до 5 АЦП с различным числом входных каналов:

  • ADC1 — 14 внешних каналов + 4 внутренних;
  • ADC2 — 16 внешних каналов + 2 внутренних;
  • ADC3 — 15 внешних каналов + 3 внутренних;
  • ADC4 — 16 внешних каналов + 2 внутренних;
  • ADC5 — 13 внешних каналов + 5 внутренних.

Внутренние каналы позволяют подключать АЦП к опорному напряжению, встроенному датчику температуры, напряжению аккумулятора VBAT/3, выходам операционных усилителей OPAMP1, 2, 3, 4, 6.

В таблице 3 поясняется возможность подключения внутренних каналов к разным модулям ADC.

Таблица 3. Подключение внутренних каналов к разным модулям ADC

Канал Модуль
Сигнал ADC1 ADC2 ADC3 ADC4 ADC5
Датчик температуры IN16 IN4
VBAT/3 IN17 IN17 IN17
REFINT IN18 IN18 IN18 IN18
OPAMPx IN13 (x = 1) IN16 (x = 2),
IN18 (x = 3)
IN13 (x = 3) IN17 (x = 6) IN3 (x = 5),
IN5 (x = 4)

Входы могут работать в несимметричном и дифференциальном режимах.

АЦП позволяет выполнять калибровку для устранения ошибок усиления и смещения. Калибровка несимметричных и дифференциальных каналов производится по отдельности (в соответствии с состоянием бита ADCCALDIF). Запуск калибровки выполняется с помощью установки бита ADCAL. Результирующее калибровочное значение записывается в регистр ADC_CALFACT. Рекомендуется выполнять калибровку в случаях, когда наблюдаются значительные изменения опорного напряжения, или при значительных температурных перепадах.

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

После выполнения преобразования АЦП позволяет проводить ограниченную цифровую обработку получаемых отсчетов с помощью блока передискретизации и блока компенсации усиления и смещения. Далее результаты могут быть считаны вручную или с помощью DMA. Однако использование DMA возможно только при работе с регулярными измерениями.

Блок передискретизации позволяет увеличить разрядность измерений за счет усреднения нескольких отсчетов. Пользователь может задавать уровень передискретизации 2/4/8/16/32/64/128/256. Стоит понимать, что передискретизация снижает эффективную скорость преобразований. Например, при уровне передискретизации 256 разрядность выходных отсчетов возрастает до 16 бит, но частота получения этих отсчетов падает до 156 ksps.

Блок компенсации усиления позволяет наиболее эффективно использовать динамический диапазон АЦП.

Блок компенсации смещения для выбранного канала активируется с помощью бита OFSETy_EN=1 регистра ADC_OFRy. При компенсации смещения из значения отсчета вычитается значение, записанное в регистре OFFSETy[11:0]. Так как результат может быть отрицательным, используются знаковые числа.

В АЦП реализованы некоторые функции пониженного потребления. Например, функция автоматического ожидания (Auto-Delay mode) не запускает новое преобразование АЦП до тех пор, пока не будет считан предыдущий отсчет или пока не будет сброшен флаг окончания измерения. Однако это не относится к инжектированным измерениям.

Потребление АЦП напрямую зависит от частоты измерений: 16 мкА при частоте 10 ksps и 590 мкА при 4 Msps.

Время полного преобразования АЦП складывается из времени выборки и времени непосредственно преобразования. Для выборки требуются как минимум 2,5 такта и еще 12,5 тактов на преобразование в случае использования 12-битного разрешения. Таким образом, полное время, затрачиваемое на получение отсчета, составит 15 тактов, что при максимальной частоте 60 МГц обеспечит частоту преобразований 4 Msps. Для достижения большей частоты измерений следует уменьшить разрядность. Например, при шестибитной разрядности частота измерений составит 6,66 Msps. Кроме того, при совместной работе двух АЦП можно обеспечить частоту преобразований 7 Msps при 12-битной разрядности.

Время выборки определяет время, затрачиваемое на заряд встроенного конденсатора. Длительность этой фазы программируется пользователем и может составлять 2,5/6,5/12,5/24,5/47,5/92,5/247,5/640,5 тактов. Чем выше импеданс источника, тем больше времени потребуется для заряда конденсатора и тем больше должно быть время выборки. Время выборки выбирается индивидуально для каждого канала.

АЦП в микроконтроллерах STM32G4 поддерживает следующие основные режимы работы (рисунок 13):

  • одноканальный режим (Single Conversion mode) с однократным запуском или циклическими измерениями. В данном случае работа ведется с одним каналом;
  • сканирующий режим (Scan mode) с однократным запуском или циклическими измерениями. В данном случае производится последовательное измерение напряжений выбранных каналов;
  • прерывистый режим (Discontinuous mode), в котором измерения выполняются группами по внешнему сигналу.

Рис. 13. Алгоритмы работы АЦП в микроконтроллерах STM32G4

Рис. 13. Алгоритмы работы АЦП в микроконтроллерах STM32G4

В STM32G4 появилось и два новых режима:

  • Bulb mode, который, в отличие от Discontinuous mode, после окончания измерений очередной группы АЦП не переходит в режим ожидания, а сразу начинает следующий цикл измерений;
  • Sample control mode – режим с ручным управлением временем выборки. В данном случае время выборки определяется длительностью триггерного сигнала.

Каждый модуль ADC имеет по три цифровых оконных компаратора с программируемыми пороговыми значениями (верхним и нижним): AWD1/2/3. Если измеренное значение выходит за границы разрешенного окна, установленного пользователем, генерируется прерывание. У блока AWD1 есть функция фильтрации, благодаря ей он может генерировать прерывание не сразу, а только в том случае, если сигнал вышел за пределы разрешенного окна несколько раз (определяется пользователем).

Результаты измерений помещаются в 16-битный регистр. В режиме Dual mode результат помещается в 32-битный регистр. Контроль готовности данных может выполняться с привлечением поллинга или прерываний. Передача данных осуществляется либо вручную, либо с использованием DMA. Если данные не были вычитаны до получения следующего результата, устанавливается флаг OVERRUN. Пользователь сам выбирает, каким образом АЦП должен поступать в таких случаях: игнорировать новый отсчет или записать его поверх старого.

Инжектированные измерения необходимы для того чтобы прервать цепочку регулярных измерений для срочного определения напряжений на критически важных каналах. После выполнения инжектированных измерений (до 4) АЦП возвращается к регулярным измерениям. Для хранения отсчетов инжектированных преобразований предназначено четыре отдельных 16-битных регистра.

Модули ADC1 и ADC2 могут работать синхронно в режиме Dual mode. Аналогичным образом могут использоваться ADC3 и ADC4. В этом режиме оба АЦП используют общие триггеры запуска. В режиме Dual mode поддерживаются различные варианты работы: синхронные инжектированные измерения, синхронные регулярные измерения, последовательные измерения на одном канале, измерения с альтернативным запуском.

АЦП способен выставлять ряд флагов с возможностью генерации прерываний:

  • ADRDY – АЦП готов к выполнению преобразования;
  • EOC – преобразование завершено;
  • EOS – цепь преобразований завершена;
  • JEOC – инжектированное преобразование завершено;
  • JEOS – цепь инжектированных преобразований завершена;
  • AWD1…3 – срабатывание цифрового компаратора 1…3;
  • EOSMP – фаза выборки завершена;
  • OVR – ошибка записи новых данных, если старые данные перед этим не были вычитаны;
  • JQOVF – переполнение очереди инжектированных измерений;
  • EOCAL – калибровка завершена.

Модули ADC могут работать в режимах Run, Sleep, Low-Power Run и Low-Power Sleep.

Цифро-аналоговый преобразователь DAC

Встроенные модули DAC позволяют микроконтроллерам STM32G4 формировать аналоговые сигналы. Каждый модуль DAC состоит из двух ЦАП, которые могут работать с 8-/12-битным разрешением.

Ключевыми особенностями встроенных ЦАП являются:

  • 8-/12-битное разрешение;
  • наличие выходного буфера для работы с низкоомной нагрузкой;
  • встроенная схема выборки хранения, позволяющая существенно снизить потребление;
  • возможность синхронной и асинхронной работы каналов ЦАП;
  • поддержка DMA, что существенно разгружает процессорное ядро;
  • встроенные генераторы шума, треугольных импульсов и зубчатых сигналов);
  • развитая триггерная логика, работающая с программными и аппаратными сигналами запуска.

В качестве опорного сигнала для ЦАП может использоваться как внешний ИОН, подключаемый ко входу Vref, так и встроенный источник VREFBUF. VREFBUF позволяет выбрать три уровня опорного напряжения: 2,048 В, 2,5 В и 2,90 В.

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

Упрощенная блок-схема модуля DAC представлена на рисунке 14. Питание DAC осуществляется от VDDA, а сигнал ИОН подается на вход VREF+. DAC является ведомым на шине AHB и поддерживает запросы DMA. Благодаря развитой матрице межсоединений микроконтроллеров STM32G4 выходы ЦАП DAC_OUTx можно подключать ко входам встроенных компараторов и операционных усилителей. При работе со внешними цепями выходные сигналы ЦАП могут дополнительно буферизироваться. Блок выборки хранения использует независимое тактирование от LSE или LSI, что позволяет поддерживать статичный выходной сигнал ЦАП даже в режимах STOP. Передача данных в ЦАП происходит не напрямую, а через регистры хранения данных.

Рис. 14. Блок-схема модуля DAC

Рис. 14. Блок-схема модуля DAC

Микроконтроллеры STM32G4 могут иметь до четырех модулей DAC (таблица 4). Модули DAC1, DAC3 и DAC4 имеют по два канала, модуль DAC2 – только один. Выходы DAC1 и DAC2 могут быть подключены к выводам микроконтроллера, в то время как выходы DAC3 и DAC4 могут быть подключены только ко встроенной периферии – компараторам, ОУ. По этой причине в DAC3 и DAC4 нет выходных буферов. Частота преобразования для DAC1 и DAC2 составляет 1 Msps, а для DAC3 и DAC4 – 15 Msps.

Таблица 4. Особенности модулей DAC

Параметр Модуль
DAC1 DAC2 DAC3 DAC4
Частота преобразований, Msps 1 1 15 15
Выходной буфер + +
Число каналов 2 (внешние) 1 (внешний) 2 (внутренние) 2 (внутренние)
Подключение ко внешним выводам микроконтроллера PA4, PA5 PA6

ЦАП поддерживают различные форматы данных:

  • 8-битный формат с правым выравниванием (16-битный регистр данных);
  • 12-битный формат с правым выравниванием (16-битный регистр данных);
  • 12-битный формат с левым выравниванием (16-битный регистр данных).

При работе в режиме Dual-Channel mode для хранения данных обоих каналов ЦАП используется 32-битный регистр, причем поддерживаются различные форматы данных, как показано на рисунке 15.

Рис. 15. Форматы данных и выравнивание в режиме Dual-channel mode

Рис. 15. Форматы данных и выравнивание в режиме Dual-channel mode

Запуск преобразования может производиться либо программно (при записи в регистр данных DAC_DHR), либо аппаратно по триггеру. В качестве аппаратных триггеров могут использоваться 7 выходов от таймеров, 7 выходов от HRTIM, внешние сигналы IO.

При программном запуске данные из DAC_DHR передаются в DAC_ODR за 1 системный такт. При использовании аппаратных триггеров содержимое DAC_DHR попадает в DAC_ODR pf 3/5/7 тактов шины AHB (в зависимости от частоты шины).

Выходная схема выборки-хранения ЦАП необходима для энергоэффективного поддержания статического напряжения на выходе ЦАП. При активном состоянии ЦАП его выходное напряжение заряжает выходной конденсатор. После выключения ЦАП конденсатор также оказывается отключенным. Разумеется, с течением времени его напряжение будет неизбежно уменьшаться из-за разряда. Схема выборки-хранения отвечает за поддержание уровня заряда при неактивном ЦАП. Пользователь может самостоятельно выбрать период регенерации сигнала. Этот режим имеет огромное значение с точки зрения уменьшения потребления. Кроме того, благодаря тактированию схемы от LSE или LSI выходной сигнал на выводе микроконтроллера будет поддерживаться даже в режиме STOP.

Каждый канал ЦАП может автоматически генерировать три типа сигналов: шумовые, треугольные и зубчатые. Пример треугольного сигнала показан на рисунке 16.

Рис. 16. Работа генератора треугольных сигналов

Рис. 16. Работа генератора треугольных сигналов

Модули ЦАП могут использовать DMA для освобождения процессора от рутинных операций по пересылке данных. Каждый раз, когда ЦАП пересылает данные из DAC_DHR в DAC_ODR, новая порция данных загружается в DAC_DHR с помощью DMA. Так как пересылка данных осуществляется по сигналу аппаратного триггера, то джиттер выходного сигнала ЦАП будет минимальным, что существенно упрощает фильтрацию выходного сигнала от несущей.

Общие характеристики ЦАП представлены в таблице 5.

Таблица 5. Характеристики ЦАП микроконтроллеров STM32G4

Параметр Условие Значение
VDDA, В 1,71…3,6
Монотонность, бит 10
Дифференциальная нелинейность (DHL), LSB ±2
Интегральная нелинейность (INL), LSB ±2
Эффективная разрядность (ENOB), бит Буфер включен 11,4
Эффективная разрядность (ENOB), бит Буфер выключен 11,5
Потребление от VREF+, мкА Буфер включен 185
Потребление от VREF+, мкА Буфер выключен 155
Время установления (1 Msps), мкс ±1 LSB C = 50 пФ 1,6
Частота преобразований, Msps 1/15

Для более полного ознакомления с особенностями использования встроенных ЦАП микроконтроллеров STM32 следует обратиться к существующим руководствам:

Источник опорного напряжения VREFBUF

Встроенный источник опорного напряжения VREFBUF используется для работы ЦАП и АЦП. Выходное напряжение VREFBUF программируется пользователем и может составлять 2,048 В, 2,5 В и 2,90 В. Выходная нагрузка VREFBUF может достигать 6,5 мА.

Для работы VREFBUF необходим внешний конденсатор, подключаемый к выводу микроконтроллера VREF+. Данный вывод присутствует не у всех микроконтроллеров STM32G4. Если такого вывода у микроконтроллера нет, то использование VREFBUF невозможно.

Наличие встроенного ИОН дает сразу несколько важных преимуществ:

  • уменьшение места, занимаемого на печатной плате при отказе от внешних ИОН;
  • уменьшение стоимости;
  • получение стабильного опорного напряжения даже в тех случаях, когда напряжение VDDA изменяется (в частности – при питании от аккумулятора или батарейки).

Выбор ИОН и режим работы буфера VREFBUF определяются двумя битами: ENVR и HZ, как показано в таблице 6. Для активации VREFBUF необходимо установить бит ENVR и сбросить бит HZ в регистре VREFBUF_CSR. После этого необходимо дождаться флага готовности VRR.

Таблица 6. Режимы работы VREFBUF

ENVR HIZ VREFBUF Описание
0 0 Выкл Режим без ИОН. VREFBUF выключен. Выход VREF подтянут к VSSA.
0 1 Выкл Режим внешнего ИОН. Внешний источник опорного напряжения должен быть подключен к выходу VREF (данный режим установлен по умолчанию).
1 0 Вкл Режим внутреннего ИОН. VREFBUF подключен к выходу VREF.
1 1 Выкл Режим Hold mode. VREFBUF выключен. Выход VREF отключен от VREFBUF. Напряжение на VREF поддерживается внешним конденсатором.

Источник опорного напряжения VREFBUF калибруется при производстве. Калибровочные данные записываются в регистр VREFBUF_CCR (поле TRIM[5:0]). Этот регистр доступен не только для чтения, но и для записи. При необходимости пользователь может самостоятельно проводить калибровку, записывая новые калибровочные данные в TRIM[5:0].

VREFBUF может использоваться во всех режимах, до Stop 0 и Stop 1 включительно. Это важно, так как напряжение VREFBUF может использоваться внешними схемами.

Операционные усилители OPAMP

В составе STM32G4 могут быть до шести встроенных операционных усилителей OPAMP1…6 с программируемым коэффициентом усиления и rail-to-rail-входами/выходами. Наличие встроенных усилителей дает целый ряд очевидных преимуществ: уменьшение габаритов, снижение стоимости, упрощение трассировки печатной платы и так далее.

Усилители могут использоваться для усиления входных сигналов перед их подачей на встроенные АЦП, а могут работать независимо, так как все входы и выходы ОУ доступны через внешние выводы микроконтроллера.

Ключевыми особенностями встроенных ОУ являются:

  • rail-to-rail-входы/выходы;
  • минимальное входное смещение с возможностью калибровки;
  • возможность работы совместно со встроенной периферией и независимо;
  • два режима работы: нормальный и производительный.

При работе в нормальном режиме скорость нарастания сигнала на выходе ОУ составляет 6,5 В/мкс. В производительном режиме скорость нарастания достигает 45 В/мкс. Производительный режим нужен, когда АЦП работает с очень быстрыми сигналами. В таких случаях входной конденсатор системы выборки-хранения должен перезаряжаться максимально быстро, что и обеспечивает ОУ.

Блок-схема ОУ представлена на рисунке 17. Каждый ОУ может быть настроен индивидуально. Все входы и выход ОУ доступны пользователям.

Рис. 17. Блок-схема ОУ

Рис. 17. Блок-схема ОУ

Входные мультиплексоры обеспечивают различные варианты подключения входов и выходов:

  • В самом простом случае (по умолчанию) инвертирующий вход ОУ подключен ко внешнему выводу. Коэффициент усиления определяется внешней цепочкой обратной связи. ОУ работает независимо от других периферийных блоков.
  • Инвертирующий вход ОУ может быть подключен к выходу с помощью входного мультиплексора. В таком случае ОУ работает в режиме повторителя напряжения.
  • Инвертирующий вход ОУ может быть подключен к выходу через программируемую цепь обратной связи (PGA). Программируемый коэффициент усиления может принимать значения 2/4/8/16/32/64. Благодаря PGA, ОУ позволяют эффективно использовать динамический диапазон встроенных АЦП. Для коррекции частотной характеристики пользователь может использовать внешний конденсатор, включенный между входом и выходом ОУ.
  • С помощью конфигурации мультиплексоров пользователь может создавать и инвертирующие схемы с коэффициентом усиления -1, -3, -7, -15, -31 или -63. Для коррекции частотной характеристики пользователь может использовать внешний конденсатор, включенный между входом и выходом ОУ.

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

ОУ могут оставаться активными во всех режимах, до Stop 0 и Stop 1 включительно.

Основные характеристики встроенных ОУ приведены в таблице 7.

Таблица 7. Основные характеристики встроенных ОУ STM32G4

Параметр STM32G4
Количество ОУ До 6
Напряжение питания, В 2,0…3,6
Диапазон входных напряжений 0…VDDA (3,6 В)
Программируемое усиление x2/x4/x8/x16/x32/x64
и x-1/x-3/x-7/x-15/x-31/x-63
Начальное смещение (без нагрузки и при 25°С), мВ ±1,5
GBW, МГц 13
Скорость нарастания, В/мкс 6,5 (нормальный режим),
45 (производительный режим)
Выходной ток (без PGA), мкА 500
PSRR, дБ 80
Пробуждение, мкс 6
Потребление, мА 1,3
Ошибка усиления PGA, % ±1

Аналоговые компараторы COMP

В состав STM32G4 могут входить до семи компараторов, которые позволяют сравнивать внешние и внутренние аналоговые сигналы. В отличие от АЦП, которые измеряют сигналы периодически, аналоговые компараторы работают непрерывно. Компараторы способны пробуждать процессорное ядро из режимов Stop и Sleep.

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

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

Ключевыми особенностями встроенных аналоговых компараторов являются:

  • наличие до семи компараторов. Количество компараторов зависит от линейки STM32G4. В микроконтроллерах STM32G4х1 может быть до четырех компараторов, а в линейках STM32G4х3 и STM32G4х4 – до семи;
  • программируемый гистерезис для защиты от ложных срабатываний при работе в зашумленных условиях;
  • возможность менять местами инвертирующий и неинвертирующий входы;
  • возможность использования в качестве входов сигналы от встроенных ЦАП или поделенный сигнал VREFINT;
  • возможность подключения выходов к таймерам;
  • защита конфигурационных регистров от случайной записи.

На рисунке 18 приводится упрощенная блок-схема компараторов. Мультиплексоры позволяют выбирать источник входного сигнала инвертирующего входа. В качестве источников могут выступать порты GPIO, выходы ЦАП, поделенный сигнал VREFINT. Выходной сигнал компаратора может быть дополнительно инвертирован. Выход компаратора можно подключать к выводу микроконтроллера и/или перенаправить ко внутренним блокам – EXTI или таймерам.

Рис. 18. Блок-схема компаратора

Рис. 18. Блок-схема компаратора

Каждый компаратор имеет инвертирующий и неинвертирующий входы. Для выбора источников инвертирующего и неинвертирующего входов используются поля INMSEL и INPSEL регистров COMP_CxCSR.

Компараторы могут работать в нескольких особых режимах. Режим Blanking mode весьма полезен для схем контроля тока в различных приложениях, например, в приводах электродвигателей или во многофазных мостовых преобразователях. В процессе коммутации этих устройств часто возникают броски тока. Очень часто такие кратковременные перегрузки являются неизбежным и допустимым явлением, но могут вызвать срабатывание компаратора. Чтобы защититься от ложных срабатываний, используется режим Blanking mode со слепой зоной и блокирующим сигналом. Принцип работы компаратора в этом режиме поясняется на рисунке 19. В качестве блокирующего сигнала могут выступать выходы таймеров. Выбор блокирующего сигнала выполняется с помощью поля BLANKSEL.

Рис. 19. Использование режима Blanking mode для фильтрации стартового броска

Рис. 19. Использование режима Blanking mode для фильтрации стартового броска

Для защиты от помех встроенные компараторы позволяют добавлять программируемый гистерезис. Гистерезис назначается в диапазоне 0…70 мВ с шагом 10 мВ. Для задания гистерезиса используется поле HYST[2:0]. Стоит отметить, что гистерезис является несимметричным и действует только по фронту. Однако в случае необходимости потребитель может использовать дополнительные внешние цепи для задания своего собственного гистерезиса (рисунок 20).

Рис. 20. Режим компаратора с гистерезисом

Рис. 20. Режим компаратора с гистерезисом

Выходы компараторов могут подключаться к таймерам:

  • для аварийной остановки ШИМ (используются входы BKIN1 и BKIN2);
  • для циклического контроля тока (используется вход ETR);
  • для измерения временных интервалов.

Компараторы способны генерировать прерывания напрямую для NVIC и через EXTI.

Компараторы могут также использоваться в режимах пониженного потребления вплоть до Stop.

Независимый сторожевой таймер IWDG

Независимый сторожевой таймер IWDG необходим для защиты микроконтроллера от зависания. Если после запуска этот таймер не будет сброшен в течение определенного времени, программируемого пользователем, то он сформирует сигнал сброса для микроконтроллера.

Для тактирования IWDG используется встроенный резонатор 32 кГц LSI, благодаря чему IWDG продолжит работу даже при отсутствии системного тактового сигнала.

После того как IWDG запущен, его нельзя отключить (но можно временно приостановить, например, в режиме отладки). Он будет остановлен только тогда, когда будет выполнен сброс микроконтроллера.

Основными особенностями IWDG являются:

  • возможность программировать длительность таймаута в широких пределах 125 мкс…32 с;
  • независимое тактирование от 32 кГц LSI. При этом LSI не может быть отключен после включения IWDG;
  • генерация сигнала сброса по завершению таймаута или при обновлении IWDG вне разрешенного окна;
  • возможность «заморозки» IWDG в режиме отладки, а также в режимах STOP и Standby;
  • возможность автоматического запуска IWDG после сброса микроконтроллера.

Блок-схема IWDG представлена на рисунке 21. IWDG состоит из двух доменов. Регистры управления находятся в домене APB. Тактирование этого домена производится от сигнала тактирования шины APB. Функциональные блоки IWDG находятся в домене VDD. Тактирование этого домена IWDG производится от LSI. Такая архитектура необходима для работы IWDG в режимах пониженного потребления вплоть до Standby. Входной 8-битный делитель позволяет поделить частоту LSI. Основным блоком IWDG является 12-битный вычитающий счетчик.

Рис. 21. Блок-схема IWDG

Рис. 21. Блок-схема IWDG

Поведение IWDG в различных режимах определяется опциональными битами регистра FLASH_OPTR:

  • если установлен бит IWDG_SW, то IWDG автоматически запускается после сброса;
  • для остановки IWDG в режиме STOP необходимо установить бит IWDG_STOP;
  • для остановки IWDG в режиме Standby необходимо установить бит IWDG_STDBY.

На рисунке 22 поясняется принцип работы IWDG. Когда вычитающий счетчик досчитает до 0, происходит сброс микроконтроллера. IWDG также генерирует сигнал сброса, если выбран оконный режим работы и программа выполнила сброс счетчика слишком рано (вне разрешенного окна). Таким образом, чтобы предотвратить сброс микроконтроллера, счетчик должен обновляться в рамках разрешенного окна.

Рис. 22. Принцип действия IWDG

Рис. 22. Принцип действия IWDG

При использовании режима автоматического запуска (должен быть установлен бит IWDG_SW) после сброса микроконтроллера происходит автоматически запись в счетчик IWDG значения 0xfff. По умолчанию выбирается делитель тактового сигнала 4. Счетчик начинает считать вниз. Если пользователь вовремя не сбросит счетчик, произойдет сброс микроконтроллера. При частоте LSI 32 кГц сброс микроконтроллера произойдет через 0,5 с.

При ручном запуске IWDG необходимо выполнить процедуру инициализации:

  • записать в регистр управления IWDG_KEY значение 0x0000 СССС;
  • снять защиту от записи, для чего записать в регистр управления IWDG_KEY значение 0x0000 5555;
  • в регистре IWDG_PR задать значение делителя тактового сигнала;
  • задать начальное значение вычитающего счетчика в регистре IWDG_RLR;
  • убедиться, что биты готовности в регистре IWDG_SR сброшены и значения регистров обновлены;
  • для выбора оконного режима задать граничное значение в регистр IWDG_WINR;
  • если оконный режим не требуется — еще раз записать в регистр IWDG_KEY значение 0x0000 AAAA.

Значение таймаута IWDG можно определить по формуле 1:

  • tLSI = 1/32000 = 31,25 мкс;
  • PR и RL – значения делителя тактового сигнала и начальное значение счетчика, задаваемые в регистрах управления.

Оконный сторожевой таймер WWDG

Оконный сторожевой таймер WWDG, как и независимый сторожевой таймер IWDG, используется для сброса микроконтроллера в случае программных ошибок и зависаний. После запуска WWDG он может быть отключен только при сбросе микроконтроллера.

На рисунке 23 представлена блок-схема WWDG. Тактирование WWDG выполняется сигналом pclk — тактовым сигналом шины APB. Этот сигнал по умолчанию делится на 4096 и может быть дополнительно поделен на программируемое значение (задается в поле WDGTB). Основным элементом WWDG является 7-битный вычитающий счетчик. Стартовое значение счетчика задается пользователем в поле T[6:0]. Ширина разрешенного окна обновления определяется содержимым поля W[6:0].

Рис. 23. Блок-схема WWDG

Рис. 23. Блок-схема WWDG

У WWDG есть несколько особенностей:

  • пользователь может задавать длительность таймаута и ширину разрешенного окна сброса счетчика WWDG;
  • сигнал сброса генерируется в двух случаях: когда вычитающий счетчик досчитает до 0x3F или когда обновление счетчика произошло слишком рано (за рамками разрешенного окна);
  • WWDG может генерировать предупреждающее прерывание непосредственно перед тем как сбросить микроконтроллер. Это позволяет программе запустить процедуру самодиагностики и предотвратить сброс.

Сторожевой таймер может автоматически запускаться после сброса микроконтроллера. Для этого необходимо установить опциональный бит WWDG_SW.

WWDG находится в замороженном состоянии в режиме STOP и в режиме отладки DEBUG.

На рисунке 24 подробно поясняется принцип работы WWDG. После запуска вычитающий счетчик начинает обратный отсчет от начального значения T[6:0] до 0x40. Если программа не обновила таймер, то при переходе от 0x40 к 0x3F будет сгенерирован сигнал сброса. При необходимости таймер может сгенерировать предупреждающее прерывание при счете 0x40.

Если обновление счетчика произошло слишком рано – за границами разрешенного окна, задаваемого W[6:0], также формируется сброс микроконтроллера. При этом никакого прерывания не генерируется.

Таким образом, чтобы безопасно сбросить счетчик, необходимо, чтобы в этот момент его значение находилось между W[6:0] и 0x3F.

Рис. 24. Принцип работы оконного сторожевого таймера WWDG

Рис. 24. Принцип работы оконного сторожевого таймера WWDG

По формуле 2 рассчитывается таймаут WWDG:

Таймеры общего назначения GPTIM

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

Микроконтроллеры STM32G4 имеют в своем составе несколько видов таймеров общего назначения GPTIM (таблица 8). Все они имеют общую архитектуру, но отличаются составом функциональных блоков и, следовательно – своими возможностями:

  • General-purpose – 16/32-битные таймеры общего назначения. Они имеют базовый набор функций и могут использоваться в различных приложениях для генерации сигналов, измерения времени, обработки сигналов с датчиков, например, с энкодеров или датчиков Холла.
  • Advanced – таймеры с расширенными возможностями и комплементарными выходами. Они предназначены для управления электродвигателями и многофазными инверторами.
  • Basic timers – базовые таймеры, не имеющие внешних выходов. Они используются для совместной работы с другими встроенными периферийными блоками микроконтроллера, например, с ЦАП или АЦП.

Таблица 8. Типы таймеров в STM32G4

Тип таймера Название
Advanced (с расширенным функционалом) TIM1, TIM8, TIM20
General purpose (общего назначения) 32-битные TIM2, TIM5
16-битные TIM3, TIM4
Basic (базовые) TIM6 и TIM7
Одноканальные
Двухканальные
Одноканальные с комплементарными выходами TIM16, TIM17
Двухканальные с комплементарными выходами TIM15

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

Блок-схема таймера TIM1 представлена на рисунке 25. Аналогичную структуру имеют таймеры TIM8 и TIM20. Базовым элементом таймера является 16-битный счетчик, который может по усмотрению пользователя считать вверх или вниз. В таймерах TIM2 и TIM5 счетчик является 32-битным. Период счета определяется регистром автозагрузки. Каждый раз, когда счетчик переполняется, таймер устанавливает флаг переполнения и может генерировать прерывание.

Рис. 25. Блок-схема таймера TIM1

Рис. 25. Блок-схема таймера TIM1

Тактирование таймера может осуществляться различными источниками:

  • внутренним тактовым сигналом CK_INT;
  • внешним тактовым сигналом со входа таймера или внутренним триггером;
  • внешним сигналом со входа ETR или внешним триггерным сигналом.

В режиме энкодера тактирование счетчика производится сигналами со входов TI1FP1 и TI2FP2.

ETR – триггерный сигнал, который может либо генерироваться цифровыми или аналоговыми компараторами, либо поступать на вывод ETR микроконтроллера.

Таймер TIM1 имеет шесть каналов, которые могут быть использованы для захвата внешних сигналов (кроме каналов 5 и 6), генерации ШИМ, генерации однократных импульсов.

Таймер TIM1 поддерживает функцию аварийного останова по приходу сигнала заданной полярности на входы TIM1_BKIN и TIM1_BKIN2. Эта функция позволяет безопасно остановить генерацию ШИМ при возникновении аварийной ситуации, например, при обнаружении КЗ в мощном инверторе.

Таймер TIM1 позволяет работать в режиме энкодера для обсчета датчиков положения, например, датчиков Холла.

Таймеры общего назначения могут синхронизироваться и работать совместно в режиме «ведущий/ведомый».

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

Малопотребляющий таймер LPTIM

LPTIM – 16-битный таймер, способный работать даже в режимах пониженного потребления. Это стало возможным благодаря использованию независимого тактирования. LPTIM имеет базовый функционал и может работать в качестве асинхронного счетчика даже при отсутствии источников тактирования.

Основными отличительными особенностями LPTIM являются:

  • возможность тактирования от LSE, LSI, HSI16 или pclk (сигнал тактирования шины APB);
  • возможность тактирования от внешнего источника, подключенного ко входу LPTIM_IN1. Это позволяет таймеру обеспечивать минимальное потребление при работе в качестве счетчика импульсов в таких приложениях как счетчики воды или газа;
  • поддержка до восьми внешних сигналов-триггеров с программируемой полярностью;
  • два режима работы: непрерывный и с однократным запуском.

На рисунке 26 изображена блок-схема LPTIM. В LPTIM используется двухдоменная система тактирования. Регистры управления тактируются сигналом pclk (шина APB). Основное ядро LPTIM использует отдельный тактовый сигнал: LSE, LSI, HSI16 или pclk. Кроме того, возможно тактирование ядра от внешнего сигнала, подаваемого на вход LPTIM_IN1. Основой LPTIM является 16-битный счетчик и набор 16-битных регистров: регистр автозагрузки LPTIM_ARR и регистр сравнения LPTIM_CMP.

Рис. 26. Блок-схема LPTIM

Рис. 26. Блок-схема LPTIM

Благодаря регистрам автозагрузки и сравнения LPTIM может генерировать ШИМ-сигнал с программируемым коэффициентом заполнения и однократные импульсы программируемой длительности. Кроме того, LPTIM может использоваться для обсчета квадратурных энкодеров.

LPTIM имеет возможность генерации следующих прерываний:

  • по совпадению (Compare Match). Возникает, когда содержимое счетчика LPTIM_CNT сравнивается или становится больше чем содержимое регистра сравнения LPTIM_CMP;
  • по совпадению с LPTIM_ARR (Auto-Reload Match). Возникает, когда содержимое счетчика LPTIM_CNT сравнивается с содержимым регистра LPTIM_ARR;
  • по триггеру (External Trigger Event). Возникает при обнаружении внешнего триггера;
  • по обновлению регистра LPTIM_ARR (Autoreload Register Write Completed). Возникает при обновлении регистра LPTIM_ARR;
  • по обновлению регистра LPTIM_CMP (Compare Register Write Completed). Возникает при обновлении регистра LPTIM_CMP;
  • при изменении направления счета (Direction Change). Возникает при изменении направления счета при работе LPTIM в режиме энкодера.

Таймер повышенного разрешения HRTIM

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

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

  • повышению плавности регулирования напряжения в традиционных повышающих и понижающих преобразователях;
  • точному управлению частотой и фазовым сдвигом в резонансных LLC-регуляторах и мостовых преобразователях.

В таблице 9 поясняются преимущества использования HRTIM по сравнению с обычными таймерами общего назначения.

Таблица 9. Сравнение возможностей таймеров HRTIM и TIMx

Параметр Таймер
TIMx HRTIM
Разрешение 5,9 нс 184 пс
Эквивалентная частота тактирования 170 МГц 5,44 ГГц
Разрешение ШИМ (ШИМ 300 кГц) 566 уровней (9,1 бит) 18133 (14,1 бит)
Шаг изменения частоты (ШИМ 300 кГц) 532 Гц 16,5 Гц

Высокое разрешение HRTIM обеспечивается особой схемой автоподстройки задержек (Delay‐Locked Loop, DLL), которая позволяет разделить входной тактовый сигнал на 32 части, что эквивалентно умножению частоты на 32. DLL может работать с диапазоном входных частот 100…170 МГц, обеспечивая разрешение выходного сигнала 184…312 пс. Пред началом работы схема DLL требует некоторого времени на самокалибровку.

Высокое разрешение HRTIM может использоваться для генерации выходных сигналов (периода или фазы ШИМ), но не для измерения входных сигналов. Для входных сигналов используется стандартная частота выборки 100…170 МГц.

Блок-схема HRTIM представлена на рисунке 27. На самом деле модуль HRTIM объединяет сразу семь 16-битных таймеров, которые способны работать вместе или независимо друг от друга. Каждый таймер использует индивидуальные параметры тактирования. 28 блоков сравнения и 12 блоков захвата помогают управлять 12 каналами.

Центральный блок мультиплексоров позволяет гибко управлять подключением выходом. С его помощью любой из каналов можно подключить к любому таймеру (как ведущему, так и ведомому) или ко входу внешнего события. Таким образом, каждый канал имеет 32 варианта подключения.

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

Контроллер режима Burst mode отвечает за управление при работе с малой нагрузкой и реализует функцию пропуска импульсов. Он также отвечает за сверхбыструю асинхронную защиту от аварийных ситуаций.

HRTIM может обрабатывать до 10 внешних событий и до 6 аварийных сигналов. Сигналы внешних событий обычно используются для своевременной корректировки параметров выходного сигнала, а аварийные сигналы необходимы для защиты внешних силовых каскадов. Благодаря сигналам событий HRTIM может работать совместно с другой периферией: АЦП, таймерами, ЦАП.

Рис. 27. Блок-схема HRTIM

Рис. 27. Блок-схема HRTIM

В составе HRTIM есть шесть одинаковых модулей таймеров. Основой каждого из них является 16-битный инкрементирующий счетчик с программируемым периодом. Кроме того, в состав таймеров входят по два 16-битных регистра захвата и по четыре 16-битных регистра сравнения. Несколько регистров сравнения позволяют генерировать несколько событий в течение одного периода ШИМ.

Счетчики могут работать в одном из двух режимов:

  • Непрерывный режим (Continuous mode). При достижении верхнего значения, заданного в регистре HRTIM_PERxR, счетчик сбрасывается и начинает считать заново. Сброс возможен и по внешнему сигналу. Первый вариант используется для ШИМ постоянной частоты, а второй – для генерации ШИМ переменной частоты. Это самый простой и наиболее широко используемый режим.
  • Режим однократного запуска (Single‐Shot mode). В данном случае счетчик считает от 0 до заданного порогового значения и останавливается. Далее возможны два варианта. В режиме Non‐Retriggerable mode сигналы сброса игнорируются до окончания счета. В режиме Retriggerable mode счетчик может быть сброшен в любое время.

HRTIM может работать в режиме Half mode, в котором он автоматически поддерживает коэффициент заполнения ШИМ 50%. Это очень полезный режим для резонансных преобразователей, в которых используется переменная частота и постоянный коэффициент заполнения.

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

Каждый выход имеет три конфигурационных бита: OEN, ODIS и ODS. Включение выхода осуществляется с помощью бита OEN, отключение – с помощью бита ODIS. Бит ODS сигнализирует об отключении выхода при возникновении авариного сигнала.

HRTIM является источником 100 прерываний. Восемь векторов прерываний генерирует ведущий таймер и по 12 прерываний – остальные таймеры.

HRTIM может генерировать запросы DMA от 91 источника. Всего для него выделено по одному каналу DMA для каждого встроенного таймера.

HRTIM может использоваться только в режимах Run, Low Power Run, Sleep и Low Power Sleep.

Подробную информацию о работе и особенностях HRTIM можно получить из документа AN4539 Application note HRTIM cookbook.

Часы реального времени RTC

Модуль часов реального времени RTC имеет функцию календаря и может работать во всех режимах пониженного потребления. При тактировании от LSE 32768 Гц RTC может использоваться даже в режиме VBAT, при котором основное питание микроконтроллера отключено.

RTC потребляет всего 300 нА при 1,8 В с учетом потребления LSE. Встроенный календарь представляет данные в BCD-формате, чтобы максимально снизить нагрузку на программу. Еще одной особенностью RTC является защита дежурных регистров от взлома (TAMPER).

Главными отличительными чертами RTC являются:

  • календарь с измерением долей секунд, секунд, минут, часов, дней недели, дат, месяцев и лет. Представление данных идет в BCD-формате;
  • возможность коррекции летнего времени;
  • два программируемых пробуждающих сигнала, позволяющих выводить процессор из режимов пониженного потребления;
  • пробуждающий таймер, позволяющий генерировать периодические прерывания с заданным периодом;
  • возможность откалибровать календарь с помощью сигналов 50 или 60 Гц;
  • встроенная цифровая калибровка, позволяющая компенсировать погрешность кварцевого резонатора и повышать точность до 0,95 ppm;
  • возможность формирования временных меток.

На рисунке 28 представлена блок-схема RTC. Для тактирования RTC используются два источника: RTCCLK (для тактирования счетчика RTC) и PCLK (для тактирования регистров). В качестве RTCCLK могут выступать LSE, HSE/32, LSI. Для работы в режиме Stop или Standby тактирование ядра RTC может производиться только от LSE или LSI. В режиме VBAT тактирование RTC возможно только от LSE.

Входной тактовый сигнал RTCCLK дополнительно делится с помощью 7-битного асинхронного делителя, на выходе которого генерируется тактовый сигнал ck_arpe. Большинство блоков RTC тактируется именно от сигнала ck_arpe. Если необходимо уменьшить потребление RTC – следует выбирать максимальное значение делителя (по умолчанию 128). Еще один 15-битный делитель используется для получения сигнала ck_spre clock. Этот сигнал необходим для измерения временных интервалов в часах и календаре, поэтому он должен иметь частоту 1 Гц. Субсекундные интервалы измеряются с помощью сигнала ck_arpe. Кроме основных регистров в RTC есть теневые дублирующие регистры.

RTC имеет два выхода, на которые можно вывести сигналы пробуждения, флаг пробуждения, калибровочный тактовый сигнал, сигнал системы защиты от взлома.

Регистры управления RTC подключены к шине APB и тактируются сигналом PCLK.

Рис. 28. Блок-схема RTC

Рис. 28. Блок-схема RTC

Для инициализации RTC используется особый безопасный метод. Регистры RTC по умолчанию защищены от записи. Для разрешения записи необходимо установить бит DBP (Backup Domain Protection) в регистре PWR_CR. После этого необходимо выполнить инициализацию по специальному алгоритму.

Календарь RTC продолжает работу во всех режимах, даже когда микроконтроллер находится в состоянии сброса. Инициализация регистров даты и времени выполняется с помощью теневых регистров, подключенных к шине APB. Регистр субсекундных интервалов не может быть инициализирован.

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

Если бит BYPSHAD сброшен, то при запросе чтения содержимое рабочих регистров сначала копируется в теневые регистры, откуда в дальнейшем и происходит чтение. При этом гарантируется, что содержимое всех регистров относится к одному моменту времени. Другими словами, при чтении регистров RTC_SSR или RTC_TR содержимое счетных регистров защелкивается в теневых регистрах одновременно. Перезапись их содержимого возможна только после чтения регистра RTC_DR. Недостаток этого варианта заключается в том, что после выхода из режимов Stop, Standby или Shutdown программе приходится выжидать дополнительное время, необходимое для синхронизации рабочих и теневых регистров.

Календарь RTC имеет несколько важных особенностей:

  • возможность автоматического перехода на летнее время;
  • синхронизация с внешним тактовым сигналом;
  • функция обнаружения опорного сигнала (50 или 60 Гц) для обеспечения длительной стабильности измерений;
  • установка временных меток по приходу внешнего сигнала при переходе к VBAT в случае обнаружения взлома. Если временная метка не была считана, до появления следующей временной метки устанавливается флаг переполнения TSOVF.

RTC может генерировать сигналы пробуждения (Alarm) при достижении счетчиком RTC предустановленных значений. Эти сигналы способны пробуждать процессорное ядро из любого режима пониженного потребления. Кроме того, сигналы пробуждения можно вывести на выход RTC_OUT и использовать для управления внешними микросхемами.

RTC позволяет генерировать автоматические сигналы пробуждения с помощью встроенного 16-битного счетчика. Содержимое этого счетчика не может быть считано пользователем. Тактирование счетчика выполняется сигналом RTCCLK, который дополнительно делится на 2/4/8/16. Благодаря этому период пробуждения может быть запрограммирован на время 122 мкс…32 с (при тактировании RTC от LSE).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *