Prueba a hacerlo de esta manera:
Codigo:
#include <16f88.h>
#fuses XT,NOPROTECT, NOPUT, NOWDT, BROWNOUT, NOMCLR, NOLVP
#use delay(clock=4000000)
#define led_off output_high(PIN_A2)
#define led_on output_low(PIN_A2)
int1 Flag=0; // Flag que cambia cada interrupcion
#int_RTCC // Interrupción por desbordamiento
RTCC_isr() {
++Flag;
if(Flag==1){
led_on;
}
else{
led_off;
}
set_timer0(252);
}
void main(void)
{
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);// TIMER0: Clock Interno
enable_interrupts(INT_RTCC); // Habilito Interrupción RTCC
set_timer0(252);
enable_interrupts(global); // Habilito Interrupciones
do{
}while(true);
}
Imagino que para una frecuencia de 56 Khz el led debe estar la mitad del tiempo
encendido y la otra mitad apagado para obtener una onda cuadrada de 0.018 ms
de periodo (0.009 ms de semiperiodo) Para ello tenemos que fijar la RTCC cada
0.009 ms y que una vez salte encienda el led y a la siguiente lo apague con lo que
obtendremos el tipo y la frecuencia requeridos. Y cogiendo la calculadora vemos
que aproximadamente saltará cada 0.009 ms con un valor de contador de 252
que es lo que fijamos al inicio y cada vez que salte RTCC.
Prueba y me cuentas.
Creo que con un clock de 4MHz va a ser muy difícil obtener esa frecuencia, porque sólo la rutina de la interrupción ya ocupa más de 14 ciclos de instrucción, a los que habrá que añadir el tiempo de desborde puesto que la precarga del timer se está configurando al salir de la interrupción.
He modificado un poco el programa, reduciendo la interrupción a sólo 7 ciclos de instrucción, y poniendo el set_timer al principio.
Codigo:
#include <16f88.h>
#fuses XT,NOPROTECT, NOPUT, NOWDT, BROWNOUT, NOMCLR, NOLVP
#use delay(clock=4000000)
#define led_off output_high(PIN_A2)
#define led_on output_low(PIN_A2)
int1 Flag=0; // Flag que cambia cada interrupcion
#int_RTCC // Interrupción por desbordamiento
RTCC_isr() {
set_timer0(252);
output_toggle(PIN_A2);
}
void main(void)
{
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);// TIMER0: Clock Interno
enable_interrupts(INT_RTCC); // Habilito Interrupción RTCC
set_timer0(252);
enable_interrupts(global); // Habilito Interrupciones
do{
}while(true);
}
De todas formas, lo que nos sacará de dudas, es la prueba de Diego y su envidiado osciloscopio.

He conseguido los puñeteros 56Khz pero a base de frustración y encono ....

De todas formas he aprendido mucho de varios temas y creo interesante
publicar las vicisitudes por las que he pasado ....
1º Que efectivamente, como decía Nocturno, con un cristal de 4 Mhz iba a
ser dificil el poder conseguirlo. Así que me fuí al saco de los Xtales a por
alguno gordo ... y la primera en la frente: solo había por encima de 4 Mhz
uno solo de 6 Mhz ... doble cambio por molinete y me fuí corriendo a mi
tendero electrónico favorito y me traje un puñado de 10, 12 y 20 Mhz
2º Con el Xtal de 20 Mhz en la RRBOARD1 y modificado correspondientemente
el programa para usar esta frecuencia me encuentro con que el 16F628 se queda
tieso como un plátano de mármol. Una y otra vez lo intento y parece como
muerto, como ausente que diría Neruda. Entonces caí en la cuenta ... y corrí
a cambiar el 16F628 por el 16F628A (Recordé aquello de que los dos son iguales
pero el tipo A es más igual)
3º Como no hay dos sin tres, el cabrón tampoco quería funcionar. Una hora de
desesperación después y caí en la cuenta de cambiar el puñetero fuse XT (cristal)
por el mas adecuado fuse HS (Hight Speed) y por fín salió andando ...
4º Continuamos para bingo y el programa tal como lo dejó Nocturno no era capaz
de generar pulsos por debajo de 30 us de periodo. Seteando el TIMER0 con cualquier
valor inferior a 240 el pulso siempre era superior a esos 30 us ....
5º Mirando el fichero C/ASM que genera el CCS vi que hiciese lo que hiciese
siempre incluía un TRIS antes de conmutar el estado del PIN_A2 ... así que
quité el output_toggle() y puse en su lugar las otras instrucciones ASM que
hacían efectivamente la conmutación .... y logré que el pulso bajase a unos
25 us ... y eso fué todo ... Con la gestión de la interrupción que hace CCS
metía unas 20 instrucciones ASM con lo que bajar mas era imposible.
y 6º Quité la interrupción y lo puse a güevo en el main(). Si el TIMER0 es igual
a 0 lo pongo a 234 y conmuto PIN_A2 con dos instrucciones ASM. El resultado
en ASM de esta mezcla Pastor Alemán y Yegua son exactamente 8 instrucciones
ASM que conforman el main() y que os pego mas abajo.
Resultado : Un pulso de 20 us según mi osciloscopio. Cualquier intento de
lograr que baje hasta los 18 us resulta vano, sale encefalograma plano en
el putoscopio y hasta aquí hemos llegado .... Doctores tiene la Iglesia que
sabrán explicar exactamente el porqué de las cosas.
Codigo:
// Wink56Khz.c
#include <16f628a.h>
#fuses HS,NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOMCLR, NOLVP
#use delay(clock=20000000)
void main(void)
{
setup_counters(RTCC_INTERNAL,RTCC_DIV_2); // TIMER0: Clock Interno
disable_interrupts(global); // Deshabilito Interrupciones
output_low(PIN_A2); // Para forzar TRIS inicial
do{
if(get_timer0()==0){
set_timer0(234);
#asm
MOVLW 04 // Wink bit 2 del puerto A
XORWF 05,F
#endasm
}
}while(true);
}
Y el main() es en realidad esto otro:
Codigo:
.................... do{
....................
.................... if(get_timer0()==0){
0023: MOVF 01,W
0024: BTFSS 03.2
0025: GOTO 02A
.................... set_timer0(234);
0026: MOVLW EA
0027: MOVWF 01
.................... #asm
.................... MOVLW 04 // Wink bit 2 del puerto A
0028: MOVLW 04
.................... XORWF 05,F
0029: XORWF 05,F
.................... #endasm
.................... }
....................
.................... }while(true);
....................
.................... }
002A: GOTO 023
¡Ea¡

Championix: Ahí tienes 56Khz clavados en un 16F628 con un Xtal de 20Mhz.
(Medidos en el osciloscopio con un error de +-0.2 uS)
Codigo:
// Wink56Khz.c
#include <16f628a.h>
#fuses HS,NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOMCLR, NOLVP
#use delay(clock=20000000)
void main(void)
{
setup_counters(RTCC_INTERNAL,RTCC_DIV_2); // TIMER0: Clock Interno
disable_interrupts(global); // Deshabilito Interrupciones
output_low(PIN_A2); // Para forzar TRIS inicial
do{
output_toggle(PIN_A2);
delay_us(7);
}while(true);
}
Corto y cierro.