Bueno ahora si entiendo, voy a decirte que puede estar mal en tu programa antes de decirte "hacelo con interrupciones" ( esto seria lo ideal ) y hacerte cambiar bastante del mismo metiendote en tal ves algo que no manejas muy bien.
Por lo visto esta bien estructurado el programa, por ahi le faltaria un poco mas de comentarios para recordar lo que haces, acostumbrate a eso, te va a salvar la vida bastantes veces.
1- Mientras el programa esta corriendo, no hay nada que evite que se pueda "incrementar" o "decrementar" la variable.
2- Los delays pueden hacer que no corra en "segundos" sino que por ahi se actualize mas lento y termines perdiendo mucha precision, por ejemplo si pones 30 segundos, tal ves pasen 35 por culpa de no hacerlo con una interrupcion al timer.
3- Dejando de lado los otros problemas encuentro algunos problemas de programacion. Aca recopilo todos los problemas de programacion
DECFSZ SEG,1
RETURN
MOVLW B'1001'
MOVWF SEG
DECFSZ MIN,1
RETURN
Esa es una parte de tu codigo, hay en 2 partes que restas.. pero es algo bastante simple, tu idea es que vaya de 9 a 0, y cuando supere el 0 pase nuevamente a 9, graficamente
6 - 5 - 4 - 3 - 2 - 1 - 0 - 9 - 8
Pero ahi primero resta y luego pregunta, lo cual te queda algo asi:
6 - 5 - 4 - 3 - 2 - 1 - 9 - 8
Por que decrementaste cuando estaba en 1 eso es 0 y luego pregunta.
Una solucion bastante "simple" a esto seria decrementar y luego preguntar por si el bit 7 de ese registro SEG,7 esta en 1, si esta en 1 ponerle un 9, esto es por que cuando tu registro de 8 bits le restas 1 estando en 0x00 pasa a 0xFF
Sigamos con otro error de programacion
No tan facil de ver esto, pero CBLOCK en realidad no crea "variables" es decir, para el compilador esas no son variables ni registros sino que le das un valor fijo que si lo usas en las instrucciones se reemplaza, pero observa que tenes ahi, tenes un MOVLW, eso estaria moviendo esa constante ( OJO no el contenido, sino lo que indica la direccion ) en tu programa es 0x2D (NUM es el registro ubicado en esa direccion) , en fin, creo que es un error, para mi que trataste de cargar el valor que tiene DENTRO el registro NUM, para eso deberias haber usado MOVF , y no MOVLW
Una cosa que note tambien es que te olvidas quitar el FLAG en el boton de reset, asi que usas el bit 0 del registro EMPIEZA para indicar que deberia contar pero cuadno presioans reset no lo pones a 0.
Tenes que tener ojo aca, ya que el timer0 JAMAS para,
Tampoco estas limpiando el flag cuando salis, lo cual queda en 1, esto significa que apenas presiones el boton de start y este a 1 el flag del timer, va a entrar rapidisimo ahi, por que estaba puesto en 1 el flag tuyo y estarias "perdiendo" 1 segundo. Una solucion rapida seria poner en 0 el flag del timer y cargar el valor del mismo cuando presionas start
Yo pregunte por el timer1 por que al ser de 16bits permite acercarse mas al valor de 1 segundo o un multiplo del mismo, incluso se puede usar otros modulos que pueden facilitar aun mas la operacion de cargar el timer,etc etc etc. como el CCP ( Capture/Compare/PWM)
Usando el TMR0 , como lo tenes configurado con preescaler 1:2 y cargandole 226 al registro, tenes que cada "interrupcion" o se va a poner a 1 el flag cada 0.06ms o 60us
Tcy = 4 / Fosc = 4 / 4Mhz = 1us,
con preescaler 1:2 va a aumentar cada 2us
El valor que le falta para que se dispare el TMR es de 256-226 = 30 => 30*2us = 60us
Es decir que tu flag se va a poner a 1 cada 60us, esto quiere decir que si pones un delay de 30ms, se habria puseto 500 veces a 1 ese flag. o aun peor, tenes cerca de 60 instruccion de un ciclo ( los saltos ocupan 2 ) para atender ese flag.
Asi que deberias arreglar eso, deberias tener un valor mucho mas grande, el TMR0 podes elegir hasta 1:256 en preescaler, es decir se necesita 256 pulsos desde el reloj para que el timer sume 1, y ya sabes que pasaron 256us
Por ser tiempo es mas facil intentar encontrar un valor que es multiplo entero, por ejemplo si logro que en mi timer ocurra ese desborde activandome la bandera cada 0.2s seria genial, ya que cuando cuente 5 veces que ocurre eso, se que paso 1 segundo.
Como dije el TMR0 es mas complejo de hacerlo, con el TMR1 uno puede hacer hasta de 0.5s ( preescaler 1:8 y cargas el valor 3036 en el timer )
Aca pasa a ser un compromiso, como ves no es un numero "redondo" el 256, lo cual por mas que lo multipliques como quieras, vas a tener problemas ya que nunca va a dar exacto.
Por ejemplo con preescaler 1:256 tenes que cargando 61 pasan 0.04992s, asi que deberias contar unas 20 veces ese flag ( borrarlo y cargar 61 de vuelta en el TMR ) para que pase 1 segundo.
Esas son todas las que note... Realmente yo lo haria con interrupciones, y si pudiera hasta con el modulo CCP, el TMR0 va a hacer que tengas error, como ves me qeudo en 0.04992, si tomas como que eso son 0.05, cuando contes 999 vas a tener un error de tiempo de 0.08s + lo que tardas en actualizar el timer con su nuevo valor, el cual le toma 2 ciclos mas al timer, mas el error del oscilador interno por no ser de exactamente 4Mhz, mas el error de no limpiar la bandera y cargar el timer apenas ocurre el overflow eso te lleva a tener segundos de error y mas si se usan delays.
La solucion aca seria usar una interrupcion.
Para que entiendas un poco mas , para mantener un buen "tiempo" en los timers seria de cargarle el valor ahi noams que se pueda, por que ? Por que cuando el timer pone a 1 su bandera, este sigue funcionando, no se para. y si te tardas tu timer siguio sumando y tal ves tenga un valor de 0x05 , lo cual esos 5 que conto los estarias eliminando cuando le pones un nuevo valor. uno tiene la necesidad de saber cuanto tiempo paso asi que cuenta los ciclos del reloj, asi que cuando conto la cantidad que le pusimos tenemos que actualizar el timer ahi nomas para que vuelva a hacer otro tramo de tiempo mas determinado por nosotros. Espero no haberla complicado con esto.
4- Otra cosa mas que no toque, es la de los botones, lo cual puede que incremente o decrementen mas de 1
5- Posibles (aunque estoy seguro) problemas al mantener presionado el boton start mientras corre el programa
Esto es un offtopic:
Otra 2 cosas mas para pedirte y si te acostumbras mejor, tanto para vos como para mi:
Eso por :
Es mas entendible, F es del registro, por eso INC
F, incrementar registro, como decia es solo para entenderlo mas al codigo xD.
Igual que aca:
podrias haber puesto:
Todos los bits de registros especiales estan incluidos en el p16f88.inc con el mismo nombre que tienen en el datasheet, es mas facil leerlo asi, ya que TMR0IF seria TiMeR 0 Interrupt Flag