Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F107 и RTC.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Jenya7
Насколько я понимаю есть только таймер. Хардварных регистров для секунд, минут, часов нету.
Меня сбил с толку рисунок в мануале. это я так понимаю надо реализовывать самому?



AlanDrakes
В STM32F1XX есть только регистр-счётчик (точнее, два 16-битных) - RTC_CNTH / RTC_CNTL. Вот в F3/F4 там регистры интереснее.
То есть, у вас есть 32 бита (секунд, если делить тактовую RTC до секунд, либо более короткие промежутки времени), и значение секунд/минут/часов/даты нужно вычислять.

Рекомендую так же обратиться к самой первой странице данного документа, где определён список контроллеров, на которые он распространяется. Там отсутствуют кристаллы STM32F1. А так же сноска несколько выше Вашего рисунка, отсылающая к таблице 15, где указано наличие/отсутствие специфических для линейки параметров, как то функции/регистры RTC.

Для линейки STM32F1XX нужно реализовывать данный функционал программно.
Jenya7
Цитата(AlanDrakes @ Jan 14 2016, 16:35) *
В STM32F1XX есть только регистр-счётчик (точнее, два 16-битных) - RTC_CNTH / RTC_CNTL. Вот в F3/F4 там регистры интереснее.
То есть, у вас есть 32 бита (секунд, если делить тактовую RTC до секунд, либо более короткие промежутки времени), и значение секунд/минут/часов/даты нужно вычислять.

Рекомендую так же обратиться к самой первой странице данного документа, где определён список контроллеров, на которые он распространяется. Там отсутствуют кристаллы STM32F1. А так же сноска несколько выше Вашего рисунка, отсылающая к таблице 15, где указано наличие/отсутствие специфических для линейки параметров, как то функции/регистры RTC.

мда...посмотрел я на эти вычисления
Код
if (RTC_GetCounter() == 0x0001517F)
  {
     RTC_SetCounter(0x0);
     /* Wait until last write operation on RTC registers has finished */
     RTC_WaitForLastTask();
  }
  
  /* Compute  hours */
  THH = TimeVar / 3600;
  /* Compute minutes */
  TMM = (TimeVar % 3600) / 60;
  /* Compute seconds */
  TSS = (TimeVar % 3600) % 60;

гораздо проще и быстрее в интерапте обработать.
CODE
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
/* Clear the corresponding RTC pending bit */
RTC->CRL &= (uint16_t)~RTC_IT_SEC;

rtc_sec_int = 1;

rtc.rtcSec++; // increment seconds
if(rtc.rtcSec > 59) // check seconds overflow
{
rtc.rtcSec = 0;
rtc.rtcMin++; // increment minutes
if(rtc.rtcMin > 59) // check minutes overflow
{
rtc.rtcMin = 0;
rtc.rtcHour++; // increment hours
rtc_hour_int = 1;
if(rtc.rtcHour > 23) // check hours overflow
{
rtc.rtcHour = 0;
rtc.rtcDay++; // increment days
UpdateDayOfWeek();
//if(rtc.rtcDay > daysInMonthCalc[rtc.rtcMonth-1]) // check days overflow
if(rtc.rtcDay > numDaysInMonth[rtc.rtcMonth])
{
rtc.rtcDay = 1;
rtc.rtcMonth++; // increment months
if(rtc.rtcMonth > 12) // check months overflow
{
rtc.rtcMonth = 1;
rtc.rtcYear++; // increment years
}
}
}
}
}

/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
Alechek
Эт смотря для чего.
У меня в LPC наоборот, из полного времени RTC собираются секунды и получается time_t результат стандартной Си функции time(NULL).
Так как человеческий формат времени все равно нужен только человеку.
А если кому надо... экрану там, или протоколу какому-то - пущай сам разбирает.
Jenya7
Цитата(Alechek @ Jan 14 2016, 17:01) *
Эт смотря для чего.
У меня в LPC наоборот, из полного времени RTC собираются секунды и получается time_t результат стандартной Си функции time(NULL).
Так как человеческий формат времени все равно нужен только человеку.
А если кому надо... экрану там, или протоколу какому-то - пущай сам разбирает.

в любом случае нам нужны готовые объекты – секунды, минуты, часы, дни и так далее, скажем для планировщика. рутина в прерывании быстро апдейтирует их и потом они готовы к работе и их можно вызвать из любого модуля.
AlanDrakes
Цитата(Jenya7 @ Jan 14 2016, 17:12) *
в любом случае нам нужны готовые объекты – секунды, минуты, часы, дни и так далее, скажем для планировщика. рутина в прерывании быстро апдейтирует их и потом они готовы к работе и их можно вызвать из любого модуля.


Тогда вам вообще не нужен этот таймер.
Просто получаете начальное время и каждую секунду по событию часов добавляете секунду. Как раз, как в вашем коде.
Кстати, у вас нет коррекции дат в високосный год.
Jenya7
Цитата(AlanDrakes @ Jan 14 2016, 17:24) *
Тогда вам вообще не нужен этот таймер.
Просто получаете начальное время и каждую секунду по событию часов добавляете секунду. Как раз, как в вашем коде.
Кстати, у вас нет коррекции дат в високосный год.

ну таймер все равно нужен - чтоб максимально точно отсчитать секунду. таймер то клокируется от часового кристала.
коррекцию високосного года я делаю при инициализации.
Код
if(IsLeapYear(2000 + rtc.rtcYear))
{
    numDaysInMonth[2] = 29;
}
else
{
    numDaysInMonth[2] = 28;
}
Alechek
Цитата(Jenya7 @ Jan 14 2016, 16:12) *
в любом случае нам нужны готовые объекты – секунды, минуты, часы, дни и так далее, скажем для планировщика. рутина в прерывании быстро апдейтирует их и потом они готовы к работе и их можно вызвать из любого модуля.

Смотрите... Но по мне так выгодней у планировщика время переводить и хранить в time_t. Сравнивать всяко быстрее будет.
mktime и gmtime никто не отменял, а памяти у камня не так много отъест.

А по поводу вызывать из любого модуля.... Придется делать операцию взятия времени атомарной. Ведь куча регистров, и все меняются..
Jenya7
Цитата(Alechek @ Jan 14 2016, 18:05) *
Смотрите... Но по мне так выгодней у планировщика время переводить и хранить в time_t. Сравнивать всяко быстрее будет.
mktime и gmtime никто не отменял, а памяти у камня не так много отъест.

А по поводу вызывать из любого модуля.... Придется делать операцию взятия времени атомарной. Ведь куча регистров, и все меняются..

ну не вызову атомарно - потеряю секунду - я могу жить с этим. :)

посмотрел сейчас библиотеку timer.h. ну не знаю не знаю... как по мне, ничего она не добавляет. а функцию перевода времени в строку для вывода на терминал я напишу оптимальней.

Alechek
Цитата(Jenya7 @ Jan 14 2016, 17:23) *
ну не вызову атомарно - потеряю секунду - я могу жить с этим. :)

не вызовешь атомарно - попадешь либо в будущее, либо в прошлое - смотря что первым копироваться будет, младшая часть времени, или старшая.
Пример: 23:59:59

Копируем секунды
/время увеличивается/
Копируем минуты
Копируем часы

Ура, мы опередили время на 59 секунд!


Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.