TMR0 precision entre PicBasic y ASM

Saludos a todos en este ya experimentado Foro y basicamente realizo una consulta general pues en la experiencia que alguno tenga favor me comenta lo siguiente: He estado probando entre realizar un sencillo contador de tiempo (1seg) utilizando TMR0 con PicBasic la verdad que el codigo no es complicado y facil de entender y al querer mejor precision se utiliza preferente un Cristal externo por ejemplo 4MHz cuando lo he probado con el 16F628A, por ejemplo el codigo que se encuentra en otro hilo de este foro se muestra un ejemplo ya funcional de hacer un contador hasta 5min, lo realize en breadboard y naturalmente aunque se utilizan interrupciones para lograr hasta 1seg de demora el problema que encontre fue que a medida que el tiempo avanza se vuelvo menos preciso a tal grado que en 5minutos logre tener hasta 10segundos mas adelantado. En el siguiente hilo encontraran el ejemplo que utilize: https://www.forosdeelectronica.com/f24/curso-programacion-pic-bsic-pro-20658/index2.html (#23) el caso es con TMR0=cero y Prescaler a 64 logrando 0.016384segundos y repitiendo 61 veces logrando un delay de 0.999424seg cosa que en verdad tendria un ajuste ideal, pero naturalmente las rutinas adicionales de PicBasic para completar mostrar el dato en el LCD que no tengo idea como calcular provoca mas tiempo del deseado, y estar variando la cantidad de veces que se repita la interrupcion mas parece a prueba y error que a calculo matematico.

Entonces probe buscar un ejemplo con ASM (mis respetos para aquellos que dominan la programacion, para mi si es mas arido) y aunque el codigo por supuesto para aquellos que no dominamos ASM parece complejo logra una presicion increible,para decirles que en 25minutos comparado contra un cronometro la diferencia es apenas 1seg (y debe ser entre el tiempo de pulsar el start del cronometro y arrancar el PIC para que empieze a contar).

Por tanto como se puede lograr precision de reloj con PicBasic (por supuesto con Cristal externo por ejemplo en vez de utilizar el oscilador interno del PIC) utilizando TMR0 o TMR1 a traves de interrupciones sin la ayuda de algun RTC. Si alguien ya se topo con esto favor me ilustre.

FELIZ AÑO A TODOS LOS MIEMBROS DE ESTE FORO
 
Si utilizas un buen depurador puedes hacerlo, ya que puedes calcular cuantas instrucciones emplean las rutinas basic.
Yo utilizo picsimulator con su basic y tienes control sobre eso sencillo.
Las rutinas del lcd no tendrian que darte problemas, ya que una vez contado el segundo, se inicializa el timer y mientras el lcd trabaja el timer sigue contando independiente.
No se si el lcd en picbasic utiliza algun timer. Quiza te venga de ahi el problema si usas ese mismo timer.
 
Muchas gracias por la respuesta, en verdad no tengo conocimiento como utilizar el depurador que indicas con PicBasic, y en efecto al enviar comandos al LCD existen milisegundos para cargar la informacion en la pantalla, estoy de acuerdo que los tiempos no son los precisos que me gustaria tener pero no encuentro aun la forma de corregirlo.
 
Prueba el picsimulator. Le cargas el hex y lo pones a funcionar.
Podras contar los ciclos de reloj, de modo que podras saber cuantos pierdes en las rutinas basic.
Si programaras con el propio basic del picsimulator, verias como va saltando en el codigo el punto de ejecucion a la vez que verias todos los cambios en los registros, con lo que puedes ver cuanto has de modificar los tiempos para que sea exactamente un segundo.
es un Basic parecido por lo que se al picbasic pro. Tiene sus propias rutinas LCD. Estas no utilizan los timer del pic, pero las del picbasic no se si lo hacen.
 
Hola Para manejar interrupciones muy precisas te recomiendo que uses Proton que es muy similar a pic basic pro, pero maneja interrupciones por hardware y podes hacerlas muy muy presisas. Y para simular usa rl Proteus o el pic siulator ide que podes ver bien el tiempo de ejecucion y calcular exactamente cuanto tarda cada interrupcion y ir ajustandola hasta que quede perfecta.
Ah te recomiendo trabajar con cristal de 20Mhz, asi cada instruccion que ejecute el programa va a demorar mucho menos tiempo y el error va a ser menor.

Te dejo una parte de mi codigo para que te orientes

GoTo INITIALIZE

On_Hardware_Interrupt GoTo Interrupcion ' Interrupción por Hardware (es la más rápida)
;######################### INTERRUPT CODE ######################################
Disable;
Interrupcion:
Context Save
If INTCON.2 = 1 Then ;######## TIMER ######## ; si la bandera Timer esta activada... entonces
INTCON.2 = 0 ;Borra la bandera TMR0
TMR0 = 227 ;(226) cada 100us a 20mhz y con 1/16 227 (97.2)
pulsos = pulsos + 1 ;Cada 100us incrementa la variable
Refresh = Refresh + 1
Resume
EndIf

If INTCON.1 = 1 Then ;######## PULSO EN RB0 ######## (paso de 0 a 1)
bandera = 0 ;Esto lo puse mas que nada para hacer un retardo de 0.2us lo ke da 99.8us hasta contar el prox pulso, aunke si cuanto ke tarda 0.2us en detectar la señal serian 100us exactos.
TMR0 = 228 ;227 Resetea timer y le sume 2 para corregir el retardo de la int.
;A partir de aca lo ke ponga no afecta al programa porque ya esta contando.
TEMPL=pulsos ;Carga los pulsos contados en la variable TEMPL para despues hacer el calculo
pulsos=0 ;Resetea pulsos del timer
INTCON.1 = 0 ;Borra la bandera RB0 (RBIF)
bandera = 1 ;pongo esto aca para que muestre la velocidad solo despues de calcularla
EndIf
Resume
;****** Fin de Interrupcion ***********
Context Restore
Enable
;############################## REGISTROS ######################################
INITIALIZE:
 
Última edición:
Atrás
Arriba