STM32F4 (placa de descubrimiento) función de retardo universal (milisegs)

2

En la red, he encontrado la siguiente función para el retraso en milisegundos para STM32F4 (Discovery board MCU :

void delay_us(const uint32_t us)
{
    us*=STM32_DELAY_US_MULT;

    /* fudge for function call overhead */
    //us--;
    asm volatile(" mov r0, %[us] \n\t"
                 "1: subs r0, #1 \n\t"
                 " bhi 1b \n\t"
                 :
                 : [us] "r" (us)
                 : "r0");
}

Dentro de esta función, se usa la constante STM32_DELAY_US_MULT , pero no se declara y no se compila, pero esto no es un problema actual. ¿Cómo se obtiene un reloj STM32F4 actual y se establece esta constante de acuerdo con esto? Si pregunto de otra manera, ¿cómo escribo la función de demora (milisegs) para STM32F4 proc, que es independiente del reloj?

    
pregunta KernelPanic

2 respuestas

2

En su lugar, podría usar un temporizador o el RTC con una precisión inferior a milisegundos. Estos son mucho más versátiles y previenen ocupado-waiting . También se pueden configurar fácilmente como espera ocupada agregando un bucle while adicional cuando sea necesario.

Hay un código de ejemplo existente para lo que quieres lograr. Este ejemplo muestra cómo obtener el reloj del sistema actual, etc.

Si descarga: STM32F4 DSP y la biblioteca de periféricos estándar

y navega hasta:

STM32F4xx_DSP_StdPeriph_Lib_V1.2.0 \ Project \ STM32F4xx_StdPeriph_Examples \ SysTick \ SysTick_Example \ system_stm32f4xx.c

Hay una función llamada: SystemCoreClockUpdate ()

Esta función y los comentarios anteriores del estilo Doxygen responderán a tu pregunta.

En mi experiencia con STM32, los ejemplos de bibliotecas de periféricos estándar generalmente tienen la mayoría de las respuestas cuando se trata de configuración. También puede ver los ejemplos de la biblioteca de periféricos estándar para STM32F1, STM32F2, STM32F3, etc. también. Hay muchos ejemplos por ahí. Prueba también los ejemplos de Keil.

    
respondido por el iQt
2

Solo he usado un poco la serie STM32, pero no puedo pensar cómo sería posible hacerlo totalmente independiente del reloj. Podría leer la configuración de PLL pero no tendría una manera de conocer la frecuencia del cristal sin otra referencia de tiempo. Es posible que haya algunos trucos que no conozco al usar elementos como el oscilador RC interno en el perro guardián y otros periféricos para proporcionar esa referencia externa, pero no estoy seguro de si valdría la pena y la precisión no sería tan precisa. bueno como usar un valor calculado a partir de la frecuencia del cristal.

Personalmente, o bien leí la guía familiar y calculé cuántos ciclos debería tomar el ciclo y calculo la constante a partir de eso si se requiere una precisión bastante alta o si no, simplemente adivine el valor inicial y llame con un valor bastante alto como 1000mS y mida con un alcance el tiempo que realmente toma y ajusta desde allí.

En su caso, mencionó milisegundos (aunque el código anterior menciona los microsegundos), por lo que su constante sería bastante grande, por lo que tal vez podría usar algo como lo siguiente sin introducir una cantidad inaceptable de error:

#define STM32_CLOCK_HZ 72000000UL
#define STM32_CYCLES_PER_LOOP 6 // This will need tweaking or calculating

void delay_ms(const uint32_t ms)
{
    ms *= STM32_CLOCK_HZ / 1000 / STM32_CYCLES_PER_LOOP;

    asm volatile(" mov r0, %[ms] \n\t"
             "1: subs r0, #1 \n\t"
             " bhi 1b \n\t"
             :
             : [ms] "r" (ms)
             : "r0");
}

Al menos entonces tiene una constante de fácil lectura / actualización para la velocidad de reloj real del sistema.

    
respondido por el PeterJ

Lea otras preguntas en las etiquetas