Hola @jipc. Me parece habértelo explicado ya dos veces en post anteriores, más el ejemplo que te puse; tres veces. Sin embargo aún no has comprendido que al TMR0 no hay que cargarle el valor de ajuste. El valor de ajuste hay que sumárselo a su valor actual.
Intentaré explicarlo nuevamente: En el instante que se produce la interrupción el TMR0 habrá desbordado y su contenido será cero. El micro ejecutará algunas acciones: el propi salto a la dirección al vector de interrupción, el respaldo del “contexto” de la situación del programa en el momento de la interrupción, las propias instrucciones de atención a la interrupción, etc. Imagina que en hacer todo esto transcurren unos 20 ciclos de maquina (solo como ejemplo); como el pre-escalador estaba a 1:8, ya habrá entregado dos pulsos al TMR0 y el valor de este ya no cera cero sino dos (y con los siguientes 4 ciclos de máquina, su valor será tres). Espero estés comprendiendo, si en este momento cargas en el TMR0 el valor de ajuste, estarás botando a la basura el tiempo transcurrido desde la última interrupción, lo correcto es actualizar el contenido del TMR0 con el valor de juste calculado MAS su contenido en ese instante.
Fíjate en el ejemplo que te puse en el post #27, estoy usando la instrucción
“TMR0L += 0b00001100”; significa:
"TMR0L = TMR0L + 0b00001100". Tu sin embargo usas
“set_timer0(65036)”; justamente ahí la causa para que no logres 1KHz exacto.
Y bueno, para generar 50KHz, Yo dejaría el pre-escalador en 1:8, como ya mencioné, trabajando el micro a 32MHz se logra una señal con periodo de 1uS (exacto) para alimentar el TMR0. Como el TMR0 hará solo diez cuentas antes de desbordar, lo configuraría a 8 bits y utilizaría 246 como valor de ajuste.
Para quienes recomiendan utilizar ensamblador; estoy de acuerdo. Es importante que la rutina de interrupción sea lo mas veloz posible,
para dejar al micro espacio suficiente para atender otras tareas entre interrupciones.
Sin embargo, la propuesta de
D@rkbytes:
#asm
es_cero:
btfsc PORTC,1
goto es_uno
bsf PORTC,1
es_uno:
btfss PORTC,1
goto es_cero
bcf PORTC,1
#endasm
Estoy seguro que consume más ciclos de máquina que la instrucción
“output_toggle(pin_c1)” puesto que cuando CCS la traduzca a ensamblador, seguro lo hará con
“btg PORTC,1”; instrucción perteneciente al set de instrucciones del 18F4550, que permite cambiar el estado de un pin en un solo ciclo de máquina.
Saludos…