Cómo usar SysTick_Handler (una función de biblioteca HAL) para tener una base de tiempo

0

En realidad necesito medir la velocidad del motor. He seguido un procedimiento, es decir,

  1. use el modo Codificador para obtener pulsos del sensor.
  2. cuente el número de estos pulsos en 1 seg ~ 1000 ms usando SysTick_Handler (ISR). Significa usar la función SysTick_Handler como una base de tiempo para contar los pulsos en 1000 ms.

Ahora, estoy un poco confundido acerca de cómo incorporar el paso no. 2 en los códigos. Porque me han enseñado que el controlador Systick (ISR) se llama cada 1 milisegundo. Y si es así, mientras pasa por las líneas de códigos dentro del Controlador, no se pasará la duración de 1 milisegundo por segundo. ¿No se volverá a llamar al Systick_Handler incluso antes de contar completamente por 1 milisegundo? Además, ¿cómo me aseguro de que Systick_Handler cuente por solo un segundo y luego comience nuevamente a contar después de que se haya superado la duración de 1 segundo?

This is the Handler function. 

void SysTick_Handler(void)
{
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  Encoder_Start();                     //encoder mode start

  counter=Encoder_Read(void);          //reading counter(defined globally and shared by handler and main)

  Encoder_Stop();                      //encoder mode stop

} 

y

    this is the main

    main.c
    .
    .
    .
    uint32_t Encoder_Read(void)         //reads counts from sensor
    {
        return TIM3->CNT;
    }

    void Encoder_Start(void)            
    {
        HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
    }

    void Encoder_Stop(void)
    {
        HAL_TIM_Encoder_Stop(&htim3, TIM_CHANNEL_ALL);
    }
    main()
{
 .
 .
    while()                                                              
    {
      speed=counter*constant;              //speed, counter is used here

      printf("\n%d",speed);                //print speed using semihosting on eclipse
      PWM code;
      PWM code;
      PWM code;
    }
.
.
}

Mi pregunta original era esto

La placa de desarrollo es STM32F407, el sistema operativo es Linux (Ubuntu), el código se genera utilizando STM32CubeMX.

¿Alguna idea sobre esto?

O cualquier otra alternativa, necesito tener una base de tiempo de 1 segundo para medir el número de conteos desde el sensor (basado en LM393) y usar esta base de tiempo una y otra vez para medir la velocidad y mostrarla cada segundo .

Por favor sugerir.

    
pregunta abinjacob

1 respuesta

1

Lo que estás buscando es probablemente un planificador básico. Código de ejemplo:

static volatile uint32_t ms_ticks = 0;
static volatile bool tick_1ms_elapsed = false;
static volatile bool tick_1000ms_elapsed = false;

//! The interrupt handler for the SysTick module
void SysTick_Handler(void)
{
    ms_ticks++;

    tick_1ms_elapsed = true;

    if (ms_ticks % 1000 == 0) {
        tick_1000ms_elapsed = true;
    }
}

void main(void) {

    // Setup SysTick Timer for 1ms interrupts
    if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) {
        while (true) {  /* no error must happen here, otherwise this board is dead */ }
    }

    while(true) {

        if (tick_1ms_elapsed) {
            ... Do something every ms
            tick_1ms_elapsed = false; // Reset the flag (signal 'handled')
        }

        if (tick_1000ms_elapsed) {
            ... Do something every second
            if (state == STATE_1) {
                DoTaskOne;
                state = STATE_2;
            }
            else if (state == STATE_2) {
                DoTaskTwo;
                state = STATE_3;
            }
            tick_1000ms_elapsed = false;  // Reset the flag (signal 'handled')
        }
    }
}

¿Qué hace esto?

  • Inicializamos el temporizador de Systick para activar una interrupción cada milisegundo.
  • Dado que tener manejadores de interrupciones largas es un no ir, lo único que hacemos es manejar una bandera que le indica a nuestra ruta principal (que se maneja durante el flujo normal del programa y no dentro de la rutina de interrupción) que 1 milisegundo ha pasado
  • Adicionalmente, incrementamos un contador 'ms_ticks' que conoce el 'tiempo' actual (tiempo como en milisegundos desde el inicio del programa). Siempre podemos consultar ese temporizador para saber cuánto tiempo ha pasado.

Cuáles serán tus próximas tareas (al menos si te entiendo bien):

  • Como quiere manejar tres eventos que suceden uno tras otro cada segundo, deberá crear una máquina de estado que se ejecute dentro del controlador de marca de 1000 ms.
  • Cambie de un estado al siguiente una vez que haya completado la tarea para la ejecución actual, luego espere hasta que la bandera llegue la próxima vez y sabrá que ha pasado otro segundo.
respondido por el Tom L.

Lea otras preguntas en las etiquetas