AHTOXA 14 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Понадобилось мне время поточнее. В новом 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(!). Возможно и более, я не очень долго смотрел. Внимание, вопрос: почему так? Что я сделал не так? Кто-нибудь сталкивался с таким? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Внимание, вопрос: почему так? Что я сделал не так? Кто-нибудь сталкивался с таким? как то странно пытаться использовать внутренний RTC для быстрого чтения времени.... Не знаю как точно это устроено в STM32, но в других МК, в которых я работал с внутренним RTC, он находится в отдельном домене питания и связь этого домена с системным доменом - последовательная. Т.е. RTC считает в своём домене, а при запросах чтения/записи IO-регистров RTC данные от него/к нему передаются через последовательный канал, что приводит к выставлению сигнала HALT ядру до момента завершения передачи. И передача может достигать нескольких сотен системных тиков (в зависимости от частоты ядра). Соответственно и время выполнения такой команды. Так сделано по-крайней мере в МК Infenion и Tiva и сиё подробно расписано в даташитах. Сильно подозреваю что в STM32 дела обстоят аналогично. Если действительно нужно быстро читать из часов реального времени, то можно задействовать любой general purpose timer, засинхронизировать его по edge секундного прерывания от RTC и работать уже с его счётчиком. Периодически подсинхронизируя этот таймер с RTC методом ФАПЧ. Тогда и доли секунд и даже микросекунды реально будет получить без всяких задержек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Неужели никто не сталкивался с таким? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mcheb 0 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Неужели никто не сталкивался с таким? если поделить на 31 то получается 1057 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Не, там и больше бывает. Сейчас вот увидел 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 Видно, что счётчик этот перезаряжается раньше, чем перещёлкиваются секунды. И непонятным значением. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Неужели никто не сталкивался с таким? Не применял дробную часть, нужды не было. Сейчас под отладчиком посмотрел что в STM32L1 в SSR при стандартных делителях 128+256: как и ожидалось, диапазон от 0 до 0xFF. Так что может у вас, действительно, асинхронный делитель на 31 делит? Кстати, а есть ли смысл в чтении дробной части? С "теневыми регистрами" вроде смысла нет. Если их отключить (BYPSHAD=1), то все равно читать нужно минимум дважды для исключения попадания на фронт клока, когда читаться будет лабуда. Точности нет... как то странно пытаться использовать внутренний RTC для быстрого чтения времени.... Не знаю как точно это устроено в STM32, но в других МК, в которых я работал с внутренним RTC, он находится в отдельном домене питания и связь этого домена с системным доменом - последовательная. Т.е. RTC считает в своём домене, а при запросах чтения/записи IO-регистров RTC данные от него/к нему передаются через последовательный канал, что приводит к выставлению сигнала HALT ядру до момента завершения передачи. И передача может достигать нескольких сотен системных тиков (в зависимости от частоты ядра). Соответственно и время выполнения такой команды. Так сделано по-крайней мере в МК Infenion и Tiva и сиё подробно расписано в даташитах. Сильно подозреваю что в STM32 дела обстоят аналогично. В STM32 домены питания тоже разные, но шина между ними параллельная. Читается быстрее, но тоже есть ограничение на частоты доменов, присутствуют "теневые регистры", куда периодически копируется синхронная копия даты/времени, которая у них сбоит - errata :) , разные флаги синхронизации. Т.е. тоже - не подарок... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Так, с диапазоном разобрался: перепутал частоту внешнего кварца и внутреннего :) Осталась проблема перескока счётчика субсекунд до переключения секунды: 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], стало вообще отлично. Спасибо всем, кто поучаствовал в обсуждении! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба В STM32 домены питания тоже разные, но шина между ними параллельная. Читается быстрее, но тоже есть ограничение на частоты доменов, присутствуют "теневые регистры", куда периодически копируется синхронная копия даты/времени, которая у них сбоит - errata :) , разные флаги синхронизации. Т.е. тоже - не подарок... Если нужны доли секунды то лучше вообще не использовать чтение регистров RTC. А синхронизировать работу одного из таймеров общего назначения с секундным импульсом. Делал так, получал дискретность времени до мкс. Секундные импульсы брал с внешнего высокоточного генератора. И постоянно подсинхронизировал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 23 мая, 2018 Опубликовано 23 мая, 2018 (изменено) · Жалоба Для системы старт-финиш, синхронизирующейся по pps от GPS, я делал автоподстройку таймера. В данном случае тоже можно завести отдельный таймер, который автоподстраивать периодически по RTC. И будут вам и милли, и микросекунды при желании! // плохо читаю комментарии, выше уже как раз-таки это посоветовали. Изменено 23 мая, 2018 пользователем Эдди Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба Если контроллер в основном глубоко спит, и просыпается на десятки-сотни миллисекунд, то таймеры никак не помогут. А RTC с миллисекундами - очень даже удобен. Кстати, и будильник можно зарядить с точностью до миллисекунд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться