Перейти к содержанию

    

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
... например, относительно 00:00:00 01.01.2000.

Тогда уж лучше с начала века (и тысячелетия), а именно 00:00:00 01.01.2001, к тому же - понедельник.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно узнать про точность часов и кто как калибрует.

 

У меня на платке Discovery, с родным кварцем 6pf, часы без калибровки безбожно врали, на несколько минут в день. В своем проекте я решил попробовать кварц 12.5pf(кварц обычный DT-26, 32768, 12.5pf, другой информации нет. ) и конденсаторы 12pf, знаю что так делать плохо, но ведь работает. Часы стали отставать примерно на 40 сек в сутки, т.е. частота как бы 32752Гц, думаю поменять делитель и не париться, мне достаточно погрешности в несолько минут в год.

Изменено пользователем batson

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Тогда уж лучше с начала века (и тысячелетия), а именно 00:00:00 01.01.2001, к тому же - понедельник.

А правильнее, шеф, - с 01-01-1970 00:00:00, т.к. С-шная библиотека с ее функциями даты и времени из этого исходит.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подниму тему по часам STM32 (или не совсем по часам?).

 

В общем такое дело. Микроконтроллер STM32F407. Подключаю батарейку CR2032 к VBAT.

Потребление от батарейки 0. Включаю устройство от штатного питания и выключаю.

Потребление от батарейки становится 3 мА, а на шине штатного питания остается

и держится небольшое напряжение примерно на уровне 0.6 вольт.

Батарейка, разумеется, садится через 3 суток, как и положено (220 мА/ч).

Выхода из такого состояния два: или отключить и подключить опять батарейку,

или закоротить и отпустить шину штатного питания (те самые 0.6 вольта).

Наличие или отсутствие программы в МК (можно его полностью стереть) не влияет.

В чем может быть дело? Надо менять МК?

Или что-то надо настроить в регистрах как можно быстрее при запуске прошивки?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

STM32F051, сегодня увидел, как на отладочной платке дискавери с внешней 2032, после отключения питания от отладчика (шнур USB от ноута)остался светится светодиод "PWR". После снятия и установки перемычки JP2 (в цепи питания основного процессора)

все угомонилось. Пару раз удалось повторить эффект. Почему батарейка запитывает шину? Все шины питания в одной куче и вроде с этим не должно быть проблем?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Подниму тему по часам STM32 (или не совсем по часам?).

 

Потребление от батарейки 0. Включаю устройство от штатного питания и выключаю.

Потребление от батарейки становится 3 мА, а на шине штатного питания остается

и держится небольшое напряжение примерно на уровне 0.6 вольт.

 

Ну незнаю, делал все, как по даташиту, при выключении питания - 2мкА, так что все в пределах нормы...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пример работы с таймером. может пригодится кому-то.

 

/*------------------------------------------------------------------------------
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
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Подниму тему по часам STM32 (или не совсем по часам?).

 

В общем такое дело. Микроконтроллер STM32F407. Подключаю батарейку CR2032 к VBAT.

Потребление от батарейки 0. Включаю устройство от штатного питания и выключаю.

Потребление от батарейки становится 3 мА, а на шине штатного питания остается

и держится небольшое напряжение примерно на уровне 0.6 вольт.

Батарейка, разумеется, садится через 3 суток, как и положено (220 мА/ч).

Выхода из такого состояния два: или отключить и подключить опять батарейку,

или закоротить и отпустить шину штатного питания (те самые 0.6 вольта).

Наличие или отсутствие программы в МК (можно его полностью стереть) не влияет.

В чем может быть дело? Надо менять МК?

Или что-то надо настроить в регистрах как можно быстрее при запуске прошивки?

 

Столкнулся с такой же проблемой на STM32F051. Началось с того что хотел откалибровать внутренние часы и вывел на PC13 частоту чтобы измерить период. Оставил на пару дней чтобы определить на сколько уйдут часы и батарейка оказалась разряжена. В ходе разбирательства выяснилось что в режиме вывода частоты этот вывод push-pull, а не open drain. И при выключенном питании контроллера все так же пытается выдать единичку и тянет ток из батарейки. Как только отключил выдачу частоты, стразу стало все нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация