Autor Tema: No me anda programa para medir frecuencia  (Leído 1899 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
No me anda programa para medir frecuencia
« en: 27 de Julio de 2016, 18:41:50 »
Hola como les va a todos, estoy tratando de medir frecuencia de una señal cuadrada en RA2 usando la interrupcion externa, pero no me mide nada si la frecuencia pasa un limite se debe prender la salida RB0 trabajo con pic 12f629 o 12f675
Código: [Seleccionar]
#include <12F629.h>

#FUSES WDT                    // Watch Dog Timer
#FUSES INTRC_IO                 // >>> Oscilador interno, no CLKOUT
#FUSES PUT                      // Power Up Timer
#FUSES NOMCLR                   // Master Clear pin used for I/O
#FUSES BROWNOUT                 // Reset when brownout detected
#FUSES PROTECT                // Code not protected from reading
#FUSES NOCPD                    // No EE protection
#byte PORTA=0x05
#use delay(int=4000000,restart_wdt) // Especifica al compilador que hace uso del OSC interno
int16 Ta,Tb,Tick;
Float F=0, Periodo=0,T;
#int_ext
void int_ext_isr()
{
Ta=get_timer1();
Tick=Tb-Ta;
Tb=Ta;
}
void main()
{
   setup_comparator(NC_NC);   // Todo digital
   set_tris_a(0xF4); 
   setup_wdt(WDT_1152MS);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); //Para poder generar 200ms
   enable_interrupts( INT_EXT_H2L );
   enable_interrupts(GLOBAL);
   output_Low(PIN_A0);
   F=0;
   while(TRUE){
   T=32.0/4000000.0;
   Periodo=Tick*T;
   F=1/T;
   if(F>=100)
   {
   output_high(PIN_A0);
   delay_ms(1000);
   output_Low(PIN_A0);
   Tick=0;
   T=1;
   }
   restart_wdt();
      }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:No me anda programa para medir frecuencia
« Respuesta #1 en: 27 de Julio de 2016, 19:05:32 »
Voy a resumir tu programa en 4 lineas de codigo ( Aunque el while tampoco deberia ir, y serian 3).

Código: C
  1. while(TRUE)
  2.    {
  3.            output_high(PIN_A0);
  4.            delay_ms(31);
  5.            reseteo_de_micro();
  6.    }

Y si, eso es todo tu programa. ¿Por que?

A 4MHz suponiendo que el preescaler de WTD es el maximo 1:128, serian 32ms para que el WDT se dispare. Es decir a 4Mhz son 1us por cuenta, con preescaler 1:128 serian 128us por cada 1 que sume el WDT, en 8 bits es decir contar 256 veces, son 32ms.

Asi que eso se reiniciaria en el delay_ms o tal ves antes. por eso puse el resteo ese.

Despues otros problemas muy basicos. El if esta comparando F con 100. Curiosamente, F es 1/T, y T es un valor fijo que es 32/4000000 , F siempre es 125000 y es mayor a 100 por ende siempre va a entrar al if. Por lo tanto el if no funciona para nada, y es como si no estuviera.

Tick no se usa para nada, por lo tanto es lo mismo que nada. Por eso no lo puse. Es cierto que calculas algo y lo depositas en "Periodo" pero eso no se usa para nada. Por eso tambien lo quite

PD:

Te diste cuenta que la frecuencia es mas facil asi:

Código: C
  1. F = 4000000/32;

O mejor dicho es mas facil asi:

Código: C
  1. F = 125000;
« Última modificación: 27 de Julio de 2016, 19:08:08 por KILLERJC »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:No me anda programa para medir frecuencia
« Respuesta #2 en: 27 de Julio de 2016, 21:00:08 »
Hola como va, el restart_wdt () no resetea el micro sino el watchdog . Ya lo modifique pero sigue sin funcionar, cual sera el error ahora?
Código: [Seleccionar]
#include <12F629.h>

#FUSES WDT                    // Watch Dog Timer
#FUSES INTRC_IO                 // >>> Oscilador interno, no CLKOUT
#FUSES PUT                      // Power Up Timer
#FUSES NOMCLR                   // Master Clear pin used for I/O
#FUSES BROWNOUT                 // Reset when brownout detected
#FUSES PROTECT                // Code not protected from reading
#FUSES NOCPD                    // No EE protection
#byte PORTA=0x05
#use delay(int=4000000,restart_wdt) // Especifica al compilador que hace uso del OSC interno
int16 Ta,Tb,Tick;
Float F=0, Periodo=0,T;
#int_ext
void int_ext_isr()
{
Ta=get_timer1();
Tick=Tb-Ta;
Tb=Ta;
}
void main()
{
   setup_comparator(NC_NC);   // Todo digital
   set_tris_a(0xF4); 
   setup_wdt(WDT_1152MS);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); //Para poder generar 200ms
   enable_interrupts( INT_EXT_H2L );
   enable_interrupts(GLOBAL);
   output_Low(PIN_A0);
   while(TRUE){
   T=32.0/4000000.0;
   Periodo=Tick*T;
   F=1/Periodo;
   if(F>=100)
   {
   output_high(PIN_A0);
   delay_ms(1000);
   output_Low(PIN_A0);
   }
   restart_wdt();
      }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:No me anda programa para medir frecuencia
« Respuesta #3 en: 27 de Julio de 2016, 22:16:01 »
Nadie dijo que el restart_wdt() resetea el micro. Sino que se produce el reset culpa del WDT.

Y parece que no sabes como funciona el WDT, a pesar que intente explicarte el por que se resetea, te sugiero que leas sobre el WDT, asi de esa forma vas a saber en que estas equivocandote. Y vas a entender mi explicacion. Si no entra al if ahora, no vas a ver nada, si entra al if se va a resetear por el WDT.

Ahora ademas de lo anterior tenes otro problema, el cual deberias evitar

Código: C
  1. Periodo=Tick*T;
  2.    F=1/Periodo;

Si Tick = 0, Periodo es igual a 0, intenta dividir 1 / 0

Igual pienso que es mas eficiente hacer:

Código: C
  1. F = 125000.0 / Tick;
« Última modificación: 27 de Julio de 2016, 22:40:02 por KILLERJC »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:No me anda programa para medir frecuencia
« Respuesta #4 en: 28 de Julio de 2016, 09:06:23 »
ya le saque el perrro guardian y el problema no se soluciono, o sea ese no es el problema. la division por 0 es algo accesorio el tema es que no se porque no entra en el if

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:No me anda programa para medir frecuencia
« Respuesta #5 en: 28 de Julio de 2016, 09:38:48 »
Ya lo solucione ,era un error de la formula, gracias a todos.


 

anything