Кому интересно, результат пока такой: опорные часы на DS1306 формируют сигнал 1PPS с выхода 1Hz микросхемы. Этот сигнал поступает на два микроконтроллера и на вход PB15, по фронту импульса 1PPS попадаем в обработчик внешнего прерывания (EXTI), в прерывании опрашиваем регистр SSR, если он имеет не нулевое значение, то подводим часы в ту или иную сторону. Кварцы подобраны так, что часы RTC1 спешат, а RTC2 отстают относительно опорных.
Широковещательным запросом по RS485 задаем время с компьютера, до секунд, при записи нового времени регистр SSR у обоих микроконтроллеров обнуляется, но затем с течением времени появляется расхождение. Время идет с точностью в 0,001 сек на RTC1 и на RTC2. Спешащие часы всегда переводятся назад (через RTC_SHIFTR) и идут правильно, а отстающие периодически (1 раз в 8 секунд, после коррекции) показывают время в миллисекундах .000 примерно на полсекунды, а потом идут тоже с точностью 0,001 сек.
Код обработчика внешнего прерывания такой:
Код
// Для PREDIV_S равного 2048.
ssr = RTC_GetSubSecond(); // Читаем до сдвига.
if(ssr)
{
if(ssr>1023) // Если часы модуля спешат (Работает правильно).
{
// Delay (seconds) = SUBFS / ( PREDIV_S + 1 )
status = RTC_SynchroShiftConfig(RTC_ShiftAdd1S_Reset, 2047-ssr+1); // Переводим время назад.
}
else // Если часы модуля отстают.
{
// Advance (seconds) = ( 1 - ( SUBFS / ( PREDIV_S + 1 ) ) )
status = RTC_SynchroShiftConfig(RTC_ShiftAdd1S_Set, 2047-ssr+1); // Переводим время вперед.
}
}
Кто что посоветует?
PS: Читал RM0090, AN3371, AN3133. Во всех этих документах методика отличается. Как-то плохо описан процесс.
Эскизы прикрепленных изображений