Hola a todos, muy buenas.
Haber, tengo un codigo en CCS q lee por Timer1 (RB0) el periodo de un pulso; codigo del amigo RedPic (justo
Aqui) q me ha sido muy util.
Lo q sucede es que solo podia leer un pulso menor de 13,1072 us, despues de esto se desbordaba el Timer1. Entonces cambie el valor de:
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
por:
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
Y como RedPic me dijo... tb cambie la constante flotante uSxTick a su valor por el numero q puse en la configuracion del timer1 (2, T1_DIV_BY_2).
Y si, pude leer un pulso mayor de 13,1072 us.
Mi problema es que al leer tal periodo de pulso mayor a 13,1072 us, por ejemplo: 16,... us, ya asi desde q se inicia el PIC, hay veces q lee 14,... us y hasta 23,... us y luego se "retorna" a su valor en us normal. Y bueno ese es un problema muy grande, almenos para mi.
He probado con T1_DIV_BY_4 y ...8 y pasa lo mismo en cualquier periodo mayor de 13,1072 us (al parecer). Nose que hago mal o q no estoy haciendo pero porsiacaso quien pueda ayudarme aqui dejo el codigo que, de modificado, solo tiene: el #include del procesador, una directiva irreconosible en el main para el 18f2550 (q es el q uso) y el cambio del timer1 para poder leer mas de 13,1072 us de periodo, y oon este la constante flotante uSxTick.
#include <18f2550.h>
#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
float const uSxTick = 0.4 // Microsegundos por Tick de TMR1 a 20 Mhz
// Variables en RAM/////
char cRec = 0x00; // Último carácter recibido vía serie
char Command = 0x00; // Comando a procesar
int8 numFlancoQueLlega = 0; // Número de Flanco que llega
int1 flagToggleFlanco = 0; // Flag para cambiar de flanco
int16 t1 = 0x00, t2 = 0x00, t3 = 0x00; // Variables para guardar estados de ...
int16 tth = 0x00, ttl = 0x00, tt = 0x00; // Timers y pulsos.
float sth = 0.0, stl = 0.0, st = 0.0, f = 0.00; // Para hacer las restas oportunas en uS
int1 flagHayDatos = 0; // Flag para indicar que ya hay datos de ..
// dos flancos (de subida y bajada)
int1 flagHayTransmitir = 0; // Flag para indicar que hay datos para ...
// Transmitir al PC.
// Interrupción por Recepción Serie RS232///
#int_rda
void handle_rda_int()
{
if (kbhit()) // Si hay algo pdte de recibir ...
{
cRec = getc(); // lo recibo sobre cRec ...
if (cRec != 0x00) // Si es distinto de \0 ...
{
Command = ToUpper(cRec); // cargo cRec sobre Command para procesarlo
} // pasándolo a Mayúsculas para no confundir.
}
}
// Interrupción por Externa por Cambio de Flanco en RB0///
#int_ext
void handle_ext_int()
{
++numFlancoQueLlega; // Cuento flanco que nos llega
if (flagToggleFlanco == 0) // He recibido Flanco de Subida
{
if (numFlancoQueLlega == 1)
{
set_timer1(0); // Reinicio TMR1
t1=get_timer1(); // Guardo en t1 el valor de TMR1 al primer Flanco de Subida
}
if(numFlancoQueLlega == 3)
{
t3 = get_timer1(); // Guardo en t1 el valor de TMR1 al primer Flanco de Subida
if (flagHayDatos == 0) // Si los datos anteriores han sido procesados ...
{
flagHayDatos = 1; // Indico que ya hay nuevos datos de flancos para calcular
}
}
ext_int_edge(0, H_TO_L); // Configuro para capturar siguiente flanco de Bajada
flagToggleFlanco = 1; // Indico que el siguiente flanco será de Bajada
}
else // He recibido Flanco de Bajada
{
t2=get_timer1(); // Guardo en t2 el valor de TMR1 al Flanco de Bajada
ext_int_edge(0, L_TO_H); // Configuro para capturar siguiente flanco de subida
flagToggleFlanco = 0; // Indico que el siguiente flanco será de Subida
}
if (numFlancoQueLlega == 3) //Reinicio el Flag q llega para poder leer otro pulso.
{
numFlancoQueLlega=0;
}
}
// Inicio Programa.//
void main()
{
//INICIALIZACIONES GENERALES//
delay_ms(333); // Espero a que todo se estabilice e ...
disable_interrupts(global); // Inicializo el Micro y ...
disable_interrupts(int_timer1); // deshabilitando todo lo no necesario ...
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
//setup_psp(PSP_DISABLED); //Para 18F4550 No para 18F250.
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); /*****************************************/
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
delay_ms(333);
//INICIALIZACIONES PERTINENTES A LA APLICACION//
set_tris_c(0b10000000); // Habilito como entrada RC7 para canal RS232
ext_int_edge(0,L_TO_H); // Configuro captura de 1er flanco de subida
flagToggleFlanco = 0; // inicializo el Flag para cambiar de flanco
enable_interrupts(int_rda); // Habilito las interrupciones necesarias
enable_interrupts(int_ext);
enable_interrupts(global);
printf("\r\nMidiendo un pulso : Periodo\r\n");
printf("By Redpic para Foro TODOPIC\r\n\n");
do
{
if (flagHayDatos == 1) // Detecto que ya hay datos de flancos ...
{
if ((t3 > t2) && (t2 > t1)) // Compruebo que estoy en la misma vuelta de TMR1
{
tth = t2 - t1; // Calculo en Tick's de TMR1 el tiempo en Alto
ttl = t3 - t2; // Calculo en Tick's de TMR1 el tiempo en Bajo
tt = tth + ttl; // Calculo en Tick's de TMR1 el Periodo del Pulso
sth = uSxTick * tth; // Calculo en uS el tiempo.
stl = uSxTick * ttl; // Calculo en uS el tiempo.
st = uSxTick * tt; // Calculo en uS el tiempo.
f = 1 / (st / 1000000); // Calculo la Frecuencia
printf("uSegundos ... H %3.1f + L %3.1f = %3.1f F = %4.2f Hz\r\n\n", sth, stl, st, f);
}
flagHayDatos = 0; // Indico que ya han sido procesados los datos.
}
}
} while (TRUE);
}
Espero puedan ayudarme en lo q se pueda, gracias de antemano.
salu2