Цитата(khach @ Nov 24 2012, 16:20)

Смотрите в сторону PTP. Для начала гляньте AN3411 IEEE 1588 precision time protocol demonstration for STM32F107 connectivity line microcontroller. Конечно для достижения точности в наносекунды понадобится отдельный аппаратный TimeServer.
С получением точного времени у меня проблем нет. Проблема в коррекции субсекундного счётчика RTC, который пытается изменить процедура, приведённая выше.
Судя по RTC->SSR, коррекция не проходит, не понятно почему.
Делаю в соответствии с документом AN3371: Using the hardware real-time clock (RTC) in STM32 F0, F2, F3, F4 and L1 series of MCUs.
Оказалось всё просто.
После установки времени и даты в регистрах DR и TR, субсекундный счётчик сбрасывается и остаётся только вычислить и установить его новое значение.
Рабочий вариант процедуры:
CODE
void RTC_TimeSync(vTime DateTime)
{
uint32_t TimeReg, DateReg;
// Преобразование времени в 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->SHIFTR = (RTC_PREDIV_S - ((t100mks * 16384) / 10000) + 1) | RTC_SHIFTR_ADD1S;
RTC->ISR &= ~RTC_ISR_INIT; // Выходим из режима инициализации RTC
RTC->WPR = 0xFF; // Включаем защиту регистров RTC
}
Всем спасибо
Сообщение отредактировал IgorKossak - Nov 26 2012, 07:20
Причина редактирования: [codebox] для длинного кода!!!