|
|
  |
STM32F107 и RTC. |
|
|
|
Jan 14 2016, 10:35
|

Частый гость
 
Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474

|
В STM32F1XX есть только регистр-счётчик (точнее, два 16-битных) - RTC_CNTH / RTC_CNTL. Вот в F3/F4 там регистры интереснее. То есть, у вас есть 32 бита (секунд, если делить тактовую RTC до секунд, либо более короткие промежутки времени), и значение секунд/минут/часов/даты нужно вычислять.
Рекомендую так же обратиться к самой первой странице данного документа, где определён список контроллеров, на которые он распространяется. Там отсутствуют кристаллы STM32F1. А так же сноска несколько выше Вашего рисунка, отсылающая к таблице 15, где указано наличие/отсутствие специфических для линейки параметров, как то функции/регистры RTC.
Для линейки STM32F1XX нужно реализовывать данный функционал программно.
Сообщение отредактировал AlanDrakes - Jan 14 2016, 10:53
|
|
|
|
|
Jan 14 2016, 10:54
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(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(); } }
Сообщение отредактировал IgorKossak - Jan 14 2016, 19:31
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Jan 14 2016, 11:24
|

Частый гость
 
Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474

|
Цитата(Jenya7 @ Jan 14 2016, 17:12)  в любом случае нам нужны готовые объекты – секунды, минуты, часы, дни и так далее, скажем для планировщика. рутина в прерывании быстро апдейтирует их и потом они готовы к работе и их можно вызвать из любого модуля. Тогда вам вообще не нужен этот таймер. Просто получаете начальное время и каждую секунду по событию часов добавляете секунду. Как раз, как в вашем коде. Кстати, у вас нет коррекции дат в високосный год.
|
|
|
|
|
Jan 14 2016, 11:38
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(AlanDrakes @ Jan 14 2016, 17:24)  Тогда вам вообще не нужен этот таймер. Просто получаете начальное время и каждую секунду по событию часов добавляете секунду. Как раз, как в вашем коде. Кстати, у вас нет коррекции дат в високосный год. ну таймер все равно нужен - чтоб максимально точно отсчитать секунду. таймер то клокируется от часового кристала. коррекцию високосного года я делаю при инициализации. Код if(IsLeapYear(2000 + rtc.rtcYear)) { numDaysInMonth[2] = 29; } else { numDaysInMonth[2] = 28; }
|
|
|
|
|
Jan 14 2016, 12:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882

|
Цитата(Jenya7 @ Jan 14 2016, 16:12)  в любом случае нам нужны готовые объекты – секунды, минуты, часы, дни и так далее, скажем для планировщика. рутина в прерывании быстро апдейтирует их и потом они готовы к работе и их можно вызвать из любого модуля. Смотрите... Но по мне так выгодней у планировщика время переводить и хранить в time_t. Сравнивать всяко быстрее будет. mktime и gmtime никто не отменял, а памяти у камня не так много отъест. А по поводу вызывать из любого модуля.... Придется делать операцию взятия времени атомарной. Ведь куча регистров, и все меняются..
|
|
|
|
|
Jan 14 2016, 15:21
|
Профессионал
    
Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882

|
Цитата(Jenya7 @ Jan 14 2016, 17:23)  ну не вызову атомарно - потеряю секунду - я могу жить с этим. :) не вызовешь атомарно - попадешь либо в будущее, либо в прошлое - смотря что первым копироваться будет, младшая часть времени, или старшая. Пример: 23:59:59 Копируем секунды /время увеличивается/ Копируем минуты Копируем часы Ура, мы опередили время на 59 секунд!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|