2024-01-07 04:07 AM
Hello,
I struggle to use the LSE clock as a source for timer LPTIMER1. My MC is a STM32L051R8Tx and I am using Keil MDK-Lite. ARM Compiler default 5.
For debugging purpose I am using the following settings: PSC = 1; ARR = 3275; Interrupt: Auto-reload match. In the IRQ handler I toggle a LED to measure the frequency by use of a manual stop-watch.
I cant measure the 32,768 kHz. Instead I measure the following:
with printf() statement in loop | with debugger | Lowest drive | ~3,276kHz |
with printf() statement in loop | without debugger | Lowest drive | ~3,276kHz |
without printf() | with debugger | Lowest drive | ~150Hz |
without printf() | without debugger | Lowest drive | ~50Hz |
The frequency is approx. factor 10 less and will dramatically go down when I remove the printf statement inside the while(1) loop. Can someone please give me some hints where I need to have a look on?
bool low_power_timer_init(void)
{
RCC->APB1ENR |= RCC_APB1ENR_PWREN; // 1: Power interface clock enabled
RCC->APB1ENR |= RCC_APB1ENR_LPTIM1EN; // 1: Low-power timer clock enabled
RCC->CCIPR |= RCC_CCIPR_LPTIM1SEL_0; // 11: LSE clock selected as LP Timer cloc
RCC->CCIPR |= RCC_CCIPR_LPTIM1SEL_1; // 11: LSE clock selected as LP Timer cloc
PWR->CR |= PWR_CR_DBP; // 1: Access to RTC, RTC Backup and RCC CSR registers enabled
PWR->CR; // Dummy read, needed due to timings?
LPTIM1->CR = 0; // CFGR must only be modified when the LPTIM is disabled
LPTIM1->CFGR &= ~LPTIM_CFGR_CKSEL; // 0: LPTIM is clocked by internal clock source (APB clock or any of the embedded oscillators)
LPTIM1->CFGR &= ~LPTIM_CFGR_COUNTMODE; // 0: the counter is incremented following each internal clock pulse
RCC->CSR |= RCC_CSR_LSEON; // Enable LPTIM -> LSE (32.768 kHz) clock
// Wait until the LSE oscillator is stable
WaitForConditionToTrue(((RCC->CSR) & RCC_CSR_LSERDY) == RCC_CSR_LSERDY,
I2C_POLL_TIME, return false);
//RCC->CSR |= RCC_CSR_LSEDRV_1; // 11: Highest drive
//RCC->CSR |= RCC_CSR_LSEDRV_0;
RCC->CSR &= ~RCC_CSR_LSEDRV_1; // 00: Lowest drive
RCC->CSR &= ~RCC_CSR_LSEDRV_0;
PWR->CR &= ~PWR_CR_DBP; // Lock Access to CSR register
// If any bit in the LPTIM_IER register (Interrupt Enable Register) is set after that its
// corresponding flag in the LPTIM_ISR register (Status Register) is set, the interrupt is not
// asserted.
LPTIM1->ICR |= LPTIM_ICR_ARRMCF; // Writing 1 to this bit clears the ARRM flag in the LPTIM_ISR register
LPTIM1->IER |= LPTIM_IER_ARRMIE; // 1: ARRM interrupt enabled
//The LPTIM_CFGR register must only be modified when the LPTIM is disabled (ENABLE bit reset to ‘0’).
//LPTIM1->CFGR |= LPTIM_CFGR_PRELOAD; // Registers are updated at the end of the current LPTIM period
LPTIM1->CFGR &= ~LPTIM_CFGR_PRELOAD; // 0: Registers are updated after each APB bus write access
LPTIM1->CFGR &= ~LPTIM_CFGR_TRIGEN_0; // 00: software trigger (counting start is initiated by software)
LPTIM1->CFGR &= ~LPTIM_CFGR_TRIGEN_1; // 00: software trigger (counting start is initiated by software)
LPTIM1->CFGR &= ~LPTIM_CFGR_PRESC_0; // 000: /1
LPTIM1->CFGR &= ~LPTIM_CFGR_PRESC_1;
LPTIM1->CFGR &= ~LPTIM_CFGR_PRESC_2;
return true;
}
void low_power_timer_enable(void)
{
LPTIM1->CNT = 0; // Reset counter value
LPTIM1->CR |= LPTIM_CR_ENABLE; // 1:LPTIM is enabled
LPTIM1->CR |= LPTIM_CR_CNTSTRT; // Setting this bit starts the timer in Continuous mode
// This bit can be set only when the LPTIM is enabled.
LPTIM1->CMP = 0; // CMP is the compare value used by the LPTIM.
// This bit can be set only when the LPTIM is enabled.
LPTIM1->ARR = 3276-1; // This value must be strictly greater than the CMP[15:0] value
// This bit can be set only when the LPTIM is enabled.
}
main()
low_power_timer_enable();
while(1)
{
//printf("\r");
}
Solved! Go to Solution.
2024-01-08 07:01 AM
> By the way: Using TIM2 with the MSI clock is working as excepted, therefore I assume my assumptions on timers are generally ok.
If it works on other clock sources, LSE is not reliable on your hardware. The frequency changing with drive strength suggests this as well. That isn't surprising given the breadboard setup.
Perhaps you can show the schematic. Perhaps load capacitors are incorrectly sized or the crystal is insufficient.
2024-01-08 08:07 AM
What breadboard?
Post photo, especially the 32.768kHz crystal arrangement.
JW
2024-01-08 12:01 PM
Just to be sure: The LSE crystal is already implemented inside the microcontroller, isn’t it? I didn’t put any additional components to the setup. There is no "crystal arrangement".
In RM0377 chapter 7.2.5 I read:
“The LSE crystal is a 32.768 kHz low speed external crystal or ceramic resonator. It has the advantage of providing a low-power but highly accurate clock source to the real-time clock peripheral (RTC) for clock/calendar or other timing functions.”
Furthermore, in chapter 7.2:
“The devices have two secondary clock sources:
• 37 kHz low speed internal RC (LSI RC) which drives the independent watchdog and optionally the RTC used for Auto-wakeup from Stop/Standby mode and the LPTIMER.
• 32.768 kHz low speed external crystal (LSE crystal) which optionally drives the realtime clock (RTCCLK), the LPTIMER and USARTs.”
I would like to use the LSE for timing functions and I read it has a high accuracy (typically a few tens of ppm’s). Attached please find the schematic of the pcb. Removing the ST LINK V2 (breakout from a NUCLEO board) and adding a battery as power supply to the breadboard, the timer is not working/starting at all. Same as for my pcb's.
2024-01-08 12:08 PM - edited 2024-01-08 12:10 PM
The LSE (low speed external) crystal is not inside the MCU. You need to add one externally.
2024-01-08 11:27 PM
Hi TDK,
If this is the case, why is the Reference Manual talking about a special mode using a separate external source (LSE bypass)? I thought this mode is used to add an external clock source of up to 1 MHz. And if you dont use the bypass mode you can use the internal LSE crystal which is specified to be 32,768 kHz. Could you please confirm once again that I interpret the RM wrong?
2024-01-09 12:32 AM
The wording of RM may be not the perfect, and you are not the first to misunderstand it.
You have two options to use LSE:
- connect externally a 32.768kHz crystal (known sometimes also as "watch crystal"), or
- connect externally a 32.768kHz oscillator, when you set the LSEBYP bit (to avoid using the internal amplifier which would be used otherwise as part of the oscillator together with external crystal)
As TDK said above, there's no crystal built into the chip.
JW
2024-01-09 07:11 AM - edited 2024-01-09 07:12 AM
blah