|
Часы на STM32, Проблема с часами на STM32/ |
|
|
|
Nov 20 2010, 09:58
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 27-01-09
Пользователь №: 44 027

|
Нужно добавить часы в проект на STM32. Использую библиотеки ST и пример RTCCalendar. При инициализации на RTC_WaitForLastTask() программа виснет. В пошаговом режиме чаще проходит. Может кто подскажет в чем может быть проблема.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 23)
|
Nov 20 2010, 11:03
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 27-01-09
Пользователь №: 44 027

|
CODE void RTC_Config(void) { u16 WaitForOscSource; if (BKP_ReadBackupRegister(BKP_DR1) != CONF_DONE) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); PWR_BackupAccessCmd(ENABLE); BKP_DeInit(); RCC_LSEConfig(RCC_LSE_ON); while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {} RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); RTC_WaitForLastTask(); RTC_SetPrescaler(32767); RTC_WaitForLastTask(); DateVar.Month = DEFAULT_MOUNT; DateVar.Day = DEFAULT_DAY; DateVar.Year = DEFAULT_YEAR; TimeVar.Sec = DEFAULT_SEC; TimeVar.Min = DEFAULT_MIN; TimeVar.Hour = DEFAULT_HOUR; SummerTimeCorrect =OCTOBER_FLAG_SET; BKP_WriteBackupRegister(BKP_DR1,CONF_DONE); RTC_DataWrite(); } else { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); RTC_WaitForSynchro(); RTC_WaitForLastTask(); } }
Сообщение отредактировал IgorKossak - Oct 13 2011, 14:12
Причина редактирования: [codebox]
|
|
|
|
|
Nov 20 2010, 17:31
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 27-01-09
Пользователь №: 44 027

|
И питание тоже включал. Правда конденсаторы 9,1 пФ.
|
|
|
|
|
Nov 20 2010, 18:20
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 27-01-09
Пользователь №: 44 027

|
Да
|
|
|
|
|
Nov 20 2010, 19:14
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(ЛеонидК @ Nov 20 2010, 21:20)  Да Тогда может Вам стоит проверить конкретно биты в регистрах, почему не устанавливаються флаги?
--------------------
Magic Friend
|
|
|
|
|
Nov 21 2010, 08:29
|

embedder
  
Группа: Свой
Сообщений: 264
Регистрация: 11-05-05
Из: Казань
Пользователь №: 4 911

|
Цитата(ЛеонидК @ Nov 20 2010, 12:58)  Использую библиотеки ST и пример RTCCalendar. При инициализации на RTC_WaitForLastTask() программа виснет. В пошаговом режиме чаще проходит. Может кто подскажет в чем может быть проблема. Генератор часов раскачивается полминуты в моем случае, потом, после первой инициализации все нормально, пока батарейку не выдернешь. Советую посмотреть, правильные ли нагрузочные емкости к Вашему кварцу?
--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
|
|
|
|
|
Nov 22 2010, 03:10
|

Местный
  
Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328

