реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32F407 Synchronizing the RTC
Pridnya
сообщение Jun 10 2016, 12:55
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159



Здравствуйте!

Есть два макета, оба на STM32F407, в обоих включен RTC, тактирование от внешнего LSE-кварца 32768 Гц.

Код инициализация RTC
Код
void initRTC(void)
{
RTC_InitTypeDef RTC_InitStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

    PWR_BackupAccessCmd(ENABLE);  
    
    RCC_LSEConfig(RCC_LSE_ON);        
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {;}    
                    
    RCC_RTCCLKCmd(ENABLE);    
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

    RTC_CalibOutputConfig(RTC_CalibOutput_1Hz); // 1 Hz            
    RTC_CalibOutputCmd(ENABLE);    
    
    RTC_StructInit(&RTC_InitStructure);
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
    //RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
    //RTC_InitStructure.RTC_SynchPrediv = 0xFF;
    RTC_InitStructure.RTC_AsynchPrediv = 0x0F;
    RTC_InitStructure.RTC_SynchPrediv = 0x7FF;
    RTC_Init(&RTC_InitStructure);    
    
    PWR_BackupAccessCmd(DISABLE);
}

Т.е. изменил значения предделителей. Суммарный коэффициент деления остался неизменным. На выходе PC13 место 1Гц получаю 8Гц, т.е. частота LSE делится сначала на 16, а затем на 256, поэтому 8Гц. Должна делиться на 2048.

Субсекунды при этом идут как положено RTC_SSR изменяется с 2047 до 0, т.е. с 0 до 999 мс.

PS: вопрос возник в связи с тем, что когда оба предделителя по умолчанию, то частота на выходе PC13 равна 1Гц и этими импульсами можно синхронизировать часы другого микроконтроллера (по внешнему прерыванию 1 импульс в секунду). А тут 8Гц. В RM0090 нарисовано, что частота 1Гц формируется с выхода синхронного предделителя. При дефолтных предделителях оба модуля RTC синхронизируются (в обработчике внешнего прерывания читаем RTC_SSR и корректируем RTC_SHIFTR), часы идут с точностью до 0,01 сек на дисплее (разрешающая способность по субсекундам равна 1/(PREDIV_S+1), т.е. 3,9 мс).

Сообщение отредактировал Pridnya - Jun 10 2016, 13:21
Go to the top of the page
 
+Quote Post
Pridnya
сообщение Jun 15 2016, 19:40
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159



Кому интересно, результат пока такой: опорные часы на 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. Во всех этих документах методика отличается. Как-то плохо описан процесс.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Pridnya
сообщение Jun 16 2016, 10:56
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159



Цитата(Pridnya @ Jun 15 2016, 22:40) *
а отстающие периодически (1 раз в 8 секунд, после коррекции) показывают время в миллисекундах .000 примерно на полсекунды, а потом идут тоже с точностью 0,001 сек.

Оказывается, что после сдвига значение регистра SSR может превышать значение синхронного счетчика PREDIV_S (он равен 0x7FF), а я это не учел в формуле, которая переводит субсекунды в миллисекунды. Получилось, что для всех значений, больших PREDIV_S миллисекунды равны нулю, а затем расчитываются правильно.
CODE
//SecondFraction = (float)( PREDIV_S - SSR ) / ( PREDIV_S + 1 );
uint32_t SSR = 2058; // Субсекунды.
uint32_t SS = 0; // Тысячные доли.
do
{
float Second_fraction = 0;
Second_fraction = (float)( 2047.0F - (float)SSR ) / ( 2048.0F );
printf("SSR=%d",SSR);
printf(" ");
printf("Second_fraction=%f",Second_fraction);
Second_fraction *= 1000.0F;
SS = Second_fraction;
printf(" ");
printf("SS=%d\n",SS);
SSR--;
}
while(SSR>2028);

