2012-12-22 08:11 AM
I meet troubles with RTC on STM32F103RBT6. And it seems RTC in STM32 is very big problem. Many people have problem with RTC.STM32 has many restrictions for LSE crystal.
Noname crystal from China which works fine with LPC and AVR doesn't work stable with STM. I know about AN28 My board works fine some weeks with RTC, but now RTC doesn't start. I test with 3 different noname crystals, without capacitor and with capacitors from 5pF to 22pF. Also try to solder 5 MOhm resistor. Nothing. Doesn't work. After thatI tried to implement switching RTC signal source to HSE/ But also doesn't work. RTC doesn't counts. It looks as HSE/128 is not connected as clock signal source. But on KEIL debugger I see clock signal source is HSE/ From LSI RTC works fine. Code is below. You can see two lines (one of them is not active):RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128); // doesn't work
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // it works
No other difference only signal source. Maybe I forgot something??? Why doesn't work from HSE/128?
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* LSI clock stabilization time */
//for(i=0;i<5000;i++) { ; }
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) {
/* Backup data register value is not correct or not yet programmed (when
the first time the program is executed) */
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* Enable LSE */
RCC_LSEConfig(RCC_LSE_ON);
// enable LSI
RCC_LSICmd(ENABLE);
/* Wait till LSE is ready */
os_dly_wait(10*SEC);
// while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
// {
//
// }
if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
// LSE is not ready
// select HSE/128 as RTC clock source
#warning dont' forget
//RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
//RTC_SetPrescaler((HSE_VALUE/128)-1);
RTC_SetPrescaler(62499);
printf(''RTC clock source is HSE/128\r\n'');
}
else
{
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (768 KHz)/(32767+1) */
printf(''RTC clock source is LSE\r\n'');
}
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set initial value */
RTC_SetCounter( (uint32_t)((11*60+55)*60) ); // here: 1st January 2000 11:55:00
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
/* Lock access to BKP Domain */
PWR_BackupAccessCmd(DISABLE);
} else {
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
}
2012-12-22 11:25 AM
The LSE isn't a problem, you just have to follow some basis design instructions that specify what you're supposed to be doing. It's like complaining your car engine is making some awful knocking sounds when you put in some off-brand gasoline/petrol with the wrong octane value.
Are you sure your HSE is enabled and clocking? Suggest also you use an ''if (1)'' to force the LSE/128 code path, and select the LSE-Div_128. As I recall the LSI speed in the F103 runs at about 40 KHz, and needs enabling if you're using that.2012-12-25 02:02 AM
I guess HSE works. Because I see in keil debugger clock source and that HSE is ready.
And on my board already work USB and UARTs on 57600. I guess USB will not work with HSI 8MHz, because HSI is not so precious.I don't want to use LSI because frequency of LSI can be 30...60 kHz. And I told that RTC works with LSI,But RTC doesn't work with HSE/128. I need stable frequency from HSE.I can't see advantages of LSI using.2012-12-25 04:43 AM
My board works fine some weeks with RTC, but now RTC doesn't start.
Does it mean LSE is permanently damaged, what load capacitors have you used when it worked?I'm interested not to burn my devices.2012-12-25 10:25 AM
I used 5,1pF when in works.
It's easy to check generation by oscilloscope. On my board amplitude rise time was about 3 seconds. And it's easy to check in softwareif(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
// LSE is not ready
2012-12-25 11:33 AM
I see, thanks.
I wonder if it could be started ''by hand'', with some pulse generated on gpio pin.2012-12-26 09:20 PM
I also saw same idea on other forum.
But nobody tried it.Let me know your results.2012-12-27 02:11 AM
I may work or not. The problem is that the crystal can only take energy at frequencies very close to resonance, not easy to charge it.
2015-02-13 01:34 PM
Hi,
I had the same problem, resolved by adding : /* Reset the backup domain, clear RTC */ RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE); before the clock select. So my code is :void
init_RTC_Calendar(
void
)
{
RTC_InitTypeDef RTC_InitStructure;
//NVIC_InitTypeDef NVIC_InitStructure;
//EXTI_InitTypeDef EXTI_InitStructure;
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessCmd(ENABLE);
/* Reset the backup domain, clear RTC */
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
/* Check the HSE oscillator is ON */
while
(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)
{}
/* Select the RTC Clock Source */
//RCC_RTCCLKConfig(RCC_BDCR_RTCSEL_LSI);
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div32);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Configure the RTC data register and RTC prescaler */
RTC_InitStructure.RTC_AsynchPrediv = 125-1;
//99;
RTC_InitStructure.RTC_SynchPrediv = 2000-1;
//399;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
return
;
}