Contamos con la mejor solución que encontramos online. Nuestro deseo es que te resulte de ayuda y si quieres aportar algo que nos pueda ayudar a crecer hazlo con libertad.
Solución:
HAL_GetTick()
deberían devuelve el número de milisegundos transcurridos desde el inicio, ya que muchas funciones HAL dependen de él. Cómo lo logras depende de ti. Por defecto, HAL_Init()
consulta la velocidad del reloj del sistema y establece la frecuencia de SysTick en 1/1000 de eso:
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
/*Configure the SysTick to have interrupt in 1ms time basis*/
HAL_SYSTICK_Config(SystemCoreClock /1000);
/*Configure the SysTick IRQ priority */
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0);
/* Return function status */
return HAL_OK;
Luego, el controlador de interrupciones SysTick predeterminado llama HAL_IncTick()
para incrementar un contador interno una vez cada ms, y HAL_GetTick()
devuelve el valor de ese contador.
Todas estas funciones se definen como weak
para que pueda anularlos, siempre que su versión de HAL_GetTick()
devuelve el tiempo transcurrido en milisegundos, estará bien. Puede, por ejemplo, reemplazar HAL_InitTick()
para permitir que SysTick se ejecute a 10 kHz, pero luego debe asegurarse de que HAL_IncTick()
se llama solo en cada décima interrupción. En un controlador STM32F7 de 216 MHz (o el recién lanzado STM32H743 de 400 MHz), en realidad puede bajar a Systick de 1 MHz, pero entonces debería estar muy cuidado de regresar lo más rápido posible del manejador. Y aún sería una pérdida horrible de preciosos ciclos de procesador a menos que haga algo en el controlador que un contador de hardware no puede.
O puede hacerlo sin configurar SysTick en absoluto (anular HAL_InitTick()
con una función vacía), pero configure un temporizador de hardware de 32 bits con un preescalador suficiente para contar con cada microsegundo, y deje HAL_GetTick()
devolver el contador del temporizador.
Volviendo a su problema real, midiendo el tiempo en el orden de microsegundos, hay mejores formas.
Si tiene un temporizador de 32 bits disponible, puede poner el valor de MHz del reloj APB respectivo en el preescalador, iniciarlo y ahí está su reloj de microsegundos, sin restarle tiempo de procesamiento a su aplicación. Este código debería habilitarlo (no probado) en un STM32L151/152/162STM32F4:
__HAL_RCC_TIM5_CLK_ENABLE();
TIM5->PSC = HAL_RCC_GetPCLK1Freq()/1000000 - 1;
TIM5->CR1 = TIM_CR1_EN;
luego obtenga su valor en cualquier momento leyendo TIM5->CNT
.
Consulte su manual de referencia qué temporizadores de hardware tienen contadores de 32 bits y de dónde obtiene su reloj. Varía mucho en toda la serie STM32, pero debería estar presente en un F4.
Si no puede usar un temporizador de 32 bits, entonces está el contador de ciclos del núcleo. Solo habilítalo una vez con
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
y luego leer el valor de DWT->CYCCNT
. Tenga en cuenta que a medida que devuelve los ciclos de procesador transcurridos, se desbordará en un par de segundos.
EDITAR:
Acabo de notar que estás usando un STM32L0. Por lo tanto, olvídese de los temporizadores de 32 bits y los núcleos de más de 200 MHz. Utilizar .DWT->CYCCNT
, o piense con mucho cuidado acerca de la duración de los intervalos que le gustaría medir y con qué precisión, luego tome un temporizador de 16 bits. Puede publicarlo como una pregunta separada, describiendo con más detalle cómo se ve su hardware y qué debería hacer. Puede haber una manera de activar un inicio/parada de contador directamente por los eventos que le gustaría cronometrar.
Son ambos. La mayoría de las veces, la función que incrementa el contador de ticks HAL está conectada a la interrupción SysTick, que está configurada para marcar cada 1 ms. Por lo tanto HAL_GetTick()
devolverá el número de milisegundos desde que se configuró la interrupción SysTick (esencialmente desde el inicio del programa). Esto también se puede considerar como “la cantidad de veces que la interrupción de SysTick ha ‘marcado'”.
Aunque la pregunta ya fue respondida, creo que sería útil ver cómo HAL usa HAL_GetTick()
para contar milisegundos. Esto se puede ver en la función de HAL HAL_Delay(uint32_t Delay)
.
Implementación de HAL_Delay(uint32_t Delay)
desde stm32l0xx_hal.c
:
/**
* @brief This function provides minimum delay (in milliseconds) based
* on variable incremented.
* @note In the default implementation , SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals where uwTick
* is incremented.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @param Delay specifies the delay time length, in milliseconds.
* @retval None
*/
__weak void HAL_Delay(uint32_t Delay)
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a period to guaranty minimum wait */
if (wait < HAL_MAX_DELAY)
wait++;
while((HAL_GetTick() - tickstart) < wait)
Puntuaciones y reseñas
Nos encantaría que puedieras mostrar este artículo si te valió la pena.