|
Цитата(ЛеонидК @ Nov 20 2010, 18:03)  void RTC_Config(void) {...} Что-то здесь не так с последовательностью инициализации (хотя вдумчиво не смотрел). Посмотрите как у меня сделано. CODE //****************************************************************************** // RTC_DRV_CPP // DESCRIPTION: // Драйвер аппаратного RTC. // При совпадении текущего времени с заданными временами, // вызывается пользовательский обработчик (из прерывания). // //******************************************************************************
#include "rtc_drv.h" #include "platform_config.h" #include "stm32f10x.h" #include "helper.h"
//------------------------------------------------------------------------------ // T Y P E S and D E F I N I T I O N S //------------------------------------------------------------------------------
namespace { const Time zero_time = {0,0,0}; const uint32_t sec_per_day = 0x00015180; // = 24*60*60 enum {nch = 2}; // Кол-во каналов для сравнения. const uint16_t key = 0xA5A5; } // ns
//------------------------------------------------------------------------------ // G L O B A L V A R I A B L E S //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ // L O C A L S //------------------------------------------------------------------------------ namespace { // Prototypes. void enable_bkp(); bool rtc_config(); void set_time(const Time& tm); uint32_t time2int(Time tm); Time int2time(uint32_t u);
// Variables. rtc_drv::Cmp_callback callback; uint32_t cmp_time[nch]; } // ns
//============================================================================== // I M P L E M E N T A T I O N //==============================================================================
namespace rtc_drv { //------------------------------------------------------------------------------ // Инициализация и запуск "железа". // Возврат 0 - ошибок нет; 1 - кварц не запустился; 2 - восстановление по // умолчанию (следствие разряда батареи). uint8_t init() { uint8_t res = 0; NVIC_InitTypeDef NVIC_InitStructure; // Enable the RTC Interrupt. NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = RTC_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = RTC_SUBPRIORITY; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
enable_bkp(); // Наличие правильной настройки определяется по ключевому значению в // регистре в BKP domain. if (key != BKP_ReadBackupRegister(BKP_DR1)) { // Backup data register value is not correct or not yet programmed (when // the first time the program is executed). if (!rtc_config()) { return 1; } set_time(zero_time); BKP_WriteBackupRegister(BKP_DR1, key); res = 2; } else { // Без основного питания может пройти не один день. Счетчик необходимо // привести в надлежащее состояние. // Wait for RTC registers synchronization. RTC_WaitForSynchro(); uint32_t ticks = RTC_GetCounter(); ticks = ticks % sec_per_day; set_time(int2time(ticks)); } // Enable the RTC Second interrupt. RTC_WaitForSynchro(); RTC_ITConfig(RTC_IT_SEC, ENABLE); RTC_WaitForLastTask(); // RTC clock output. // Disable the Tamper Pin. // To output RTCCLK/64 on Tamper pin, // the tamper functionality must be disabled. BKP_TamperPinCmd(DISABLE); // Enable RTC Clock Output on Tamper Pin. BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock); return res; }
//------------------------------------------------------------------------------ // Возврат текущего времени. Time time() { return int2time(RTC_GetCounter()); }
//------------------------------------------------------------------------------ // Установка текущего времени. void time(const Time& tm) { set_time( tm ); }
//------------------------------------------------------------------------------ // Устанавливает значение делителя для получения секундного интервала. void set_divider(uint32_t div) { if (div) { // Wait until last write operation on RTC registers has finished. RTC_WaitForLastTask(); // Enable the RTC Second interrupt. // Set RTC prescaler: set RTC period to 1sec. RTC_SetPrescaler(div-1); // RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(div+1) // Wait until last write operation on RTC registers has finished. RTC_WaitForLastTask(); } }
//------------------------------------------------------------------------------ // Устанавливает обработчик. // При вызове обработчика, ему передается номер канала, в котором было совпадение. void set_callback(Cmp_callback cb) { callback = cb; }
//------------------------------------------------------------------------------ // Устанавливает время для сравнения. // ch =[0,1] - канал совпадения. void set_cmp_time(uint8_t ch, const Time& tm) { if (ch < nch) cmp_time[ch] = time2int( tm ); }
} // namespace rtc_drv
//------------------------------------------------------------------------------ // Обработчик секундного прерывания. extern "C" void RTC_IRQHandler() { if (RESET != RTC_GetITStatus(RTC_IT_SEC)) { RTC_ClearITPendingBit(RTC_IT_SEC); RTC_WaitForLastTask(); // Reset RTC Counter when Time is 23:59:59. uint32_t curr = RTC_GetCounter(); if (sec_per_day == curr) { curr = 0; RTC_SetCounter(0); RTC_WaitForLastTask(); } // Проверка на совпадение. for (uint_fast8_t i=0; i<nch; ++i) { if (curr == cmp_time[i] && callback) callback(i); } } }
//============================================================================== // Local functions.
namespace { //------------------------------------------------------------------------------ // Открывает доступ к регистрам из bkp domain. void enable_bkp() { // Enable PWR and BKP clocks. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Allow access to BKP Domain. PWR_BackupAccessCmd(ENABLE); }
//------------------------------------------------------------------------------ // Настраивает и запускает аппаратный rtc. // Возврат true, если ошибок нет. bool rtc_config() { BKP_DeInit(); // Enable LSE. RCC_LSEConfig(RCC_LSE_ON); // Wait till LSE is ready (но не более 3 секунд). uint32_t i=0; while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && i<3000) { delay_us(1000); ++i; } if (i >= 3000) return false; // Select LSE as RTC Clock Source. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Enable RTC Clock. RCC_RTCCLKCmd(ENABLE); // Wait for RTC registers synchronization. RTC_WaitForSynchro(); rtc_drv::set_divider(rtc_drv::divider_def); return true; }
//------------------------------------------------------------------------------ // Устанавливает новое значение времени. void set_time(const Time& tm) { // Wait until last write operation on RTC registers has finished. RTC_WaitForLastTask(); // Change the current time. RTC_SetCounter(time2int); // Wait until last write operation on RTC registers has finished. RTC_WaitForLastTask(); }
//------------------------------------------------------------------------------ // Преобразование времени в число и обратно. uint32_t time2int(Time tm) { return (tm.hour*3600 + tm.min*60 + tm.sec); }
Time int2time(uint32_t u) { Time tm = {u/3600, (u%3600)/60, (u%3600)%60}; return tm; }
} // ns
|
|
|
|
|
Nov 22 2010, 15:16
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 27-01-09
Пользователь №: 44 027

|
Так то оно так, только RTC_WaitForLastTask() не проходит. И прерываний у меня нет. Я хочу смотреть часы, когда хочу, а не во время измерения.
|
|
|
|
|
Nov 22 2010, 18:32
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 27-01-09
Пользователь №: 44 027

|
Вопрос снимается. Удалил лишнее RTC_WaitForLastTask(). Правда четкого понимания нет.
|
|
|
|
|
Feb 15 2012, 17:49
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-11-11
Пользователь №: 68 153

|
Еще вопрос по часам. Плата stm32discovery не могу запустить часы от внешнего кварца. Смотрел осцилом - нет генерации на кварце. На OSC32_OUT просто 3 вольта. На OSC32_IN что то около нуля. Самое странное на плате не было резистора R15 который как раз идет с OSC32_OUT на кварц. Впаял перемычку вместо него, ничего не изменилось. Вот код инициализации часов: CODE unsigned char RtcInit (void) { //разрешить тактирование модулей управления питанием и управлением резервной областью RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN; //разрешить доступ к области резервных данных PWR->CR |= PWR_CR_DBP;
//если часы выключены - инициализировать их if ((RCC->BDCR & RCC_BDCR_RTCEN) != RCC_BDCR_RTCEN) { //выполнить сброс области резервных данных RCC->BDCR |= RCC_BDCR_BDRST; RCC->BDCR &= ~RCC_BDCR_BDRST;
//выбрать источником тактовых импульсов внешний кварц 32768 и подать тактирование RCC->BDCR |= RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_LSE;
RTC->CRL |= RTC_CRL_CNF; RTC->PRLL = 0x7FFF; //регистр деления на 32768 RTC->CRL &= ~RTC_CRL_CNF;
//установить бит разрешения работы и дождаться установки бита готовности RCC->BDCR |= RCC_BDCR_LSEON; while ((RCC->BDCR & RCC_BDCR_LSERDY) != RCC_BDCR_LSERDY);
RTC->CRL &= (uint16_t)~RTC_CRL_RSF; while((RTC->CRL & RTC_CRL_RSF) != RTC_CRL_RSF){}
return 1; } return 0;
} Что может быть?
|
|
|
|
|
Feb 16 2012, 13:15
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-11-11
Пользователь №: 68 153

