Page 1 of 1
Calibration of stm32f103 clock
Posted: Sun Oct 06, 2024 6:59 am
by k008
Tell me how to calibrate the clock in stm32f103.
Now I work like this:
Code: Select all
#include <STM32RTC.h>
STM32RTC& rtc = STM32RTC::getInstance();
setup() {
rtc.setClockSource(STM32RTC::LSE_CLOCK);
rtc.begin(); // initialize RTC 24H format
}
Calibration and initialization seem to be done like this:
Code: Select all
if ((RCC->BDCR & RCC_BDCR_RTCEN) != RCC_BDCR_RTCEN) //Check the clock, if not enabled, then initialize
{
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN; //Enable PWR and Backup clocking
PWR->CR |= PWR_CR_DBP; //Allow access to Backup area
RCC->BDCR |= RCC_BDCR_BDRST; //Reset Backup area
RCC->BDCR &= ~RCC_BDCR_BDRST;
RCC->BDCR |= RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_LSE; //Select LSE source (quartz 32768) and apply clocking
RCC->BDCR |= RCC_BDCR_LSEON; //Enable LSE
while ((RCC->BDCR & RCC_BDCR_LSEON) != RCC_BDCR_LSEON){} //Wait for power-on
BKP->RTCCR |= 3; //RCC calibration
while (!(RTC->CRL & RTC_CRL_RTOFF)); //check if RTC register changes are finished
RTC->CRL |= RTC_CRL_CNF; //Enable writing to RTC registers
RTC->PRLL = 0x7FFF; //Set the divider to 32768 (32767+1)
BKP->RTCCR |= BKP_RTCCR_CCO; //Enable the Temper pin
RTC->CRL &= ~RTC_CRL_CNF; //Disable writing to RTC registers
while (!(RTC->CRL & RTC_CRL_RTOFF)); //Wait for writing to finish
RTC->CRL &= (uint16_t)~RTC_CRL_RSF; //Synchronize RTC
while((RTC->CRL & RTC_CRL_RSF) != RTC_CRL_RSF){} //Wait for synchronization
PWR->CR &= ~PWR_CR_DBP; //prohibit access to Backup area
}
But what is the correct way to do calibration if you use STM32RTC.h?
Re: Calibration of stm32f103 clock
Posted: Sun Oct 06, 2024 10:08 am
by STM32ardui
k008 wrote: Sun Oct 06, 2024 6:59 am
But what is the correct way to do calibration if you use STM32RTC.h?
STM32RTC-libaray can't do it by itself.
You have to use getHandle() and then use this handle in HAL_RTCEx_SetSmoothCalib().
Re: Calibration of stm32f103 clock
Posted: Mon Oct 07, 2024 7:46 pm
by k008
And the code I gave above won't work?
Can you show an example of how you propose to do it?
Also, clarify the order of using the library and calibration. That is, at what point, which registers can be edited. Can I initialize the clock, and then do the calibration or should this be done immediately at the time of initialization?
Re: Calibration of stm32f103 clock
Posted: Tue Oct 08, 2024 5:30 am
by STM32ardui
I don't used registers directly. So I can't say, if your example works or not. Have you tried it?
My code is like this:
Code: Select all
#include <STM32RTC.h>
#include <stm32g0xx_hal_rcc_ex.h>
uint8_t ret;
STM32RTC& rtc = STM32RTC::getInstance();
void setup() {
rtc.setClockSource(STM32RTC::LSE_CLOCK);
rtc.begin(false,STM32RTC::HOUR_24);
RTC_HandleTypeDef hrtc = *rtc.getHandle();
ret = HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, RTC_SMOOTHCALIB_PLUSPULSES_SET, 493);
}
I used it on a STM32G0B1CBT6 and let it run for 24 hours and changed value for CALM until I had better accuracy.
Re: Calibration of stm32f103 clock
Posted: Tue Oct 08, 2024 7:29 am
by ag123
well, there is an appnote for it
https://www.st.com/resource/en/applicat ... ronics.pdf
And of course cross reference the ref manual rm0008.
That would help more than anyone here who may not have tried it before.
'calibration' is probably an 'incorrect' term, adjustments more like it. There are limits to how much you can adjust with the registers.
With badly out of sync 32k crystals some from Ebay, Aliexpress etc, those can drift by minutes a day, not seconds per month.
there are some codes for doing big adjustments, but that you would need to port it yourself over if you want to use it.
https://github.com/rogerclarkmelbourne/ ... /RTCAdjust
a 'simple' way is to get *good* accurate crystals or chip oscillators maybe from epson etc, probably won't need any 'adjustments' (ever).
https://www.epsondevice.com/crystal/en/ ... ator/tcxo/
32768 hz is a fixed number, chip oscillators made for purpose possibly 'guarantees' it with a small variation.
cheap lousy crystals and oscillators can give you like 10khz to 60khz in a random sample and sold to you as 32768 hz, they didn't bother, you can go ahead and adjust whatever you need.
'adjustment' is a simple concept, if the clock drifts 1 minute faster a month, then simply subtract that much every month (and vice versa). probably won't need any special purpose registers etc to do that.

