ATMega16: Ejecutar una subrutina por un tiempo limitado

1

Tengo un problema en ATMega16. Parece que no puedo ejecutar una subrutina durante un tiempo determinado. Aquí está el código:

void reverse(unsigned x){
    OCR0=x;                 //PWM 100%
    PORTB &= ~(1<<PB0);     //+ of Motor1   LOW
    PORTB |= (1<<PB1);      //- of Motor1   HIGH
    PORTB &= ~(1<<PB2);     //+ of Motor2   LOW
    PORTB |= (1<<PB4);      //- of Motor2   HIGH
}

por lo que es básicamente una subrutina de control de motor que aplica una Señal PWM rápida utilizando el Puerto PB3. La entrada es el ciclo de trabajo. Los 2 motores se controlan utilizando un L298.

Ahora, quiero transformar el código para que tome el ciclo de trabajo Y un cierto valor para el tiempo, como 50ms.

Estoy usando Atmel Studio 6.0 en Windows XP.

Gracias de antemano.

    
pregunta user18476

2 respuestas

1

Hay muchas maneras de hacer algo como esto. Suponiendo que esté usando AVR gcc, podría usar las funciones de utilidad en util / delay.h, específicamente _delay_ms () sería aplicable para su requerimiento. Puede encontrar la documentación en www.nongnu.org/avr-libc/user-manual/group_ < em> util _delay.html . Sin embargo, tenga en cuenta que existe un retraso máximo que puede generar al usar estas funciones, dependiendo de la velocidad de su reloj. Si desea demorar más tiempo, tendrá que usar algún tipo de bucle que lo llame repetidamente. La forma típica de usarlo en su caso sería hacer lo que tiene su función, luego retrasar y luego deshabilitar sus motores y demás. Sin embargo, hay algunas desventajas en el uso de este método. En primer lugar, estos retrasos son esencialmente para bucles simplemente en bucle alrededor de un cierto número de iteraciones. Esto significa que no son exactamente precisos. Además, cualquier interrupción que pueda estar ocurriendo causará que este tiempo se extienda.

Cuando se escribe firmware, a menudo es mejor evitar usar este tipo de retrasos. No solo son inexactas, también están bloqueando llamadas. Mientras dura el retraso, el procesador no puede ejecutar ningún otro código (a menos que sea dentro de una interrupción, lo que elimina el retraso). Hay mejores formas de resolver su problema, pero necesitan más trabajo. Una forma es configurar un temporizador para que interrumpa después del tiempo requerido, y luego use el código que el manejador de interrupciones llama para detener el motor. La "buena" forma de hacerlo sería establecer un indicador dentro de la interrupción y hacer que el bucle principal verifique este indicador. De esta manera, el bucle principal puede controlar varias cosas en paralelo y ejecutar el código en el momento correcto.

Los sistemas más complicados podrían usar un RTOS para hacer esto, pero a menudo vienen con más equipaje del que vale la pena a menos que realmente necesite una alta precisión y tenga muchas cosas diferentes que tienen que suceder en paralelo.

    
respondido por el Chintalagiri Shashank
0

¿Por qué no usa un registro de interrupción de temporizador y salidas pwm integradas en ATMega? Esa sería la forma más robusta y precisa de hacerlo que no sea utilizar un RTOS ya sugerido. Incluso puede verificar el ciclo de trabajo de salida con un osciloscopio.

    
respondido por el zacharoni16

Lea otras preguntas en las etiquetas