Estimado... el tema de los Timer da para varias enciclopedias... pero tal vez lo más sencillo para comenzar a aprender a usarlos es hacer y probar algunas rutinas generando "períodos" con el Timer Overflow (TOF). El QG8 permite, con su Timer llamado TPM, generar interrupciones de TOF con un período programado por nosotros. Esto nos permitiría tener un "aviso" periódico de que ha transcurrido dicho tiempo, y a ese evento utilizarlo para otros fines. Esta forma básica sería entonces "algo que ocurre" cíclicamente, y como es por interrupción, el micro quedaría libre para otras tareas... y yo solo debo consultar en el lugar correcto del código, si ha pasado el tiempo programado o no. Es decir, si hubo TOF o no.
Voy a tratar de ejemplificarlo "en Español" y sin demasiados detalles de registros para que se entienda:
- Supongamos que se dejan los "seteos" de fábrica en cuanto a fuente de clock y valores de registros. El QG8 "arranca" con una Fbus de 4Mhz.
El ciclo de clock será de 0.25 uS y a esa velocidad se incrementará el contador "libre" del TPM (llamado TPMCNTH y L).
- Como el contador es de 2 bytes, el Overflow se producira cada 65535 * .25 uS = 16383.75 uS. Es decir cada 16.38 mS.
Para este caso, no puedo tener TOF para períodos mayores a ese, pero sí puedo programar períodos menores, y más exactos, que pueda luego utilizar.
- Cómo hago? Uso los registros TPMMOD (H:L). Este registro de 2 bytes me permite "recortar" la cuenta del contador libre, para que solo cuente hasta el valor "escrito" en el TPMMOD(H:L).
- Si para este caso (Fbus = 4mhz y Ciclo de .25 uS) hago que TPMMOD(H:L) = 40000, entonces el contador libre solo contará hasta 40000 y no hasta 65535, con lo cual el TOF se producirá cada 40000 cuentas de .25 uS, es decir, cada 10000 uS, o bien, 10 mS.
Esto solo por poner un ejemplo... podemos programar otros valores en TPMMOD(H:L), sin duda...
- Si habilitara la interrupción por TOF, ésta ocurrirá cada 10mS (para este ejemplo) y cada vez que ocurra un TOF, se llamaría la rutina de interrupción.
La interrupción por TOF se habilita escribiendo un "uno" en el bit TOIE del registro TPMSC. Debo tener encuenta que en los vectores de interrupción, debe estar escrito el correspondiente "nombre" (etiqueta) de mi interrupción, para que cuando esta ocurra, el programa acuda a atenderla, llamando dicha rutina.
- En la rutina de interrupción por TOF podemos hacer varias cosas, pero para comenzar a probar esto, si uno no lo utilizó nunca, lo mejor es "encender el típico led" para comprobar el funcionamiento de todo lo implementado. Algo así, por ejemplo... con un led en el bit 0 de PortA:
isrVtpmovf:
; Write your interrupt code here ...
*Se ha seteado Oscilador INTERNO y FLL enganchado, con Divisor igual a 2.
*Eso da una Fbus=4Mhz.
*Con TMOD=40000 (decimal) el TOF queda cada 10mS.
PSHH ;Salvo el registro H en la pila (como en toda interrupción!!!)
LDA TPMSC ;Leo el TMPSC y le escribo un "cero" al bit TOF, para resetear la bandera TOF
AND #$7F ;y la interrupción por TOF.
STA TPMSC
BRSET 0,PTAD,PONCERO ;SI EL PTA(0) = 1, SALTO A PONERLE 0.
BSET 0,PTAD ;...SI NO, LE PONGO "UNO" (prende led).
BRA XRUT ;Y SALTO A LA "SALIDA" DE ESTA RUTINA.
PONCERO:
BCLR 0,PTAD ;LE PONGO CERO AL PTA(0) PARA APAGAR LED
XRUT PULH ;ESTA ES LA SALIDA DE LA RUTINA, DONDE RECUPERO
RTI ; EL REGISTRO H y hago el RTI.
; end of isrVtpmovf
- En conclusión, la rutina anterior haría que el led esté encendido 10mS, apagado 10 mS, y así sucesivamente... for ever.
Esto no es para mirar con los ojitos, para comprobarlo hace falta osciloscopio, cabe acotar.
Este sería "en criollo" un ejemplo bastante básico de cómo generar un período con el Timer... para usarlo luego en retardos, antirrebotes, relojes, etc.
Si me olvidé de algo, o hay algún error, por favor avisenme.
Si hay alguna duda, intentaré aclararla... pero PERDÓN: solo respondo en "Assembbler" (que es mi lenguaje materno-infantil
).
Saludos a todos, y especialmente al amigo Cicloide2, por generar esta pregunta.
Gracias.