Re: Calibration of stm32f103 clock
Posted: Sat Oct 12, 2024 7:02 am
by k008
It is based on this guide that I provided the code in the first post, the question is how to use it correctly
'adjustment' is a simple concept, if the clock drifts 1 minute faster a month, then simply subtract that much every month (and vice versa). probably won't need any special purpose registers etc to do that.

when the watch runs on battery, the brain can't think, bad option
STM32ardui wrote: Tue Oct 08, 2024 5:30 am
I used it on a STM32G0B1CBT6 and let it run for 24 hours and changed value for CALM until I had better accuracy.
your option is not suitable for stm32f103
Re: Calibration of stm32f103 clock
Posted: Sat Oct 12, 2024 9:20 am
by ag123
k008 wrote: Sat Oct 12, 2024 7:02 am
It is based on this guide that I provided the code in the first post, the question is how to use it correctly
AN2604 STM32F101xx and STM32F103xx RTC calibration
https://www.st.com/resource/en/applicat ... ronics.pdf
The digital calibration circuit removes 0 to 127 cycles every 2 ^ 20 clock cycles (see Figure 2.).
CAL[6:0]bits in BKP_RTCCR register
Table 1: ...
well, apparently the value in BKP_RTCCR simply slows down the LSE value (lets say 32768 hz) according to the value in BKP_RTCCR register.
Hence, say if you have a crystal that runs 200 seconds too fast each month, look in table 1 that calibration value should be 17.
Hence, store 17 in BKP_RTCCR. That would slow down the RTC by 200 seconds each month.
There are some specific requirements for accessing the backup registers, those should be covered in RM0008.
This concept isn't too different from say to use some simple codes to do this same adjustment, say with some variables. Just that it is 'hardware assisted'. Hence, you won't need to do that in program codes.
Re: Calibration of stm32f103 clock
Posted: Sun Oct 13, 2024 3:52 pm
by k008
That's the thing, the code calibrates the pointer upwards, here are the lines that control the quartz frequency and the additional coefficient to calculate the time faster.
And the question is exactly how to combine the simplicity of the RTC library control and the given code. As far as I understand, the RTC does approximately the same thing during initialization as the calibration code, so it is impossible to use the library and calibration together. Perhaps you can tell me how to do this correctly
BKP->RTCCR |= 3; //RCC calibration
RTC->PRLL = 0x7FFF; //Set the divider to 32768 (32767+1)
Re: Calibration of stm32f103 clock
Posted: Mon Oct 14, 2024 4:31 am
by ag123
I've not used this yet, but assuming
you are using STM32RTC
after you run the setup() codes, e.g.
https://github.com/stm32duino/STM32RTC/ ... pleRTC.ino
Code: Select all
void setup()
{
Serial.begin(9600);
// Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK.
// By default the LSI is selected as source.
//rtc.setClockSource(STM32RTC::LSE_CLOCK);
rtc.begin(); // initialize RTC 24H format
// Set the time
rtc.setHours(hours);
rtc.setMinutes(minutes);
rtc.setSeconds(seconds);
// Set the date
rtc.setWeekDay(weekDay);
rtc.setDay(day);
rtc.setMonth(month);
rtc.setYear(year);
// you can use also
//rtc.setTime(hours, minutes, seconds);
//rtc.setDate(weekDay, day, month, year);
}
my guess is that you can add your register tweaks after those codes run.
if you reset the device between the RTC setup runs, you would also need to figure out some way to skip initialization if RTC is already running.
Alternatively, as the source codes is in the repository, you can make changes to the local copy of the source codes.