SSR=2058 Second_fraction=-0.005371 SS=0
...
SSR=2049 Second_fraction=-0.000977 SS=0
SSR=2048 Second_fraction=-0.000488 SS=0
SSR=2047 Second_fraction=0.000000 SS=0
SSR=2046 Second_fraction=0.000488 SS=0
SSR=2045 Second_fraction=0.000977 SS=0
SSR=2044 Second_fraction=0.001465 SS=1
SSR=2043 Second_fraction=0.001953 SS=1
SSR=2042 Second_fraction=0.002441 SS=2
SSR=2041 Second_fraction=0.002930 SS=2
SSR=2040 Second_fraction=0.003418 SS=3
SSR=2039 Second_fraction=0.003906 SS=3
SSR=2038 Second_fraction=0.004395 SS=4
SSR=2037 Second_fraction=0.004883 SS=4
SSR=2036 Second_fraction=0.005371 SS=5
SSR=2035 Second_fraction=0.005859 SS=5
SSR=2034 Second_fraction=0.006348 SS=6
SSR=2033 Second_fraction=0.006836 SS=6
SSR=2032 Second_fraction=0.007324 SS=7
SSR=2031 Second_fraction=0.007812 SS=7
SSR=2030 Second_fraction=0.008301 SS=8
SSR=2029 Second_fraction=0.008789 SS=8

В рабочий журнал добавил запись до сдвига и после. Видно, что после сдвига время на 1 секунду больше, при этом RTC_SSR превышает PREDIV_S, равен 0xFFA. Об этом упоминается в RM0090, в описании RTC_SSR
Цитата
Note: SS can be larger than PREDIV_S only after a shift operation. In that case, the correct
time/date is one second less than as indicated by RTC_TR/RTC_DR.

Код
// Субсекунды 0-2047 (разрешение 0,00049 сек)
ssr = RTC_GetSubSecond();  // Читаем до сдвига.
If() {...}
else  // Если часы модуля RTC отстают.
{
  AddSystemEvent(0xC000|ssr); // ssr=2, (2047-ssr/2048)=.998        
  PWR_BackupAccessCmd(ENABLE);
  stat = RTC_SynchroShiftConfig(RTC_ShiftAdd1S_Set, 2048-ssr); //2048-2=2046
  PWR_BackupAccessCmd(DISABLE);
  ssrs = RTC_GetSubSecond();
  AddSystemEvent(0xC000|ssrs);            
}

Не совсем понимаю, а как в этом случае получить корректное время и что происходит с RTC_SSR, пока его значение больше PREDIV_S?

Сообщение отредактировал IgorKossak - Jun 16 2016, 14:01
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!

Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 16 2016, 12:00
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Немного не в тему, конечно, но синхронизировать часы по RS485, это не самый точный способ. А использовать ds1306 вообще странновато, на мой взгляд. Я конечно не знаю полного техзадания ...
На своих образцах калибровал часы. Можно добиться точности пару секунд в месяц. Собственно реальная точность указана в руководстве по эксплуатации.
Если требуется совместная работа (то есть взаимная синхронизация) то лучше синхронизировать по какому-нибудь высокоскоростному интерфейсу. Обычно используется GPS, либо ethernet.
Go to the top of the page
 
+Quote Post
Pridnya
сообщение Jun 16 2016, 12:32
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159



Цитата(SasaVitebsk @ Jun 16 2016, 15:00) *
Немного не в тему, конечно, но синхронизировать часы по RS485, это не самый точный способ. А использовать ds1306 вообще странновато, на мой взгляд. Я конечно не знаю полного техзадания ...
На своих образцах калибровал часы. Можно добиться точности пару секунд в месяц. Собственно реальная точность указана в руководстве по эксплуатации.
Если требуется совместная работа (то есть взаимная синхронизация) то лучше синхронизировать по какому-нибудь высокоскоростному интерфейсу. Обычно используется GPS, либо ethernet.

Это только модель, в которой DS1306 формирует сигнал 1PPS (эмулятор импульсов с высокой точностью по времени). По RS485 часы синхронизируются с точностью до секунд (широковещательным запросом), а по сигналу 1PPS синхронизируются с точностью до миллисекунд. На практике желающие смогут использовать хоть сервер точного времени, хоть другую какую коробку с 1PPS. Хоть простой маячок с GPS и выходом 1PPS.

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

Всем спасибо! Вопрос решен.
Все просто: после сдвига вперед, в случае, если RTC_SSR превышает (PREDIV_S+1) нужно из RTC_SSR вычесть (PREDIV_S+1), а затем преобразовать остаток в миллисекунды. И из секунд вычесть 1 секунду. И часы синхронизируются до тысячной доли. Это как раз этот случай.
Цитата
Note: SS can be larger than PREDIV_S only after a shift operation. In that case, the correct
time/date is one second less than as indicated by RTC_TR/RTC_DR.


Сообщение отредактировал Pridnya - Jun 16 2016, 13:21
Go to the top of the page
 
+Quote Post
Sekat
сообщение Jun 23 2016, 12:54
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 13-02-12
Пользователь №: 70 242



Цитата(Pridnya @ Jun 16 2016, 15:32) *
Это только модель, в которой DS1306 формирует сигнал 1PPS (эмулятор импульсов с высокой точностью по времени). По RS485 часы синхронизируются с точностью до секунд (широковещательным запросом), а по сигналу 1PPS синхронизируются с точностью до миллисекунд. На практике желающие смогут использовать хоть сервер точного времени, хоть другую какую коробку с 1PPS. Хоть простой маячок с GPS и выходом 1PPS.


1PPS от GPS модуля позволяет синхронизировать внутренние часы на STM32F407 с точностью до ~200нс (нано) . Для этого нужно использовать PTP таймер.
Тогда схема синхронизации времени выглядит так. Основные часы - PTP таймер, синхронизируемый по 1PPS в пределах 1 секунды. Через какой-нибудь интерфейс (485, ETHERNET и т.д.) происходит грубая установка времени (дата/минуты/секунды). Периодически время пересчитывается и переписывается из PTP таймера в RTC. RTC используются как основные часы, когда устройство отключено и при включении питания время перезаписывается из RTC в PTP.
Go to the top of the page
 
+Quote Post
Pridnya
сообщение Jul 8 2016, 07:20
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159



Цитата(Sekat @ Jun 23 2016, 15:54) *
1PPS от GPS модуля позволяет синхронизировать внутренние часы на STM32F407 с точностью до ~200нс (нано) . Для этого нужно использовать PTP таймер.
Тогда схема синхронизации времени выглядит так. Основные часы - PTP таймер, синхронизируемый по 1PPS в пределах 1 секунды. Через какой-нибудь интерфейс (485, ETHERNET и т.д.) происходит грубая установка времени (дата/минуты/секунды). Периодически время пересчитывается и переписывается из PTP таймера в RTC. RTC используются как основные часы, когда устройство отключено и при включении питания время перезаписывается из RTC в PTP.

Спасибо! Я пока с PTP-протоколом не работал, слишком уж он точный (как мне показалось), а такой точности мне не требуется, да и на практике обеспечить её практически не возможно, нужно дорогостоящее оборудование (сервер точного времени, дорогие коммутаторы...)
На практике все немного не так: например, один из производителей (можно сказать, ведущий российский производитель РЗА) заявляет поддержку синхронизации времени по множеству протоколов, в т.ч. и по PTP, очень умные сразу понимают, что это означает точность в микросекундах , менее умные читают отдельный документ "про синхронизацию", а там что-то типа такого
Делаем вывод: на практике достаточно 1 мс.

Сообщение отредактировал Pridnya - Jul 8 2016, 07:21
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 15:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01438 секунд с 7
ELECTRONIX ©2004-2016