|
|
|
Как правильно получать доли секунд от RTC STM32? |
|
|
|
May 22 2018, 19:47
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Понадобилось мне время поточнее. В новом RTC у тех STM-ок, что поновее (вроде бы у всех, кроме F1) есть специальный регистр для этого - SSR. Также есть два предделителя: синхронный и асинхронный. Делаю такую инициализацию: Код static constexpr unsigned quartzFreqHz = 32768; // частота кварца static constexpr unsigned asyncPrediv = 0x1F; // асинхронный предделитель static constexpr unsigned syncPrediv = quartzFreqHz / (asyncPrediv + 1) - 1; // синхронный предделитель ..... RTC->PRER = syncPrediv; RTC->PRER |= asyncPrediv << 16; После этого я ожидаю, что в регистре SSR будут значения от 0 до 32768/(asyncPrediv+1) = 1024. Однако, запустив цикл вывода значений SSR на печать, я наблюдаю там числа от 0 до 1055(!). Возможно и более, я не очень долго смотрел. Внимание, вопрос: почему так? Что я сделал не так? Кто-нибудь сталкивался с таким?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 22 2018, 21:40
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(AHTOXA @ May 22 2018, 22:47) Внимание, вопрос: почему так? Что я сделал не так? Кто-нибудь сталкивался с таким? как то странно пытаться использовать внутренний RTC для быстрого чтения времени.... Не знаю как точно это устроено в STM32, но в других МК, в которых я работал с внутренним RTC, он находится в отдельном домене питания и связь этого домена с системным доменом - последовательная. Т.е. RTC считает в своём домене, а при запросах чтения/записи IO-регистров RTC данные от него/к нему передаются через последовательный канал, что приводит к выставлению сигнала HALT ядру до момента завершения передачи. И передача может достигать нескольких сотен системных тиков (в зависимости от частоты ядра). Соответственно и время выполнения такой команды. Так сделано по-крайней мере в МК Infenion и Tiva и сиё подробно расписано в даташитах. Сильно подозреваю что в STM32 дела обстоят аналогично. Если действительно нужно быстро читать из часов реального времени, то можно задействовать любой general purpose timer, засинхронизировать его по edge секундного прерывания от RTC и работать уже с его счётчиком. Периодически подсинхронизируя этот таймер с RTC методом ФАПЧ. Тогда и доли секунд и даже микросекунды реально будет получить без всяких задержек.
|
|
|
|
|
May 23 2018, 09:30
|
Местный
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602
|
Цитата(AHTOXA @ May 23 2018, 12:20) Неужели никто не сталкивался с таким? если поделить на 31 то получается 1057
|
|
|
|
|
May 23 2018, 10:11
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Не, там и больше бывает. Сейчас вот увидел 1214. Вот что получается, читаю примерно раз в 100 мс: Код 03:26:39,1050 03:26:39,945 03:26:39,839 03:26:39,734 03:26:39,629 03:26:39,523 03:26:39,418 03:26:39,312 03:26:39,207 03:26:39,102 03:26:39,1214 03:26:40,1109 03:26:40,1003 03:26:40,898 03:26:40,793 03:26:40,687 03:26:40,582 03:26:40,477 03:26:40,371 03:26:40,266 03:26:40,160 03:26:40,55 03:26:40,1168 03:26:41,1062 03:26:41,957 Видно, что счётчик этот перезаряжается раньше, чем перещёлкиваются секунды. И непонятным значением.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 23 2018, 10:17
|
Просто Che
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881
|
Цитата(AHTOXA @ May 23 2018, 12:20) Неужели никто не сталкивался с таким? Не применял дробную часть, нужды не было. Сейчас под отладчиком посмотрел что в STM32L1 в SSR при стандартных делителях 128+256: как и ожидалось, диапазон от 0 до 0xFF. Так что может у вас, действительно, асинхронный делитель на 31 делит? Кстати, а есть ли смысл в чтении дробной части? С "теневыми регистрами" вроде смысла нет. Если их отключить (BYPSHAD=1), то все равно читать нужно минимум дважды для исключения попадания на фронт клока, когда читаться будет лабуда. Точности нет... Цитата(jcxz @ May 23 2018, 00:40) как то странно пытаться использовать внутренний RTC для быстрого чтения времени.... Не знаю как точно это устроено в STM32, но в других МК, в которых я работал с внутренним RTC, он находится в отдельном домене питания и связь этого домена с системным доменом - последовательная. Т.е. RTC считает в своём домене, а при запросах чтения/записи IO-регистров RTC данные от него/к нему передаются через последовательный канал, что приводит к выставлению сигнала HALT ядру до момента завершения передачи. И передача может достигать нескольких сотен системных тиков (в зависимости от частоты ядра). Соответственно и время выполнения такой команды. Так сделано по-крайней мере в МК Infenion и Tiva и сиё подробно расписано в даташитах. Сильно подозреваю что в STM32 дела обстоят аналогично. В STM32 домены питания тоже разные, но шина между ними параллельная. Читается быстрее, но тоже есть ограничение на частоты доменов, присутствуют "теневые регистры", куда периодически копируется синхронная копия даты/времени, которая у них сбоит - errata , разные флаги синхронизации. Т.е. тоже - не подарок...
|
|
|
|
|
May 23 2018, 10:59
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Так, с диапазоном разобрался: перепутал частоту внешнего кварца и внутреннего Осталась проблема перескока счётчика субсекунд до переключения секунды: Код 00:00:05,408 00:00:05,303 00:00:05,198 00:00:05,92 00:00:05,1011 << вот здесь! 00:00:06,905 00:00:06,800 Думаю, это сейчас тоже победю, изменив последовательность чтения... ---- Добавлено: Да, всё, порядок. Если читать сначала субсекунды, а потом время, то получается консистентно. Добавил масштабирование [1023..0] -> [0..999], стало вообще отлично. Спасибо всем, кто поучаствовал в обсуждении!
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|