Ademas ASM es mas rapido ^^. lo que no recuerdo es si el 16F84 tiene interrupciones :S,, por que no le veo sentido usar una suma,, para saber cuando el timer supero el valor 0x80.. y luego si usar un solo contador si es que da el tiempo y sino anidarlo asi como lo hace el programa.. Lo veo facil, pero hubiera preferido una interrupcion xD. Otra cosa que me llama la antencion, y que lo pongo aca es:
¿Cuando pone a 0 el TMR0? (Respuesta abajo.)
TIMER
btfss TOGFLG ; TOGFLG esta en 1 ? , si esta en 1 salto
goto TIMER1 ; Si esta en cero me voy a TIMER1
movlw B'01111111' ; Pongo el valor 0x7F en W0
addwf TMR0, W ; hago la suma W0 = TMR0 + W0
btfss STATUS, C ; La suma supero los 8 bits ? es decir TMR0 es mayor a 0x80 entonces salto. O en tiempo (2^8*4us) donde 2^8 es la cantidad de combinaciones con 8 bits y 4us es la frecuencia de la CPU
retlw 0 ; Si no supero el valor vuelvo al programa principal desde donde se llamo a esta seccion
bcf TOGFLG ; Si supero el valor, pongo a 0 TOGFLG
incfsz SX1TMR, F ; SX1TMR resolution ~= 1ms e incremento --- O sea incremento hasta que llegue al valor 0xFF, al incrementar una vez mas pasa a 0x00, mientras que no sea 0 salta
retlw 0 ; SX1TMR overflow ~= 0.25sec (2^8*1ms) ---- Aca vuelve al programa principal desde donde se llamo a esta seccion. Cuando se cumple que llega a 0 el valor de SX1TMR, han pasado aproximadamente 0.25 segundos
incf SX2TMR, F ; SX2TMR resolution ~= 0.25sec -- Pero como hago para ahcer una demora mas grande?, y bueno, cada vez que llegue a 0 SX1TMR pasan 0.25 seg, entonces aca cuento cuantas veces paso por 0
retlw 0 ; SX2TMR overflw ~= 1min (2^8*0.23sec) -- Cuando este segundo registro llegue a 0 quiere decir que se cumplieron 2^8 veces el tiempo 0.25 seg y vuelve al programa principal como en los demas casos
TIMER1 -- El llegar aca me dice que es la primera vez que se llama la funcion, por lo cual TOGFLC esta en 0, o que ya el temporizador supero el valor 0x80, esta parte me asegura que solo se ejecute el incremento de los registros de arriba
-- solo si el TMR0 tiene el valor esperado, sino mientras vuelve al programa principal.
movlw B'01111111' ; Timer routine spends half its time
addwf TMR0, W ; in TIMER1 waiting to set TOGGLE
btfsc STATUS, C ; to one again
retlw 0
bsf TOGFLG -- En caso de no superarse el valor, esta bandera indica que es momento de incrementar el valor de SX1TMR y/o SX2TMR, dependiendo de los valores de los mismos. Y vuelvo al programa nuevamente
retlw 0
Bueno por lo visto no pone a 0 el TMR0, y lo unico que hace es que entre a sumar los registros solamente cuando el TMR0 tenga el valor 0x81, de ahi se pone a cero el TOGFLG y empieza a entrar en TIMER1 hasta que llegue a 0x00. donde se setea el bit TOGFLG y empieza a preguntarse en TIMER si llego al valor. y de vuelta el ciclo completo.
TOGFLG (intento de traducir TOGGLE FLAG supongo)
Bue eran las 5.30am cuando lo vi xD,, no se puede pedir mucho de mi a ese horario xD
P.D: Ahora que lo pienso un poco mejor, que enriedo que se pego el programador ese xD, podria haber hecho directamente una resta y listo,, sin tantos saltos xD, O sea asi:
TIMER
movlw B'10000000' ; Valor 0x80 en W0
subwf TMR0, W ; resto W0 = TMR0 - W0
btfss STATUS, Z ; Si es igual, tengo cero de resultado en W0 y logro que la bandera Z se active
retlw 0 ; Si no es igual vuelvo
incfsz SX1TMR, F ; Incremento el primer registro
retlw 0 ; hasta que no llegue a 0 nuevamente vuelvo
incf SX2TMR, F ; Incremento segundo registro cuando el primero ya completo toda una vuelta
retlw 0 ; Y vuelvo
Pasado a C, con mi mal C por que NO SE xD, seria algo asi para q te des una idea:
TIMER(void) --- Si es que se escribe asi xD
if ( TMR0 == 0x80)
{
SX1TMR++;
if (SX1TMR == 0x00)
{
SX2TMR++;
}
}
Return(0); --- Y esto igual xD je
E incluso podria ahi haber seteado los leds xD je , Asi en la otra parte del programa no tenia q estar fijandose cuando se pone a 0.. bueno espero tu respuesta.. aunque creo que no lo vas a tocar xD
Espero que de algo te sirva...