STM32F303RE Nucleo se congela a una frecuencia de reloj >40MHz

Tengo una placa Nucleo STM32F303RE con Mecrisp-Stellaris Forth. La consola Forth pasa por USART2, la interfaz conectada a la parte ST-Link de la placa Nucleo (cambiado del USART1 predeterminado). La MCU obtiene una entrada de reloj de 8 MHz del ST-Link, y estoy tratando de usar el PLL para obtener una frecuencia de reloj más alta hasta el máximo nominal de 72 MHz. Esto funciona bien hasta 40 MHz (PLL x5), pero a velocidades de reloj más altas (PLL x6 y superiores), el sistema deja de responder inmediatamente después del cambio de reloj. Cuando coloco el reloj del sistema en un pin de salida y mido con un osciloscopio, veo la frecuencia esperada hasta 72 MHz, por lo que no estoy seguro de si la MCU realmente se bloqueó o si es solo un problema de comunicación. El USART está configurado para usar el reloj HSI, por lo que no debería verse afectado por el interruptor del reloj.

Específicamente, esto es lo que hago:

  • Cambiar el reloj USART2 a HSI
  • Arranque HSE con reloj externo de 8 MHz (HSEBYP)
  • Configure GPIOA para dar salida al reloj del sistema en el pin MCO
  • Configure la fuente PLL desde HSE y el multiplicador deseado
  • Habilitar PLL, esperar hasta que esté listo
  • Cambiar el reloj del sistema a PLL

En este punto, todo funciona como se esperaba para multiplicadores <= 5, pero la consola se congela para multiplicadores >= 6. La frecuencia medida en el pin MCO es (multiplicador * 8 MHz), para todos los multiplicadores <= 9.

Cuarto código para completar:

: setup-gpioa
    $20000 RCC_AHBENR bis!
    $0F GPIOA_AFRH bic!
    $20400 GPIOA_MODER bis!
    $04000000 RCC_CFGR bis!
;

: toggle-led 32 GPIOA_ODR xor! ;

: delay 1000 0 do nop loop ;

: wait-for ( mask a-addr -- ) begin 2dup bit@ 0= while delay repeat 2drop ;
: wait-clear ( mask a-addr -- ) begin 2dup bit@ while delay repeat 2drop ;

: usart2-hsi ( -- ) $30000 RCC_CFGR3 bis! ;

: start-hse ( -- )
    $50000 RCC_CR bis!
    $20000 RCC_CR wait-for
;

: start-pll ( pllmul -- )
    18 lshift $04010000 or RCC_CFGR !
    $1000000 RCC_CR bis!
    $2000000 RCC_CR wait-for
;

: stop-pll ( -- )
    $1000000 RCC_CR bic!
    $2000000 RCC_CR wait-clear
;

: sysclk-pll ( -- ) RCC_CFGR @ $FFFFFFFC and 2 or RCC_CFGR ! ;
: sysclk-hsi ( -- ) RCC_CFGR @ $FFFFFFFC and RCC_CFGR ! ;

: setup usart2-hsi sysclk-hsi start-hse setup-gpioa ;

: test-pllclk ( pllmul -- ) sysclk-hsi stop-pll start-pll sysclk-pll ;

setup
3 test-pllclk  ( for multiplier 5, works )
4 test-pllclk  ( for multiplier 6, freezes )

¿Cómo puedo hacer que la MCU funcione a toda velocidad sin congelarse?

Respuestas (1)

Los relojes no están configurados correctamente.

Por ejemplo, el APB1 tiene un reloj máximo de 36 MHz.

Y es probable que también necesite reconfigurar la configuración de flash, como agregar más estados de espera para trabajar con la frecuencia más alta.

Realmente sería útil ver cómo la herramienta de configuración de CubeMX debe configurar los relojes para que no tenga que revisar la hoja de datos y el manual de referencia para todo lo relacionado con el reloj.

Puedo confirmar, con la latencia de flash configurada correctamente y el preescalador APB1 configurado en 2 por encima de 36 MHz, funciona. ¡Gracias!