Ejercicio 5.5 con 2 Timers

Ejercicio 5.5 con 2 Timers

de Juan Manuel BORQUEZ PEREZ -
Número de respuestas: 2

Hola Buen día!

Estuve intentando realizar este ejercicio de la rampa de aceleración con 2 Timers. El Timer 1 se utiliza para la generación de los pulsos de frecuencia variable mientras que el Timer 0 se utiliza para el conteo del intervalo de tiempo de 100ms entre cambios de frecuencia del oscilador. El asunto es que no funciona (al menos en el simulador). En cambio el oscilador continúa pulsando a la frecuencia inicial de 50 Hz.

Estuve realizando el debug del programa desde el simulador y aparentemente la rutina de servicio por el evento de que han transcurrido los 100ms se ejecuta correctamente en la primera sucesión del evento. En el siguiente evento de la rutina de servicio parece ser que las instrucciones ejecutadas en el llamado previo han sido revertidas, el registro OCR1A tiene el valor que tenía antes de que se ejecutara la ISR así como también el OCR0A. Si se me puede dar ayuda estaría agradecido!

A continuación dejo el archivo de texto con el código del programa y el archivo del simulador junto con capturas sucesivas del debug del programa.

En el ejercicio utilizo un prescaler x8 utilizo el WGM CTC en ambos TIMERS

En respuesta a Juan Manuel BORQUEZ PEREZ

Re: Ejercicio 5.5 con 2 Timers

de Eduardo Iriarte -
Hola Juan Manuel,
Cuando una variable cambia y parece volver siempre al valor inicial sin motivo... hay que sopechar que el micro se está reseteando. Esto puede ser por problemas de hardware o de software. Las causas de software pueden ser varias, algunas:
1-Una función accede a un array fuera de los límites definidos.
2-Un desborde de pila, por ejemplo si se utilizan funciones recursivas o algún salto que hace que se desbalanceen los "push" y los "pop" al entrar mal (con un salto y no una llamada) a una subrutina o ISR (o salir mal, con un salto y no un retorno).
3-Una interrupción que no tiene su ISR correspondiente.
Por defecto el compilador pone en los vectores de interrupción no utilizados la instrucción jmp 00 (en realidad hace jmp nn y en nn hace jmp 00. (Podés revisar el archivo nnn.lss en la carpeta debug, que es el desensamblado, en la sección .text. Allí al principio de la memoria de programa están los vectores de interrupción)
En este caso, en la función _timer1_setup() habilitaste TIMSK1 |= (1 << OCIE1A), pero no escribiste la ISR corrspondiente ,ISR(TIMER1_COMPA_vect)
Simplemente hay que eliminar esa habilitación de interrupción. También se puede insertar la ISR y dejar vacía, pero entra y sale sin hacer nada útil y quita tiempo.
Fuera de este problema, el algoritmo parece funcionar muy bien, no he verificado los límites pero hay una rampa de velocidad.