0
\$\begingroup\$

I'm trying to query the current value of the APB1 clock frequency to input into a USART configuration. Ideally, I could just query whatever the USART2 clock source is on an STM32F302xx, in case I move to another USART instance that is backed by say, the system clock.

I know what the value is from doing the math, but I want it to be parametrized in case I change clock settings. What is available in the HAL to call to replace my 36MHz value below?

LL_USART_SetBaudRate(USARTx_INSTANCE, 36000000, LL_USART_OVERSAMPLING_16, 115200);

I don't see any way to inspect what has been set by another part of the sytem, only:

HAL_Driver/Inc/stm32f3xx_hal_rcc.h
811:#define __HAL_RCC_USART2_CLK_ENABLE()   do { \
850:#define __HAL_RCC_USART2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN))
953:#define __HAL_RCC_USART2_IS_CLK_ENABLED()  ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) != RESET)
962:#define __HAL_RCC_USART2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) == RESET)
1024:#define __HAL_RCC_USART2_FORCE_RESET()   (RCC->APB1RSTR |= (RCC_APB1RSTR_USART2RST))
1034:#define __HAL_RCC_USART2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART2RST))
1337:#define __HAL_RCC_USART2_CONFIG(__USART2CLKSOURCE__) \
\$\endgroup\$
  • 2
    \$\begingroup\$ You could just access the register directly without the HAL call. \$\endgroup\$ – DKNguyen May 3 at 1:59
  • \$\begingroup\$ @Toor: That doesn't help, you still need to know what baud rate divider to write to the register. \$\endgroup\$ – Ben Voigt May 3 at 3:45
2
\$\begingroup\$

You can't query, because in the general case the system itself has no idea what the frequency is, only ratios between internal clocks and the external source clock (crystal or solid-state oscillator), and a whole range of frequencies are permissible for the source clock. The ratios can be read from PLL and/or clock divider configs.

A few microcontrollers will allow only a single value for the external crystal when certain communication circuits are in use, such as Ethernet, high speed USB, or wireless radios. But even those will allow clocks to vary to achieve power savings.

On most microcontroller models it is possible to determine the clocks without knowing which crystal is in use, by measuring the ratio of two timers, one driven by main system clock, and another driven by slow reference clock (nearly all have a 32 kHz, either as an internal oscillator circuit or a secondary crystal). But that requires assigning a timer resource to the task and waiting a bit, so it's not something you just want to throw into a uart setup function.

Generally, you just make the same choice STM32 did for the HAL function/macro you are using -- require the system developer to pass in the clock rate he's chosen. Actually measuring the frequency would generally only be done in circumstances where you expect drift, such as extreme temperatures, or high frequency digital signals that might be coupling onto your clock pins.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.