(Quito este trozo para no sobrepasar los límites de un Post que nos impone el Foro :P)Jajaja, ¡se te ha quedado pequeño el foro, Diego!
#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)
////////////////////////////////////////////////////////////////////////////////////
// Defines y Constantes
////////////////////////////////////////////////////////////////////////////////////
#define LED PIN_B5 //E0 Defino el Pin del Led
#define FLASH Output_Toggle(LED) // Defino la funcion Flash de monitor
float const uSxTick = 0.2; // 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
}
FLASH; // Reproduzco la entrada mediante un LEd en E0;
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.
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
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
flagHayTransmitir = 1; // Indico que tengo nuevo valor para transmitir
}
flagHayDatos = 0; // Indico que ya han sido procesados los datos.
}
if (Command != 0x00) // Si he recibido un comando vía Serie ...
{
if (Command == 'T') // Si el comando es 'T' (Transmite) ...
{
if (flagHayTransmitir == 1) // Si hay algo pendiente de transmitir ...
{
printf("Ticks ....... H %4Lu + L %4Lu = %4Lu\r\n", tth, ttl, tt);
printf("uSegundos ... H %3.1f + L %3.1f = %3.1f F = %4.2f Hz\r\n\n", sth, stl, st, f);
flagHayTransmitir = 0; // Indico que ya he transmitido lo pendiente.
}
}
Command = 0x00; // Indico que ya he procesado el comando.
}
} while (TRUE);
}
Para un siguiente post en este mismo hilo voy a preparar esta misma técnica pero contando vueltas completas de Timer1 para no tener que cambiar de preescaler cuando el periodo del pulso a medir sea mayor que el tiempo que tarda el Timer1 en dar una vuelta completa. No es complicado pero me gusta hacer las cosas bien y explicarlas claramente así que lo dejo para el próximo fin de semana que tengo mas tiempo. :mrgreen:Lo espero ancioso!! yeah! :-/
#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)
////////////////////////////////////////////////////////////////////////////////////
// Defines y Constantes
////////////////////////////////////////////////////////////////////////////////////
#define LED PIN_B5 //E0 Defino el Pin del Led
#define FLASH Output_Toggle(LED) // Defino la funcion Flash de monitor
float const uSxTick = 0.4;//0.64;//1.6;//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_ext1
void handle_ext_int()
{
output_low(pin_b5);
++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(1, 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(1, L_TO_H); // Configuro para capturar siguiente flanco de subida
flagToggleFlanco = 0; // Indico que el siguiente flanco será de Subida
}
//FLASH; // Reproduzco la entrada mediante un LEd en E0;
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.
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(1,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_ext1);
enable_interrupts(global);
output_high(PIN_B5);
printf("\r\nMidiendo un pulso : Periodo\r\n");
printf("By Redpic para Foro TODOPIC\r\n\n");
do
{
} while (TRUE);
}
Algo falta en los fusibles? no se puede?..... q esta mal ? :?Hola RePic.
Queria saber si es necesario la variable T1, yaque su valor es tomado del timer 1 justo despues de poner este a 0. Si no lo fuera pues entonces el valor, en ticks de timer1, del ancho del pulso en alto no serai mas que t2 y por ende no habria necesidad del: t2 - t1. Eso si esq no me equivoco y esq t1 puede llegar a tomar un valor diferente a 0, quisiera q me aclares esa duda.
Gracias.
salu2 8)
#INCLUDE <12F683.h>
#FUSES HS
#FUSES INTRC
#FUSES NOWDT
#FUSES PUT
#FUSES MCLR
#FUSES NOPROTECT
#FUSES NOCPD
#USE DELAY(clock = 8 000 000)
#USE RS232(baud = 9600, xmit = PIN_A0, FORCE_SW)
float const us_por_tick = 0.5; //0.2; //Cada 0.5 microsegundos se producira un tick de timer1, dada por la formula: 4 / (FOSC(Mhz)).
int1 hay_pulso_contado = 0;
int8 numero_de_flanco_alto = 0;
int16 periodo_alto_en_ticks_1, periodo_alto_en_ticks_2;
float frecuencia_hz, periodo_en_us;
#INT_EXT
void SQW_OUT()
{
numero_de_flanco_alto++;
if (numero_de_flanco_alto == 1)
{
set_timer1(0);
periodo_alto_en_ticks_1 = get_timer1();
}
if (numero_de_flanco_alto == 2)
{
periodo_alto_en_ticks_2 = get_timer1();
numero_de_flanco_alto = 0;
set_timer1(0);
if (hay_pulso_contado == 0)
{
hay_pulso_contado = 1;
}
}
}
void main()
{
setup_oscillator(OSC_8MHZ);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
delay_ms(300);
ext_int_edge(L_TO_H);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while (TRUE)
{
if (hay_pulso_contado == 1)
{
if (periodo_alto_en_ticks_1 < periodo_alto_en_ticks_2)
{
periodo_en_us = us_por_tick * periodo_alto_en_ticks_2; // Calculo en uS el periodo del pulso.
frecuencia_hz = 1 / (periodo_en_us / 1000000); // Calculo la Frecuencia
printf("uSegundos: %3.1f F = %4.2f Hz\r\n\n", periodo_en_us, frecuencia_hz);
}
hay_pulso_contado = 0;
}
}
}
Solo hago el conteo con los pulsos en alto y aunq aqui tb t1 (con otro nombre) vale 0 solo lo hago, como tu, el tema del timer1 desbordado.#INCLUDE <12F683.h>
#FUSES HS
#FUSES INTRC
#FUSES NOWDT
#FUSES PUT
#FUSES MCLR
#FUSES NOPROTECT
#FUSES NOCPD
#USE DELAY(clock = 8 000 000)
#USE RS232(baud = 9600, xmit = PIN_A0, FORCE_SW)
float const us_por_tick = 0.5; //Cada 0.5 microsegundos se producira un tick de timer1, dada por la formula: 4 / (FOSC(Mhz)).
int1 hay_pulso_contado = 0;
int8 numero_de_flanco_alto = 0;
int16 veces_desbordado, periodo_alto_en_ticks;
float frecuencia_hz, periodo_en_us;
#INT_TIMER1
void desbordamiento_tmr1()
{
if (hay_pulso_contado == 0)
{
veces_desbordado++;
}
}
#INT_EXT
void SQW_OUT()
{
if (hay_pulso_contado == 0)
{
numero_de_flanco_alto++; // Cuento flanco que nos llega
if (numero_de_flanco_alto == 1)
{
veces_desbordado = 0;
set_timer1(0);
}
if (numero_de_flanco_alto == 2)
{
periodo_alto_en_ticks = get_timer1();
numero_de_flanco_alto = 0;
set_timer1(0);
hay_pulso_contado = 1;
}
}
}
void main()
{
setup_oscillator(OSC_8MHZ);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
delay_ms(300);
printf("\fProbador de DS1307 y Cristal 32.768Khz");
delay_ms(300);
ext_int_edge(L_TO_H);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while (TRUE)
{
if (hay_pulso_contado == 1)
{
periodo_en_us = us_por_tick * ((65536 * veces_desbordado) + periodo_alto_en_ticks);
frecuencia_hz = 1 / (periodo_en_us / 1000000); // Calculo la Frecuencia
printf("\r\n\nuSegundos: %3.1f F: %4.2f Hz IntT1: %Lu", periodo_en_us, frecuencia_hz, veces_desbordado);
hay_pulso_contado = 0;
}
}
}