Ayer había retomado el proyecto en que estoy trabajando (si, me da vergüenza pero debo admitirlo, aún sigo con la estación automática) y me tope con una problemática que a más de uno le habrá pasado, que son distintos eventos que necesitan tiempos diferentes.
La lógica es hacer desbordar al TMR0 el tiempo necesario y con uno o dos variables auxiliares, lograr el tiempo necesario, por ejemplo 2 segundos. Si hacemos desbordar el TMR0 cada 50 ms, se necesita que desborde 4 veces (50ms x 40 = 2000ms = 2 segundos). Pero, ¿que pasa si otro evento necesita un tiempo de 5 segundos?
Muchos pensarán en utilizar un segundo timer o temporizador, pero hay varias formas de utilizar el TMR0 para diferentes eventos con diferentes o iguales tiempos. Yo voy a describir una que por ahora tengo resultados satisfactorios.
Lo primero es utilizar un temporizador (timer) con habilitación de la interrupción por desborde y el tiempo de desborde tiene que ser un número que multiplicando con números enteros, se logre el tiempo necesario para los diferentes eventos. En mi caso utilizo el timer con desborde cada 50ms y utilizando una variable por cada evento, lo que nos da una repetición hasta 12750 ms o 12,750 segundos (50ms x 255). La forma de trabajar es tan sencilla que en la parte en que el CP atiende la interrupción, solo se decica a incrementar en uno una variable, todo el trabajo se concentra fuera de la interrupción.
Partimos de la base en que, cada interrupción, el CP incrementa a uno a una variable llamada timer_50ms, por dar un ejemplo y el mismo está ubicado en el banco 0 (para los usuarios de ASM aunque el banco elegido es indistinto, solo hay que recordar en que banco se utiliza esta variable). En la rutina de un evento que necesita un tiempo de x segundos (por ejemplo, 2 segundos), hay que leer el valor de timer_50ms y guardarlo en otra variable, por ejemplo llamado tiempo_2s, a este variable, sumarle la cantidad de veces que tiene que repetir los 50ms para llegar al tiempo deseado y que en nuestro ejemplo sería 40 (50ms x 40 = 2.000ms = 2 segundos). Por lo que a el contenido de tiempo_2s sumarle 40 y guardarlo en el mismo registro.
Para saber cuando ocurrió el tiempo necesario, será necesario chequear permanentemente el valor de timer_50ms y compararlo con tiempo_2s. Si timer_50ms es igual o mayor que tiempo_2s el tiempo necesario habrá transcurrido y hacer la rutina necesaria, en caso de que sea menor, habrá que seguir esperando.
Si me entendieron hasta aquí, quiere decir que tenes suerte, no es que yo sepa explicar vamos bien y te habrás dado cuenta que un evento con otro, son independiente entre sí, y cada evento parte de una valor de timer_50ms que se estará desbordando y comenzando desde cero nuevamente hasta apagar el microcontrolador, si aún no entendiste, seguí leyendo que ya me vas a entender.
Supongamos que ahora tenemos otro evento que necesita un tiempo de 5 segundos para ello utilizamos el TMR0 que desborda cada 50ms. Para ello hacemos lo mismo que en el evento anterior, leemos el valor de la variable timer_50ms y lo guardamos en la variable llamada tiempo_5s. A esta variable le sumamos 100 (50ms x 100 = 5 segundos). Una vez echo esto tendremos que comparar el valor de timer_50ms con tiempo_5s. Y pasa lo mismo, si es mayor o igual timer_50ms con tiempo_5s quiere decir que el tiempo necesario ya pasó, y si es menor, no y habrá que seguir esperando.
Este método sirve para cuando un evento está esperando que pase cierto tiempo y se pueda ocupar la espera en realizar otro trabajo y que se topa con otro evento que necesita que pase cierto tiempo y en que la espera, el CP pueda hacer otra tarea.
Espero que se halla entendido, sino pregunten por favor.
Saludos.