|
Пришлось поменять микроконтроллер и все заработало....
|
|
|
|
|
Feb 20 2012, 19:12
|

Местный
  
Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631

|
Может не в тему, но я не могу понять, зачем использовать такие вещи, как пример RTCCalendar. Зачем сохранять в бэйкап регистры {сек,мин,час, день, мес, год}. А если устройсво долго было выключено, то в примере в цикле начинается посуточный пересчет даты (!). Я понимаю, что в ините может быть что угодно, но это уже перебор. Ведь единственным базисом времени в реальной жизни является относительное время в секундах, например, относительно 00:00:00 01.01.2000. И 32 битного счетчика вам хватит до ~2120 года (батарейки хватит  ? ). Т.е. кроме самого счетчика RTC вам ничего не нужно. И арифметика пересчета "секунды века" в человеческие "часы минуты дни месяцы годы" получается проще, чем в примере.
|
|
|
|
|
Nov 10 2012, 10:02
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 26-02-11
Пользователь №: 63 256

|
Интересно узнать про точность часов и кто как калибрует.
У меня на платке Discovery, с родным кварцем 6pf, часы без калибровки безбожно врали, на несколько минут в день. В своем проекте я решил попробовать кварц 12.5pf(кварц обычный DT-26, 32768, 12.5pf, другой информации нет. ) и конденсаторы 12pf, знаю что так делать плохо, но ведь работает. Часы стали отставать примерно на 40 сек в сутки, т.е. частота как бы 32752Гц, думаю поменять делитель и не париться, мне достаточно погрешности в несолько минут в год.
Сообщение отредактировал batson - Nov 10 2012, 10:03
|
|
|
|
|
Nov 10 2012, 12:19
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(IgorKossak @ Feb 20 2012, 22:06)  Тогда уж лучше с начала века (и тысячелетия), а именно 00:00:00 01.01.2001, к тому же - понедельник. А правильнее, шеф, - с 01-01-1970 00:00:00, т.к. С-шная библиотека с ее функциями даты и времени из этого исходит.
|
|
|
|
|
Dec 23 2013, 07:28
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 3-07-06
Пользователь №: 18 536

