STM32 RTC, Calendar.
Начнем с того, что RTC — это аббревиатура которая расшифровывается следующим образом Real-time clock или по-русски, часы реального времени. В былые времена, при использовании МК AVR в качестве RTC, использовал отдельную микросхему, общение с которой происходило по определенному протоколу. У STM32 RTC же представляет собой модуль, реализованный внутри МК.
- Автоматическое пробуждение во всех режимах энергосбережения
- Независимый BCD таймер счетчик. Отсчет времени и календарь реализованы аппаратно, с возможностью настройки сигнализирующих прерываний.
- Программный флаг пробуждения с возможностью вызова прерывания.
- Два 32-х разрядных регистра, в которых хранятся секунды, минуты, часы(в 12 часовом или 24 часовом формате), день недели, день месяца, месяц и год. Секунды хранятся в двоичном формате, все остальное в двоично-десятичном.
- Компенсация длинны месяца(а также високосного года) выполняется автоматически. Также возможна компенсация летнего времени.
- Два 32-х разрядных регистра программируемых сигнализирующих прерываний.
- Наличие калибровки для компенсации отклонения кварцевого резонатора.
- После сброса область RTC защищена от случайной записи.
- До тех пор пока напряжение питания RTC остается в рабочем диапазоне, он будет работать в не зависимости от режима работы(Run mode, low-power mode or under reset).
- Для повышения точности, можно синхронизировать часы с сетью 50 или 60Hz.
- Возможно записывать время возникновения события, так называемый Time-stamp.
- Определение вмешательства(tamper), при этом сбрасываются все backup регистры.
- Alarm A
- Alarm B
- Wakeup interrupt
- Time-stamp
- Tamper detection
В качестве примера предлагаю рассмотреть как запустить часы и настроить календарь, но перед этим рассмотрим внутреннюю структуру RTC.
- LSI — низкочастотный внутренний RC-генератор на 40 KHz.
- LSE — внешний, «часовой» кварцевый резонатор на 32 768 Hz.
- HSE/32 — внешний высокочастотный кварцевый резонатор с предделителем 32.
LSEON(LSE oscillator enable) — включение LSE.
LSERDY(LSE oscillator ready) — флаг готовности LSE.
LSEBYP(LSE oscillator bypass) — единица в этом бите позволяет тактировать RTC от внешнего источника. Внешний тактовый сигнал (меандр, синус или треугольник) со скважностью 50% подаётся только на вывод OSC32_IN, при этом вывод OSC32_OUT можно использовать в качестве GPIO.
- 00: нижний
- 01: между нижним и средним
- 10: между средним и высоким
- 11: высокий, значение по умолчанию
- 01: LSE выступает в качестве источника.
- 10: LSI выступает в качестве источника.
- 11: HSE/32 выступает в качестве источника.
BDRST(Backup domain software reset) — единица в этом бите полностью сбрасывает значение Backup domain.
После того как выбран источник тактирования необходимо позаботится о том, чтобы счетные регистры RTC тактировались с частотой один 1Hz. Для понижения частоты тактирования до 1Hz предназначены два предделителя, синхронный и асинхронный.
Изначально значения PREDIV_A = 127, PREDIV_S = 255, что позволяет из 32768 Hz получить 1 Hz .
Для установки времени выделен один 32-x битный регистр, разбитый на битовые поля.
Данные в нем хранятся в формате BCD, при чем единицы и десятки в отдельных битовых полях. Думаю пояснения требует только бит PM, отвечающий за формат хранения часов. Если в нем установлен ноль, часы будут тикать от 0 до 24 часов, если единица – от 1 до 12.
С датой все аналогично, она хранится в 32-х битном регистре, разбитом на битовые поля.
Ниже приведен код настройки и запуска часов для STM32F303.
В случае если RTC тактируется от внешнего кварца, необходимо инициализацию LSI заменить следующим кодом.
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.
На этом всё.
Всем спасибо
Русские Блоги
После просмотра официального демо ST RTC_Tamper
На официальной плате STM32H743I-EVAL2 проверьте и поймите точки знаний, показанные в демонстрации.
Точки знаний, показанные в демонстрации RTC_Tamper, — это чтение и запись в регистр RTC STM32H743 и реакция обнаружения вторжения.
Эти 3 точки знаний очень полезны. Вы можете хранить некоторые конфиденциальные секреты в регистре RTC, и вы не хотите, чтобы за вами шпионили. Когда вы обнаружите, что дело открыто, вы можете взять некоторые Саморазрушающие меры.
Я перестроил проект с CubeMx с нуля, чтобы завершить чтение и запись регистров RTC и реализацию ответа на обнаружение вторжений.
Для этого эксперимента необходимо установить 2 контакта с помощью CubeMx.
Контакт обнаружения вторжения PC13 RTC
Когда я впервые начал эксперимент, я все еще не понимал, почему кнопка PC13 будет вводить ответ обнаружения вторжения.
Позже я хотел понять, что это аппаратная реализация (поскольку PC13 является контактом обнаружения вторжения RTC), пока PC13 обозначен как RTC_TAMP1, нажатие PC13 приведет к прерыванию обнаружения вторжения RTC ответ.
Светодиодный индикатор
Когда программа работает на полной скорости и работает без STLINK, если вы хотите увидеть разницу до и после обнаружения вторжения, вам понадобится хотя бы одна инструкция.
Настройки STM32CubeMX
Настройки прерывания при обнаружении вторжений
Также необходимо выбрать соответствующее прерывание, иначе функция ответа на прерывание при обнаружении вторжения отсутствует.
Псевдоним настройки PIN-кода
PF10 — это светодиод.После установки псевдонима PORT и PIN псевдонима будут автоматически использоваться при инициализации этого вывода в CubeMx, который имеет лучшую ремонтопригодность. Нам не нужно самостоятельно определять макрос псевдонима вывода.
Предварительный просмотр проекта реконструирован с помощью CubeMx
подводить итоги
Инженерная структура, созданная CubeMx, действительно чиста.
Из демонстрационного проекта мы действительно можем увидеть разницу между поставщиками восходящего и нижнего звена.
Производители апстрима продают микросхемы, и они подробно расскажут о функциях и характеристиках микросхем, привлекая пользователей к покупке микросхем для продуктов.
Последующие производители продают платы и решения для разработки, и они с меньшей вероятностью расскажут пользователям подробности. Все они посвящены основам и основным моментам. Предполагается, что энергия и стоимость недопустимы.
Даже на демонстрационных примерах исходных производителей, если вы внимательно следите за пошаговыми инструкциями, вы все равно можете увидеть код отходов.
например, если RTC инициализируется, устанавливаются следующие параметры
Когда происходит обнаружение вторжения, содержимое регистра RTC было очищено оборудованием, и нет необходимости явно вызывать HAL_RTCEx_DeactivateTamper ()