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

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

|
Нужно добавить часы в проект на STM32. Использую библиотеки ST и пример RTCCalendar. При инициализации на RTC_WaitForLastTask() программа виснет. В пошаговом режиме чаще проходит. Может кто подскажет в чем может быть проблема.
|
|
|
|
|
 |
Ответов
|
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 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(). Правда четкого понимания нет.
|
|
|
|
Сообщений в этой теме
ЛеонидК Часы на STM32 Nov 20 2010, 09:58  AHTOXA А кварц часовой имеется? Nov 20 2010, 17:21   ЛеонидК И питание тоже включал.
Правда конденсаторы 9,1 пФ... Nov 20 2010, 17:31    Danis Проверьте часовой кварц. Резонит? Nov 20 2010, 18:05     ЛеонидК Да Nov 20 2010, 18:20      Danis Цитата(ЛеонидК @ Nov 20 2010, 21:20) Да
... Nov 20 2010, 19:14 zksystem Цитата(ЛеонидК @ Nov 20 2010, 12:58) Испо... Nov 21 2010, 08:29 BlackHead Вероятно, произошло вот что:
Привожу выдержку из ... Oct 13 2011, 13:52 rexton Еще вопрос по часам.
Плата stm32discovery не могу... Feb 15 2012, 17:49 rexton Пришлось поменять микроконтроллер и все заработало... Feb 16 2012, 13:15 ISK2010 Может не в тему, но я не могу понять, зачем исполь... Feb 20 2012, 19:12 IgorKossak Цитата(ISK2010 @ Feb 20 2012, 21:12) ... ... Feb 20 2012, 20:06  KnightIgor Цитата(IgorKossak @ Feb 20 2012, 22:06) Т... Nov 10 2012, 12:19 batson Интересно узнать про точность часов и кто как кали... Nov 10 2012, 10:02 Sidoroff Подниму тему по часам STM32 (или не совсем по часа... Dec 23 2013, 07:28 mantech Цитата(Sidoroff @ Dec 23 2013, 11:28) Под... Jan 22 2014, 04:53 Михась STM32F051, сегодня увидел, как на отладочной платк... Jan 22 2014, 03:59 VadimNic_nt Пример работы с таймером. может пригодится кому-то... Apr 22 2014, 04:14 Radjin Цитата(Sidoroff @ Dec 23 2013, 10:28) Под... Feb 9 2018, 20:53
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|