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

 
 
> Точная синхронизация RTC в STM32F4
athlon64
сообщение Nov 23 2012, 11:41
Сообщение #1


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Необходимо реализовать синхронизацию даты/времени в устройстве с внешним хостом (по SNTP и другим протоколам) с точностью до сотен микросекунд. Задача, получившая эталонное время вызывает следующую функцию и передаёт ей структуру с временем:
CODE
void RTC_TimeSync(vTime DateTime)
{
uint32_t TimeReg, DateReg;
uint32_t SSR_old, SSR_new;

// Преобразование времени в BCD
TimeReg = ((DateTime.Sec % 10) & 0x0F);
TimeReg |= (((DateTime.Sec / 10) & 0x07) << 4);
TimeReg |= (((DateTime.Min % 10) & 0x0F) << 8);
TimeReg |= (((DateTime.Min / 10) & 0x07) << 12);
TimeReg |= (((DateTime.Hour % 10) & 0x0F) << 16);
TimeReg |= (((DateTime.Hour / 10) & 0x03) << 20);
// Преобразование даты в BCD
DateReg = ((DateTime.Day % 10) & 0x0F);
DateReg |= (((DateTime.Day / 10) & 0x03) << 4);
DateReg |= (((DateTime.Month % 10) & 0x0F) << 8);
DateReg |= (((DateTime.Month / 10) & 0x01) << 12);
DateReg |= (((DateTime.Year % 10) & 0x0F) << 16);
DateReg |= (((DateTime.Year / 10) & 0x0F) << 20);

// Пишем ключи для доступа к регистрам RTC
RTC->WPR = RTC_KEY1;
RTC->WPR = RTC_KEY2;

if (!(RTC->ISR & RTC_ISR_INITF)) // RTC не в режиме инициализации?
{
RTC->ISR = (uint32_t)RTC_INIT_MASK; // Переходим в режим инициализации RTC
while (!(RTC->ISR & RTC_ISR_INITF)); // Ждём установки бита INIT в RTC->ISR
}

RTC->TR = TimeReg; // Пишем время в RTC
RTC->DR = DateReg; // Пишем дату в RTC

RTC->ISR &= ~RTC_ISR_INIT; // Выходим из режима инициализации RTC
RTC->WPR = 0xFF; // Включаем защиту регистров RTC


// Пишем ключи для доступа к регистрам RTC
RTC->WPR = RTC_KEY1;
RTC->WPR = RTC_KEY2;

SSR_old = RTC->SSR; // Текущее значение синхронного счётчика
SSR_new = RTC_PREDIV_S - ((DateTime.t100mks * 16384) / 10000); // Желаемое значение синхронного счётчика

while (RTC->ISR & RTC_ISR_SHPF);

if (SSR_new >= SSR_old) // К счётчику нужно прибавить (откат времени назад)
RTC->SHIFTR = SSR_new - SSR_old;
else // От счётчика нужно отнять (приращение времени)
RTC->SHIFTR = ((16383 - SSR_old) + SSR_new) | RTC_SHIFTR_ADD1S;

RTC->WPR = 0xFF;
}

RTC_PREDIV_S = 0x3FFF
RTC_PREDIV_A = 0x01

Дата и время (до секунд) синхронизируется нормально, а вот коррекция доли секунд не отрабатывает. Вообще. Т.е. как будто я пишу только дату и время до секунд.
Если заменить RTC простым счётом по таймеру, то синхронизация проходит верно и часы идут синхронно с удалёнными часами (т.е. пересчёт между форматами времени сделан верно).

Сообщение отредактировал IgorKossak - Nov 26 2012, 07:20
Причина редактирования: [codebox] для длинного кода!!!


--------------------
Руслан
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 03:24
Рейтинг@Mail.ru


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