Bueno aqui dejo un codigo base para un tiempo de 999.96 milisegundos, practicamente 1 segundo, con un error de 4us, creo puede mejorarse
, en fin no es muy complicado pero si es necesario conocer mas a fondo los ciclos de maquina para mayor precisión, aparte de tener en cuenta el oscilador a utilizar y que rango del divisor prescaller usar, en mi caso, no necesito tanta precisión pero quise llevarlo un poco mas allá, y logre hasta 999.96ms, para llegar aquí primero coloque al máximo el prescaller osea 256, osea cada 256 ciclos el cuenta 1, como cada ciclo de maquina es de 4 pulsos de reloj, en la formula que encontré del TMR0, es por eso la multiplicación por 4 luego de la división de 1/F, lo que da 1us por cada ciclo de maquina para los microcontroladores pic, eso utilizando un oscilador de 4MHZ, si es de 20MHZ da 0.2us, para poder lograr mas o menos 1 segundo con un margen de error mínimo con 20MHZ, lo que hice fue escoger un valor redondo en mi caso 12800us, utilizando un programa que encontré y anexo,
esos 12800us me dan con un valor de 6 cargado en el registro TMR0, lo que quiere decir que a partir de alli es que empieza a contar,
o lo que es lo mismo le resto a 256 - 6, entonces ahora no desborda al contar de 00 a 256, si no de 06 a 256,
si sacamos cuenta, para ciclos
con duración de 0.2us x 250 = 50us x 256 = 12800us = 12.8ms,
ahora eso no es ni la mitad de un segundo, para llegar a 1 segundo, multiplique cuantas veces fue necesario para llegar lo mas cerca a 1 segundo,
en mi caso elegí 78 que da 12.8ms x 78 = 998.4ms,
elegí ese porque era el mas redondo de los que calcule, ahora tengo una diferencia de 1,6ms, para compensarlo coloque 20us de pausa por cada interrupción
como son 78 entonces 20us x 78 = 1560us = 1.56ms
Y en total tenemos 998.4ms + 1.56 = 999.96ms por cada 78 interrupciones.
Ahora esto es relativo, si sabemos que cada ciclo es de 0.2us, si después de la interrupción, hacemos un procedimiento ya sea de suma o condicional, eso consume ciclos de maquina lo cual debe restarse del tiempo calculado,
digamos que un IF THEN, consume 2 ciclos de maquina,
entonces tendríamos que multiplicar 0.2us x 2 x 78 y nos daría cuanto es el tiempo que tendríamos de diferencia para 1 segundo con esa instrucción y así para cada instrucción que se vaya a realizar en la subrutina de interrupción.
Bueno hasta aquí la pequeña explicación dejo el programa, el código y la simulación para que la prueben, el código esta comentado en ingles para los registros de interrupción y option lo coloque así por que se entiende mejor que al traducirlo.
El programa lo que hace es togglear un led cada segundo bueno cada 999.96ms aproximadamente...Cualquier cosa que me este equivocando me avisan...
PD: El pulsador no tiene ninguna función de momento era para las practicas, en el proteus tienen una opción que esta en la barra de herramientas debug que se llama "Excute For Specified Time", sirve para ejecutar la simulación en un tiempo especificado es milisegundos, para menor tiempo pueden poner 0.500 y es medio segundo.