|
Подниму тему по часам STM32 (или не совсем по часам?).
В общем такое дело. Микроконтроллер STM32F407. Подключаю батарейку CR2032 к VBAT. Потребление от батарейки 0. Включаю устройство от штатного питания и выключаю. Потребление от батарейки становится 3 мА, а на шине штатного питания остается и держится небольшое напряжение примерно на уровне 0.6 вольт. Батарейка, разумеется, садится через 3 суток, как и положено (220 мА/ч). Выхода из такого состояния два: или отключить и подключить опять батарейку, или закоротить и отпустить шину штатного питания (те самые 0.6 вольта). Наличие или отсутствие программы в МК (можно его полностью стереть) не влияет. В чем может быть дело? Надо менять МК? Или что-то надо настроить в регистрах как можно быстрее при запуске прошивки?
|
|
|
|
|
Apr 22 2014, 04:14
|
Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 25-10-09
Из: Екатеринбург
Пользователь №: 53 194

|
Пример работы с таймером. может пригодится кому-то. CODE /*------------------------------------------------------------------------------ File Name : rtc.h Author : Version : 1.1 Date : 17/12/2013 Description : contens functions for work rtc timer stm32f103xx --------------------------------------------------------------------------------*/ #include "stm32F10x.h" #include "stm32f10x_rtc.h" #include "misc.h" #include "string.h" #include "stdlib.h" #include "stdio.h" #include "time.h"
#include "glb_def.h" #include "ublox530m_gps.h"
#include "rtc.h" /*------------------------------------------------------------------------------ | RTC | ------------------------------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/ extern FlagEvent_t flag_event;
/* Private variables ---------------------------------------------------------*/ static uint32_t cnt_wait; static struct tm caltime; /* from time.h*/ __IO static time_t counter; /* Private function declaration ----------------------------------------------*/ static void Rtc_counter_to_struct(struct tm *caltime); static time_t Rtc_struct_to_counter(struct tm *caltime); /**--------------------------------------------------------------------------- * @brief RTC_IRQHandler * @param none * @retval none *--------------------------------------------------------------------------- */ void RTC_IRQHandler (void) { uint32_t current_cnt;
if (RTC_GetITStatus(RTC_IT_SEC) == SET) { RTC_ClearITPendingBit(RTC_IT_SEC); /*Waits until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); current_cnt = RTC_GetCounter(); if (current_cnt > cnt_wait) { /*Waits until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* disable interrupt*/ RTC_ITConfig(RTC_IT_SEC, DISABLE); /* wait elapsed */ flag_event.WaitElapsed = 1; } } } /**--------------------------------------------------------------------------- * @brief Init rtc timer stm32f103xx for work * @param none * @retval none *--------------------------------------------------------------------------- */ void Rtc_Init (void) { NVIC_InitTypeDef NVIC_InitStruct; //enable clock power supply module and buckup domain RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN; //enable common access PWR->CR |= PWR_CR_DBP;
RCC->BDCR |= RCC_BDCR_BDRST; RCC->BDCR &= ~RCC_BDCR_BDRST; RCC->BDCR |= RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_LSE; //Enters the RTC configuration mode RTC->CRL |= RTC_CRL_CNF; //clock from external quartz RTC->PRLL = 0x7FFF; //Exits from the RTC configuration mode RTC->CRL &= ~RTC_CRL_CNF; //setup bit enable work LSE and wait ready LSE RCC->BDCR |= RCC_BDCR_LSEON; while ((RCC->BDCR & RCC_BDCR_LSEON) != RCC_BDCR_LSEON){} RTC_WaitForSynchro(); //Setup NVIC for RTC NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); }
/**--------------------------------------------------------------------------- * @brief Start wait mode * @param * @output * @retval none *--------------------------------------------------------------------------- */ void Rtc_StartWait (DataTimeCmd_t *SETime) { struct tm t1, t2; uint32_t dt; t1.tm_hour = SETime->StartWaitTime.hour; t1.tm_isdst = 0; t1.tm_mday = SETime->StartWaitTime.mday; t1.tm_min = SETime->StartWaitTime.min; t1.tm_mon = SETime->StartWaitTime.month-1; t1.tm_sec = SETime->StartWaitTime.sec; t1.tm_year = SETime->StartWaitTime.year - 1900; counter = Rtc_struct_to_counter(&t1);
/*Waits until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); Rtc_SetCounter(counter); /**/ t2.tm_hour = SETime->EndWaitTime.hour; t2.tm_isdst = 0; t2.tm_mday = SETime->EndWaitTime.mday; t2.tm_min = SETime->EndWaitTime.min; t2.tm_mon = SETime->EndWaitTime.month-1; t2.tm_sec = SETime->EndWaitTime.sec; t2.tm_year = SETime->EndWaitTime.year - 1900; /**/ dt = mktime(&t2) - mktime(&t1); /*Waits until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); cnt_wait = RTC_GetCounter() + dt;//wmin*60; //Enable second interrupt RTC_ITConfig(RTC_IT_SEC, ENABLE); }
/**--------------------------------------------------------------------------- * @brief populates time-struct based on counter-value * @param caltime - pointer to time-struct tm (from time.h) * @output time-struct tm fills * @retval none *--------------------------------------------------------------------------- */ static void Rtc_counter_to_struct (struct tm *caltime) { struct tm *ct; counter = RTC_GetCounter(); ct = localtime((const time_t*)&counter); memcpy((void*)caltime, (void*)ct, sizeof(struct tm)); }
/**--------------------------------------------------------------------------- * @brief calculates second-counter from populated time-struct tm * @param caltime - pointer to time-struct tm (from time.h) * @output none * @retval counter-value (unit seconds) time_t type *--------------------------------------------------------------------------- */ static time_t Rtc_struct_to_counter (struct tm *caltime) { counter = mktime(caltime); return counter; }
/**--------------------------------------------------------------------------- * @brief populates time-struct RTC_t type from struct tm type * @param rtc - pointer to RTC_t struct * @output time-struct gets modified * @retval none *--------------------------------------------------------------------------- */ void Rtc_Gettime (DataTime_t *rtc) { Rtc_counter_to_struct(&caltime); rtc->hour = caltime.tm_hour; rtc->mday = caltime.tm_mday; rtc->min = caltime.tm_min; rtc->month = caltime.tm_mon+1; rtc->sec = caltime.tm_sec; rtc->wday = caltime.tm_wday; rtc->year = caltime.tm_year + 1900; }
/**--------------------------------------------------------------------------- * @brief sets the hardware-counter * @param new counter-value * @output none * @retval none *--------------------------------------------------------------------------- */ void Rtc_SetCounter (uint32_t cnt) { /* Change the current time */ RTC->CRL |= RTC_CRL_CNF; RTC->CNTH = cnt>>16; RTC->CNTL = cnt; RTC->CRL &= ~RTC_CRL_CNF; }
/**--------------------------------------------------------------------------- * @brief populates time-struct tm type from time-struct RTC_t type * @param none * @output caltime - global time-struct tm type * counter - global sec counter * sets the hardware-counter * @retval none *--------------------------------------------------------------------------- */ void Rtc_Settime (DataTime_t *rtc) { caltime.tm_hour = rtc->hour; caltime.tm_isdst = 0; caltime.tm_mday = rtc->mday; caltime.tm_min = rtc->min; caltime.tm_mon = rtc->month-1; caltime.tm_sec = rtc->sec; caltime.tm_year = rtc->year - 1900;
/*Waits until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); counter = Rtc_struct_to_counter(&caltime); Rtc_SetCounter(counter); }
/**--------------------------------------------------------------------------- * @brief Get UTC data and time * @param data - pointer on struct GPSDATA_t: 'dd,mm,yyyy' * time - pointer on struct GPSTIME_t: 'hhmmss.ddd' * @output populates time-struct GPSDATA_t and GPSTIME_t * @retval none *--------------------------------------------------------------------------- */ void Rtc_GetUtcDateTime (GPSDATA_t *data, GPSTIME_t *time) { DataTime_t rtc; Rtc_Gettime(&rtc); data->date_str[0] = rtc.mday/10 + 0x30; data->date_str[1] = rtc.mday%10 + 0x30; data->date_str[2] = ','; data->date_str[3] = rtc.month/10 + 0x30; data->date_str[4] = rtc.month%10 + 0x30; data->date_str[5] = ','; data->date_str[6] = rtc.year/1000 + 0x30; data->date_str[7] = (rtc.year%1000)/100 + 0x30; data->date_str[8] = (rtc.year%100)/10 + 0x30; data->date_str[9] = rtc.year%10 + 0x30; // time->time_str[0] = rtc.hour/10 + 0x30; time->time_str[1] = rtc.hour%10 + 0x30; time->time_str[2] = rtc.min/10 + 0x30; time->time_str[3] = rtc.min%10 + 0x30; time->time_str[4] = rtc.sec/10 + 0x30; time->time_str[5] = rtc.sec%10 + 0x30; time->time_str[6] = '.'; time->time_str[7] = '0'; time->time_str[8] = '0'; time->time_str[9] = '0'; }
/**--------------------------------------------------------------------------- * @brief Get UTC data and time * @param rtc - pointer on struct RTC_t * ttime_str - pointer on struct RtcDataTime_t: 'dd,mm,yyyyhhmmss.ddd' * @output populates time-struct RtcDataTime_t * @retval none *--------------------------------------------------------------------------- */ void Rtc_ConvertToStr(DataTime_t *rtc, StrDataTime_t *time_str) { time_str->Data.date_str[0] = rtc->mday/10 + 0x30; time_str->Data.date_str[1] = rtc->mday%10 + 0x30; time_str->Data.date_str[2] = ','; time_str->Data.date_str[3] = rtc->month/10 + 0x30; time_str->Data.date_str[4] = rtc->month%10 + 0x30; time_str->Data.date_str[5] = ','; time_str->Data.date_str[6] = rtc->year/1000 + 0x30; time_str->Data.date_str[7] = (rtc->year%1000)/100 + 0x30; time_str->Data.date_str[8] = (rtc->year%100)/10 + 0x30; time_str->Data.date_str[9] = rtc->year%10 + 0x30; // time_str->Time.time_str[0] = rtc->hour/10 + 0x30; time_str->Time.time_str[1] = rtc->hour%10 + 0x30; time_str->Time.time_str[2] = rtc->min/10 + 0x30; time_str->Time.time_str[3] = rtc->min%10 + 0x30; time_str->Time.time_str[4] = rtc->sec/10 + 0x30; time_str->Time.time_str[5] = rtc->sec%10 + 0x30; time_str->Time.time_str[6] = '.'; time_str->Time.time_str[7] = '0'; time_str->Time.time_str[8] = '0'; time_str->Time.time_str[9] = '0'; }
/*----------------------------END OF FILE-------------------------------------*/
Сообщение отредактировал IgorKossak - Apr 22 2014, 07:29
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Feb 9 2018, 20:53
|
Группа: Новичок
Сообщений: 1
Регистрация: 9-02-18
Пользователь №: 101 645

|
Цитата(Sidoroff @ Dec 23 2013, 10:28)  Подниму тему по часам STM32 (или не совсем по часам?).
В общем такое дело. Микроконтроллер STM32F407. Подключаю батарейку CR2032 к VBAT. Потребление от батарейки 0. Включаю устройство от штатного питания и выключаю. Потребление от батарейки становится 3 мА, а на шине штатного питания остается и держится небольшое напряжение примерно на уровне 0.6 вольт. Батарейка, разумеется, садится через 3 суток, как и положено (220 мА/ч). Выхода из такого состояния два: или отключить и подключить опять батарейку, или закоротить и отпустить шину штатного питания (те самые 0.6 вольта). Наличие или отсутствие программы в МК (можно его полностью стереть) не влияет. В чем может быть дело? Надо менять МК? Или что-то надо настроить в регистрах как можно быстрее при запуске прошивки? Столкнулся с такой же проблемой на STM32F051. Началось с того что хотел откалибровать внутренние часы и вывел на PC13 частоту чтобы измерить период. Оставил на пару дней чтобы определить на сколько уйдут часы и батарейка оказалась разряжена. В ходе разбирательства выяснилось что в режиме вывода частоты этот вывод push-pull, а не open drain. И при выключенном питании контроллера все так же пытается выдать единичку и тянет ток из батарейки. Как только отключил выдачу частоты, стразу стало все нормально.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|