реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Часы на STM32, Проблема с часами на STM32/
ЛеонидК
сообщение Nov 20 2010, 09:58
Сообщение #1


Участник
*

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



Нужно добавить часы в проект на STM32.
Использую библиотеки ST и пример RTCCalendar.
При инициализации на RTC_WaitForLastTask() программа виснет.
В пошаговом режиме чаще проходит.
Может кто подскажет в чем может быть проблема.
Go to the top of the page
 
+Quote Post
shreck
сообщение Nov 20 2010, 10:47
Сообщение #2


Местный
***

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



Делал часы реального времени на основе примеров от ST. Все четко работает. Так что код в студию.
Go to the top of the page
 
+Quote Post
ЛеонидК
сообщение Nov 20 2010, 11:03
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 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]
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 20 2010, 17:21
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 351
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А кварц часовой имеется?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ЛеонидК
сообщение Nov 20 2010, 17:31
Сообщение #5


Участник
*

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



И питание тоже включал.
Правда конденсаторы 9,1 пФ.
Go to the top of the page
 
+Quote Post
Danis
сообщение Nov 20 2010, 18:05
Сообщение #6


Twilight Zone
***

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



Проверьте часовой кварц. Резонит?


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
ЛеонидК
сообщение Nov 20 2010, 18:20
Сообщение #7


Участник
*

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



Да
Go to the top of the page
 
+Quote Post
Danis
сообщение Nov 20 2010, 19:14
Сообщение #8


Twilight Zone
***

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



Цитата(ЛеонидК @ Nov 20 2010, 21:20) *
Да



Тогда может Вам стоит проверить конкретно биты в регистрах, почему не устанавливаються флаги?


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
zksystem
сообщение Nov 21 2010, 08:29
Сообщение #9


embedder
***

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



Цитата(ЛеонидК @ Nov 20 2010, 12:58) *
Использую библиотеки ST и пример RTCCalendar.
При инициализации на RTC_WaitForLastTask() программа виснет.
В пошаговом режиме чаще проходит.
Может кто подскажет в чем может быть проблема.


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


--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
Go to the top of the page
 
+Quote Post
shreck
сообщение Nov 22 2010, 03:10
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 317
Регистрация: 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
Go to the top of the page
 
+Quote Post
ЛеонидК
сообщение Nov 22 2010, 15:16
Сообщение #11


Участник
*

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



Так то оно так, только RTC_WaitForLastTask() не проходит.
И прерываний у меня нет. Я хочу смотреть часы, когда хочу, а не во время измерения.
Go to the top of the page
 
+Quote Post
ЛеонидК
сообщение Nov 22 2010, 18:32
Сообщение #12


Участник
*

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



Вопрос снимается.
Удалил лишнее RTC_WaitForLastTask().
Правда четкого понимания нет.
Go to the top of the page
 
+Quote Post
BlackHead
сообщение Oct 13 2011, 13:52
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 8-09-08
Пользователь №: 40 058



Вероятно, произошло вот что:

Привожу выдержку из мануала RM0008 стр 464:

To enable access to the Backup registers and the RTC, proceed as follows:
● enable the power and backup interface clocks by setting the PWREN and BKPEN bits
in the RCC_APB1ENR register
● set the DBP bit the Power Control Register (PWR_CR) to enable access to the Backup
registers and RTC.

Похоже, второй пункт у Вас не выполнен!
Go to the top of the page
 
+Quote Post
rexton
сообщение Feb 15 2012, 17:49
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 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;

}


Что может быть?
Go to the top of the page
 
+Quote Post
rexton
сообщение Feb 16 2012, 13:15
Сообщение #15


Участник
*

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



Пришлось поменять микроконтроллер и все заработало....
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th February 2018 - 03:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.11635 секунд с 7
ELECTRONIX ©2004-2016