Autor Tema: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)  (Leído 6075 veces)

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

Desconectado julietgolf

  • PIC10
  • *
  • Mensajes: 15
    • Mi Página (aún está en construcción...)
Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« en: 11 de Abril de 2008, 14:30:30 »
Hola comunidad amiga de todopic, soy un asiduo lector (un poco pasivo) del foro, pero esta vez, me veo en la necesidad de solicitar cordialmente su ayuda...
Estoy haciendo un medidor de frecuencia para la salida de 2 anemometros y quiero medirlos a ambos en los puertos CCP de un 16F877A, como veran en el codigo, solicito los datos de cada uno a traves del paso de un caracter por RS232 desde un soft q estoy haciendo en VB. Para aclarales un poco, lo unico que hago en el PIC es contar los ticks (info sacada de aqui: LINK ) que existen entre un raise edge y otro (período) y eso lo envío por RS232 al soft donde es procesada la info: saco la f a traves de ((ticks*0.2)/1000000)-1.
Para la simulac que tb adjunto, utilizo el proteus con otro PIC q emula mi soft en VB.
El motivo de mi post es que uno de los CCP (el CCP1) no está contando correctamente, en ningun momento. Hace 15 dias que vengo buscando la vuelta a ello, ya he reescrito el codigo 2 o 3 veces y no he logrado hacer funcionar de la forma que yo quiero... DONDE ESTOY HACIENDO MAL LAS COSAS???  :( :? Acaso tambien puede haber un problema con la simulación, porq la verdad q aun no lo he probado en el circuito armado (si, ya lo se, muy mal hecho, pero no tuve oportunidad aun...)
Hay alguna caracteristica de los puertos CCP que no estoy teniendo en cuenta?

Agradecería enormemente a quien pueda darme una mano...

Aquí va el codigo en CSS del PIC:
Código: CSS
  1. #include <16f877a.h>
  2. #fuses HS, NOWDT, PUT, NOPROTECT, NOCPD
  3. #use delay(clock = 20 000 000)
  4. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  5.  
  6. #define LED PIN_E0                              // Defino el Pin del Led
  7. #define POWER_ON Output_Toggle(LED)            // Defino la funcion Flash de monitor
  8.  
  9. int1 hay_pulso_contado = 0;
  10. int8 numero_de_flanco_subida = 0;
  11. int16 veces_desbordado=0;
  12. int16 periodo_alto_en_ticks=0;
  13. int32 cantidad_de_ticks=0;
  14. char cRec;
  15.  
  16. ////////////////////////////////////////////////////////////////////////////////////
  17. // Interrupcion por desborde de TMR1
  18. ////////////////////////////////////////////////////////////////////////////////////
  19.  
  20. #int_timer1
  21. void desbordamiento_tmr1()          //al desbordar el TMR1 cuento una
  22. {                                   // vuelta completa del mismo
  23.    if (hay_pulso_contado == 0)
  24.    {
  25.       veces_desbordado++;           //sumo 1 al desborde
  26.    }
  27. }
  28.  
  29.  
  30. ////////////////////////////////////////////////////////////////////////////////////
  31. // Interrupcion por Recepcion de flanco de SUBIDA en CCP1
  32. ////////////////////////////////////////////////////////////////////////////////////
  33.  
  34. #int_ccp1
  35. void llego_flanco_ccp1()
  36. {
  37.    if (hay_pulso_contado == 0)               //comienzo a contar porq no hay datos para enviar
  38.    {
  39.       numero_de_flanco_subida++;             // Cuento flanco que nos llega
  40.       if (numero_de_flanco_subida == 1)      //es el primer flanco de subida dentro del conteo
  41.       {
  42.          veces_desbordado = 0;               //reinicio contador de desborde
  43.          set_timer1(0);                      //reinicio el TMR1
  44.       }
  45.       if (numero_de_flanco_subida == 2)      //ahora llego el segundo flanco de subida
  46.       {
  47.          periodo_alto_en_ticks = CCP_1;      //guardo el valor de ccp_1    
  48.          cantidad_de_ticks = (65536 * veces_desbordado) + periodo_alto_en_ticks;
  49.          printf("@%Lu#",cantidad_de_ticks);
  50.          cRec=0x00;
  51.          disable_interrupts(INT_CCP1);
  52.          disable_interrupts(INT_TIMER1);
  53.       }
  54.    }
  55. }
  56.  
  57. ////////////////////////////////////////////////////////////////////////////////////
  58. // Interrupcion por Recepcion de flanco de SUBIDA en CCP2
  59. ////////////////////////////////////////////////////////////////////////////////////
  60.  
  61. #int_ccp2
  62. void llego_flanco_ccp2()
  63. {
  64.    if (hay_pulso_contado == 0)               //comienzo a contar porq no hay datos para enviar
  65.    {
  66.       numero_de_flanco_subida++;             // Cuento flanco que nos llega
  67.       if (numero_de_flanco_subida == 1)      //es el primer flanco de subida dentro del conteo
  68.       {
  69.          veces_desbordado = 0;               //reinicio contador de desborde
  70.          set_timer1(0);                      //reinicio el TMR1
  71.       }
  72.       if (numero_de_flanco_subida == 2)      //ahora llego el segundo flanco de subida
  73.       {
  74.          disable_interrupts(INT_CCP2);
  75.          disable_interrupts(INT_TIMER1);
  76.          periodo_alto_en_ticks = CCP_2;      //guardo el valor de ccp_2    
  77.          cantidad_de_ticks = (65536 * veces_desbordado) + periodo_alto_en_ticks;
  78.          printf("$%Lu#",cantidad_de_ticks);
  79.          cRec=0x00;
  80.       }
  81.    }
  82. }
  83.  
  84. void main()
  85. {
  86.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  87.    //set_tris_c(0x46);
  88.    delay_ms(100);                  
  89.    POWER_ON;                        //para ver q funciona el PIC
  90.    printf("@@");                    //avisa q es la primer medicion q hara y es del anem1 o sea el soft debe pasar @
  91.    //delay_ms(300);
  92.    setup_ccp1(CCP_CAPTURE_RE);      //pongo para q espere flanco de SUBIDA el CCP1
  93.    //ext_int_edge(0,L_TO_H);
  94.    setup_ccp2(CCP_CAPTURE_RE);      //pongo para q espere flanco de SUBIDA el CCP2
  95.    enable_interrupts(GLOBAL);
  96.    while (true)//(cRec!='$'||cRec!='@')
  97.    {
  98.       cRec=getc();
  99.       switch(cRec)
  100.       {
  101.          case '@':                    //pide los datos del anem 1
  102.             hay_pulso_contado = 0;
  103.             numero_de_flanco_subida = 0;
  104.             veces_desbordado=0;
  105.             periodo_alto_en_ticks=0;
  106.             cantidad_de_ticks=0;
  107.             enable_interrupts(INT_TIMER1);
  108.             enable_interrupts(INT_CCP1);
  109.             break;
  110.          case '$':                    //pide los datos del anem 2
  111.             hay_pulso_contado = 0;
  112.             numero_de_flanco_subida = 0;
  113.             veces_desbordado=0;
  114.             periodo_alto_en_ticks=0;
  115.             cantidad_de_ticks=0;
  116.             enable_interrupts(INT_TIMER1);
  117.             enable_interrupts(INT_CCP2);
  118.             break;
  119.          default: break;
  120.       }
  121.    }
  122. }


Y aquí les paso el código del otro PIC q utilizo en la simulación...
Código: CSS
  1. #include <16f877a.h>
  2. #fuses HS, NOWDT, PUT, NOPROTECT, NOCPD
  3. #use delay(clock = 20 000 000)
  4. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  5.  
  6. #define LED PIN_E0                              // Defino el Pin del Led
  7. #define POWER_ON Output_Toggle(LED)            // Defino la funcion Flash de monitor
  8.  
  9. char cRec;
  10. int1 flag=0;
  11.  
  12.  
  13. ////////////////////////////////////////////////////////////////////////////////////
  14. // Interrupcion por Rx de Confirmacion por RS232
  15. ////////////////////////////////////////////////////////////////////////////////////
  16.  
  17. #int_rda
  18. void handle_rda_int(){
  19.   if(kbhit()){                             // Si hay algo pendiente de recibir ...
  20.      cRec=getc();                          // lo recibo sobre cRec ...
  21.   }
  22. }
  23.  
  24. void main()
  25. {
  26.    delay_ms(150);                    //porq si
  27.    putc('@');
  28.    //POWER_ON;                        //para ver q funciona el PIC
  29.    //enable_interrupts(INT_RDA);
  30.    enable_interrupts(GLOBAL);
  31.    while (true)
  32.    {
  33.       cRec=getc();
  34.       if(cRec=='#')
  35.       {
  36.          if(flag==0)
  37.          {
  38.             putc('$');
  39.             flag=1;
  40.          }
  41.          else
  42.          {
  43.             putc('@');
  44.             flag=0;
  45.          }
  46.       }
  47.    }
  48. }

De todas formas, además adjunto un zip con los codigos y archivo de Proteus...

Señores, desde ya gracias y espero que alguien puede darme una mano...

Saludos desde Cordoba, Argentina!
« Última modificación: 17 de Abril de 2008, 01:26:49 por julietgolf »
...::: Un feliz usuario de Debian Linux (e17) y amante de los PIC :::...

Desconectado guille1984

  • PIC10
  • *
  • Mensajes: 8
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #1 en: 29 de Abril de 2008, 18:54:31 »
Me sorprende que nadie haya respondido todavia!. Esperaba que alguno de los grandes salgan en tu ayuda....

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #2 en: 30 de Abril de 2008, 19:51:57 »
Hola.

Mira, una de las cosas que yo uso mucho cuando uso interrupciones es: " sal de la interrupcion lo mas rapido que puedas  :mrgreen: ". Asi que yo no utilizaria el printf dentro de la interrupcion.

No entiendo bien como funcionan esos anemometros, si es con la frecuencia o con el ciclo util a una frecuencia determinada, porque si es a frecuencia no necesitarias deshabilitar las interrupciones en uno u otro caso, si no solo procesarlas con flags diferentes ..... pero como te digo no se como funcionan esos bichos!!  :-).

Al procesarlas con flags independientes solo necesitarias el flag de interrupcion con la RDA para que se envie el dato correspondiente.

Si pudieras ser un poco mas especifico, genial ... a ver si nos desenredamos o nos acabamos de perder!!!  :-/


Chao
El papel lo aguanta todo

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #3 en: 03 de Mayo de 2008, 15:29:44 »
...
Mira, una de las cosas que yo uso mucho cuando uso interrupciones es: " sal de la interrupcion lo mas rapido que puedas  :mrgreen: ". Asi que yo no utilizaria el printf dentro de la interrupcion.

...

ese precisamente es la disyuntiva que tengo, siempre leo que es recomendable salir rapidamente de una interrupción, el cuál es favorable en muchos casos. PERO hay otros casos donde da lo mismo ejecutar el proceso concerniente a la interrupción sea dentro o fuera de la misma.

me explico, supongamos que apliquemos el método de salir rapidamente, la única forma de procesar la interrupción es con una bandera en el bucle principal, pero ¿que pasa si el bucle es muuy largo? tardaría mucho en preguntar por la bandera, caeriamos en lo mismo que preguntar por el Flag que activa el módulo, de manera repetitiva.

yo creo que todo se basa en la PRIORIDAD que tenga el proceso adjunto a la interrupción, está en nosotros decidir que tan importante es ejecutar con rapidéz, Qué o cuál proceso.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #4 en: 03 de Mayo de 2008, 23:28:47 »
Totalmente de acuerdo PalitroqueZ  :mrgreen: Fue justamente en este foro en el que aprendi esa premisa ......

Normalmente en los programas que he hecho, necesito el flag unicamente para que se ejecute una accion en al programa principal
El papel lo aguanta todo

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #5 en: 04 de Mayo de 2008, 02:13:31 »
Sí, yo también estoy de acuerdo con Palitroquez, en ocasiones es obligatorio salir rápidamente de la interrupción pero en otros casos dá igual.

Desconectado electronando

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 427
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #6 en: 04 de Mayo de 2008, 02:34:50 »
en el codigo anterior esta pecando de eso mismo julietgolf es uno de los casos en q no da lo mismo , pues estas mandando datos printf en medio de la interrupcion cosa q puedes hacer en el mismo main ; te recomiendo qu uses un flag de aviso por ejemplo si ocurrio el evento en la interrupcion pones flag_evento=1  y en el main hacer una rutina q siempre este leyendo este flag, al igual si tienes otra interrupcion flag_evento2=1 , y una vez ejecutado en el main lo borras para poder reutilizar en caso se realice otra interrupcion . :-/

Desconectado julietgolf

  • PIC10
  • *
  • Mensajes: 15
    • Mi Página (aún está en construcción...)
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #7 en: 04 de Mayo de 2008, 23:35:47 »
gracias sres, antes de leer aquí ya me lo había recomendado un ing. amigo en mi facultad al tema de salir rapido (en este caso) de la INT_CCPx, le hice caso y comenzo a andar... solo q me he complicado un poco (es la primera vez q trabajo con estas caracteristicas del PIC) y para poder realizar la medición completa de ambos anemometros tuve q utilizar 2 PIC y comunicarlos a traves de una AND al MAX232... Se q no es muy ortodoxo lo que he hecho, pero por ahora funciona... y la verdad q necesitaba q funcione con urgencia...
Respondiendo a MLO__, estos anem. responden linealmente a la velocidad del viento... y para calcular la velocidad en mi software hehco en VB solo debo realizar "SLOPE*frec+OFFSET", es bastante simple, casi todos los anemometros funcionana de esta forma...
ya andaré e nuevo por aqui con alguna inquietud y quizas con alguna respuesta a otro post, porq no?  :)
Saludos desde Cordoba, ARG!
...::: Un feliz usuario de Debian Linux (e17) y amante de los PIC :::...

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #8 en: 05 de Mayo de 2008, 00:07:00 »
Oye julietgof .... podrias colocar la referencia de esos anemometros???  :mrgreen:
El papel lo aguanta todo

Desconectado julietgolf

  • PIC10
  • *
  • Mensajes: 15
    • Mi Página (aún está en construcción...)
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #9 en: 06 de Mayo de 2008, 01:25:59 »
MLO, con gusto, pero no se a que te refieres con que ponga la referencia... explicate y con gusto subiré lo que tenga sobre el tema...
Lo unico que se me ocurre como referencia es esto: http://www.nrgsystems.com/store/files/1900_specs.pdf  :-) Este es el anemometro standard que estoy utilizando en mi proyecto...
Si quieres saber alguna otra cosa, solo pregunta...
Por cierto, cuando refine bien mi codigo de CCPs, lo subiré aquí...
saludos!
...::: Un feliz usuario de Debian Linux (e17) y amante de los PIC :::...

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #10 en: 06 de Mayo de 2008, 11:55:01 »
 :mrgreen: :mrgreen: :mrgreen: :mrgreen:

Era justamente eso  :lol:

Gracias y muchos exitos en tu proyecto.
El papel lo aguanta todo

Desconectado julietgolf

  • PIC10
  • *
  • Mensajes: 15
    • Mi Página (aún está en construcción...)
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #11 en: 12 de Mayo de 2008, 23:02:58 »
Hola amigos... como he dicho con anterioridad, aquí publico el código que he realizado para poder utilizar 2 CCPs y la simulacion en Proteus. Como antes había mencionado, no he podido hacer funcionar ambos CCPs en un solo PIC pero es materia pendiente, ni bien lo logre, aquí estará el código...
Como verán, he utilizado dos PICs 16F877A que son demasiado para esto, pero ya los tenía, así q alli fueron... Tranquilamente se puede lograr lo mismo con cualquier otro PIC mas pequeño q posea CCP...

PIC 1 o Master:
Código: CSS
  1. #include <16F877A.h>
  2.  
  3. #FUSES NOWDT                    //No Watch Dog Timer
  4. #FUSES XT                       //Crystal osc <= 4mhz
  5. #FUSES NOPUT                    //No Power Up Timer
  6. #FUSES NOPROTECT                //Code not protected from reading
  7. #FUSES NODEBUG                  //No Debug mode for ICD
  8. #FUSES NOBROWNOUT               //No brownout reset
  9. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  10. #FUSES NOCPD                    //No EE protection
  11.  
  12. #use delay(clock=4000000)
  13. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  14.  
  15. int8 numero_de_flanco_subida_ccp1=0;
  16. int16 desbordes_tmr0=0;
  17. int16 veces_desbordado_ccp1=0;
  18. int16 periodo_alto_en_ticks_ccp1=0;
  19. int32 cantidad_de_ticks_ccp1=0;
  20. int32 ultima_cantidad_de_ticks_ccp1=0;
  21. int16 conteo_control=0;
  22.  
  23. ////////////////////////////////////////////////////////////////////////////////////
  24. // Interrupción por desborde de TMR0
  25. ////////////////////////////////////////////////////////////////////////////////////
  26.  
  27. #int_timer0
  28. void desbordamiento_tmr0()
  29. {
  30.    desbordes_tmr0++;
  31. }
  32.  
  33. ////////////////////////////////////////////////////////////////////////////////////
  34. // Interrupción por desborde de TMR1
  35. ////////////////////////////////////////////////////////////////////////////////////
  36.  
  37. #int_timer1
  38. void desbordamiento_tmr1()
  39. {          
  40.    if (conteo_control>100)
  41.    {
  42.       cantidad_de_ticks_ccp1=0;
  43.    }
  44.    else
  45.    {
  46.       veces_desbordado_ccp1++;           //sumo 1 al desborde
  47.       conteo_control++;
  48.    }
  49. }
  50.  
  51. ////////////////////////////////////////////////////////////////////////////////////
  52. // Interrupción por Recepción de flanco de SUBIDA en CCP1
  53. ////////////////////////////////////////////////////////////////////////////////////
  54.  
  55. #int_ccp1
  56. void llego_flanco_ccp1()
  57. {
  58.    numero_de_flanco_subida_ccp1++;             // Cuento flanco que nos llega
  59.    if (numero_de_flanco_subida_ccp1 == 1)      //es el primer flanco de subida dentro del conteo
  60.    {
  61.       veces_desbordado_ccp1 = 0;               //reinicio contador de desborde
  62.       set_timer1(0);                      //reinicio el TMR1
  63.    }
  64.    if (numero_de_flanco_subida_ccp1 == 2)      //ahora llego el segundo flanco de subida
  65.    {
  66.       periodo_alto_en_ticks_ccp1 = CCP_1;      //guardo el valor de ccp_1  
  67.       cantidad_de_ticks_ccp1 = (65536 * veces_desbordado_ccp1) + periodo_alto_en_ticks_ccp1;
  68.       ultima_cantidad_de_ticks_ccp1=cantidad_de_ticks_ccp1;
  69.       if (cantidad_de_ticks_ccp1<8265) //   1/(8265/1000000)=121Hz -->MAX F QUE MEDIREMOS
  70.       {                                //  esto es para evitar conteos por ruidos....
  71.          cantidad_de_ticks_ccp1=ultima_cantidad_de_ticks_ccp1; //para evitar un poco el posible ruido
  72.       }                                                        //si midio cualquiera, dejo lo q estaba medido q es bueno...
  73.       numero_de_flanco_subida_ccp1=0;
  74.       veces_desbordado_ccp1=0;
  75.       periodo_alto_en_ticks_ccp1=0;
  76.       conteo_control=0;
  77.    }
  78. }
  79.  
  80. void main()
  81. {
  82.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  83.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  84.    set_tris_b(0b01111111);
  85.    set_tris_c(0b10011111); //5out,4in
  86.    output_high(PIN_B7);
  87.    delay_ms(100);
  88.    output_low(PIN_B7);
  89.    delay_ms(100);
  90.    output_high(PIN_B7);
  91.    delay_ms(100);
  92.    output_low(PIN_B7);
  93.    setup_ccp1(CCP_CAPTURE_RE);      //pongo para q espere flanco de SUBIDA el CCP1
  94.    set_timer1(0);
  95.    enable_interrupts(INT_CCP1);     //habilito todas las interrupciones necesarias
  96.    enable_interrupts(INT_TIMER1);
  97.    enable_interrupts(INT_TIMER0);
  98.    enable_interrupts(GLOBAL);
  99.    while (true)
  100.    {
  101.       if(desbordes_tmr0>5860) //calculado para q pase 1500mseg 5860*0.256ms=1500
  102.       {
  103.          output_toggle(PIN_B7);
  104.          printf("@%Lu#",cantidad_de_ticks_ccp1);
  105.          delay_ms(5);
  106.          output_high(PIN_C5);
  107.          delay_ms(10); //espero q envíe el otro PIC
  108.          output_low(PIN_C5);
  109.          desbordes_tmr0=0;
  110.       }
  111.    }
  112. }

PIC 2 o Slave:
Código: CSS
  1. #include <16F877A.h>
  2.  
  3. #FUSES NOWDT                    //No Watch Dog Timer
  4. #FUSES XT                       //Crystal osc <= 4mhz
  5. #FUSES NOPUT                    //No Power Up Timer
  6. #FUSES NOPROTECT                //Code not protected from reading
  7. #FUSES NODEBUG                  //No Debug mode for ICD
  8. #FUSES NOBROWNOUT               //No brownout reset
  9. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  10. #FUSES NOCPD                    //No EE protection
  11. #FUSES WRT_50%                  //Lower half of Program Memory is Write Protected
  12.  
  13. #use delay(clock=4000000)
  14. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  15.  
  16. int8 numero_de_flanco_subida_ccp2=0;
  17. int16 veces_desbordado_ccp2=0;
  18. int16 periodo_alto_en_ticks_ccp2=0;
  19. int32 cantidad_de_ticks_ccp2=0;
  20. int16 conteo_control=0;
  21. int32 ultima_cantidad_de_ticks_ccp2=0;
  22.  
  23. ////////////////////////////////////////////////////////////////////////////////////
  24. // Interrupción por desborde de TMR1
  25. ////////////////////////////////////////////////////////////////////////////////////
  26.  
  27. #int_timer1
  28. void desbordamiento_tmr1()          //al desbordar el TMR1 cuento una
  29. {          
  30.    if (conteo_control>100)
  31.    {
  32.          cantidad_de_ticks_ccp2=0;
  33.    }
  34.    else
  35.    {
  36.       veces_desbordado_ccp2++;           //sumo 1 al desborde
  37.       conteo_control++;
  38.    }
  39. }
  40.  
  41. ////////////////////////////////////////////////////////////////////////////////////
  42. // Interrupción por Recepción de flanco de SUBIDA en ccp2
  43. ////////////////////////////////////////////////////////////////////////////////////
  44.  
  45. #int_ccp2
  46. void llego_flanco_ccp2()
  47. {
  48.    numero_de_flanco_subida_ccp2++;             // Cuento flanco que nos llega
  49.    if (numero_de_flanco_subida_ccp2 == 1)      //es el primer flanco de subida dentro del conteo
  50.    {
  51.       veces_desbordado_ccp2 = 0;               //reinicio contador de desborde
  52.       set_timer1(0);                      //reinicio el TMR1
  53.    }
  54.    if (numero_de_flanco_subida_ccp2 == 2)      //ahora llego el segundo flanco de subida
  55.    {
  56.       periodo_alto_en_ticks_ccp2 = CCP_2;      //guardo el valor de ccp_1
  57.       cantidad_de_ticks_ccp2 = (65536 * veces_desbordado_ccp2) + periodo_alto_en_ticks_ccp2;
  58.             if (cantidad_de_ticks_ccp2<8265) //   1/(8265/1000000)=121Hz -->MAX F QUE MEDIREMOS
  59.       {                                //  esto es para evitar conteos por ruidos....
  60.          cantidad_de_ticks_ccp2=ultima_cantidad_de_ticks_ccp2; //para evitar un poco el posible ruido
  61.       }            
  62.       numero_de_flanco_subida_ccp2=0;
  63.       veces_desbordado_ccp2=0;
  64.       periodo_alto_en_ticks_ccp2=0;
  65.       conteo_control=0;
  66.    }
  67. }
  68.  
  69. void main()
  70. {
  71.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  72.    set_tris_b(0b01111111);
  73.    set_tris_c(0b10111111);
  74.    output_high(PIN_B7);
  75.    delay_ms(100);
  76.    output_low(PIN_B7);
  77.    delay_ms(100);
  78.    output_high(PIN_B7);
  79.    delay_ms(100);
  80.    output_low(PIN_B7);
  81.    setup_ccp2(CCP_CAPTURE_RE);      //pongo para q espere flanco de SUBIDA el CCP1
  82.    set_timer1(0);
  83.    enable_interrupts(INT_CCP2);     //habilito todas las interrupciones necesarias
  84.    enable_interrupts(INT_TIMER1);
  85.    enable_interrupts(GLOBAL);
  86.    while (true)
  87.    {
  88.       if (input_state(PIN_C4)==1)
  89.       {
  90.          
  91.          output_toggle(PIN_B7);
  92.          printf("$%Lu#",cantidad_de_ticks_ccp2);
  93.       }
  94.    }
  95. }

También, de yapa, les dejo 2 videos donde se confirma el buen funcionamiento del circuito...  :) :) :)
MLO, los anemometros que aquí salen son los que te facilite las referencias...




Aquí hay otro video q subio uno de mis compañeros en el proyecto, podrán ver cuan linda sale la señal senoidal del anemómetro a través del osciloscopio que es enfocado en un momento...


Saludos desde CBA, ARG!
« Última modificación: 25 de Mayo de 2008, 23:38:44 por julietgolf »
...::: Un feliz usuario de Debian Linux (e17) y amante de los PIC :::...

Desconectado julietgolf

  • PIC10
  • *
  • Mensajes: 15
    • Mi Página (aún está en construcción...)
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #12 en: 25 de Mayo de 2008, 23:07:54 »
Sres, había quedado en que iba a publicar el código una vez q lo haya finalizado. Dicho código sirve para utilizar ambos CCP de un 16F877A para medir baja frecuencia, para el uso q le daré yo, solo hasta 120Hz...
No es gran cosa, pero funciona (en simulacion con proteus, aun no lo he armado al circuito) y espero q a alguien le sea util...

He aquí el código, de todas formas, subo un .zip con codigo y simulacion...

Código: CSS
  1. #include <16F877A.h>
  2.  
  3. #FUSES NOWDT                    //No Watch Dog Timer
  4. #FUSES HS                       //OSC MAYOR A 4MHz
  5. #FUSES NOPUT                    //No Power Up Timer
  6. #FUSES NOPROTECT                //Code not protected from reading
  7. #FUSES NODEBUG                  //No Debug mode for ICD
  8. #FUSES NOBROWNOUT               //No brownout reset
  9. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  10. #FUSES NOCPD                    //No EE protection
  11.  
  12. #use delay(clock=20000000)
  13. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  14.  
  15. int8 numero_de_flanco_subida_ccp1=0;
  16. int8 numero_de_flanco_subida_ccp2=0;
  17. int16 desbordes_tmr0=0;
  18. int16 veces_desbordado_ccp1=0;
  19. int16 veces_desbordado_ccp2=0;
  20. int16 periodo_alto_en_ticks_ccp1=0;
  21. int16 periodo_alto_en_ticks_ccp2=0;
  22. int32 cantidad_de_ticks_ccp1=0;
  23. int32 cantidad_de_ticks_ccp2=0;
  24. int32 ultima_cantidad_de_ticks_ccp1=0;
  25. int32 ultima_cantidad_de_ticks_ccp2=0;
  26. int16 conteo_control_ccp1=0;
  27. int16 conteo_control_ccp2=0;
  28.  
  29. ////////////////////////////////////////////////////////////////////////////////////
  30. // Interrupcion por desborde de TMR0
  31. ////////////////////////////////////////////////////////////////////////////////////
  32.  
  33. #int_timer0
  34. void desbordamiento_tmr0()
  35. {
  36.    desbordes_tmr0++;
  37. }
  38.  
  39. ////////////////////////////////////////////////////////////////////////////////////
  40. // Interrupcion por desborde de TMR1
  41. ////////////////////////////////////////////////////////////////////////////////////
  42.  
  43. #int_timer1
  44. void desbordamiento_tmr1()
  45. {
  46.    veces_desbordado_ccp1++;           //sumo 1 al desborde
  47.    veces_desbordado_ccp2++;
  48.    conteo_control_ccp1++;
  49.    conteo_control_ccp2++;
  50.    if (conteo_control_ccp1>151) //10000000=65536*desb+periodo_alto --> desb=151 --> me da f de 0,5Hz Minima q se mide
  51.    {
  52.       cantidad_de_ticks_ccp1=0;
  53.    }
  54.    if (conteo_control_ccp2>151)
  55.    {
  56.       cantidad_de_ticks_ccp2=0;
  57.    }
  58. }
  59.  
  60. ////////////////////////////////////////////////////////////////////////////////////
  61. // Interrupcion por Recepcion de flanco de SUBIDA en CCP1
  62. ////////////////////////////////////////////////////////////////////////////////////
  63.  
  64. #int_ccp1
  65. void llego_flanco_ccp1()
  66. {
  67.    numero_de_flanco_subida_ccp1++;             // Cuento flanco que nos llega
  68.    if (numero_de_flanco_subida_ccp1 == 1)      //es el primer flanco de subida dentro del conteo
  69.    {
  70.       veces_desbordado_ccp1 = 0;               //reinicio contador de desborde
  71.       set_timer1(0);                      //reinicio el TMR1
  72.    }
  73.    if (numero_de_flanco_subida_ccp1 == 2)      //ahora llego el segundo flanco de subida
  74.    {
  75.       periodo_alto_en_ticks_ccp1 = CCP_1;      //guardo el valor de ccp_1  
  76.       cantidad_de_ticks_ccp1 = (65536 * veces_desbordado_ccp1) + periodo_alto_en_ticks_ccp1;
  77.       if (cantidad_de_ticks_ccp1<41667) //   1000000/(0.2*41667)=120Hz -->MAX F QUE MEDIREMOS
  78.       {                                //  esto es para evitar conteos por ruidos....
  79.          cantidad_de_ticks_ccp1=0; //ultima_cantidad_de_ticks_ccp1; //para evitar un poco el posible ruido
  80.       }                                                        //si midio cualquiera, dejo lo q estaba medido q es bueno...
  81.       //ultima_cantidad_de_ticks_ccp1=cantidad_de_ticks_ccp1;
  82.       numero_de_flanco_subida_ccp1=0;
  83.       veces_desbordado_ccp1=0;
  84.       periodo_alto_en_ticks_ccp1=0;
  85.       conteo_control_ccp1=0;
  86.    }
  87. }
  88.  
  89. ////////////////////////////////////////////////////////////////////////////////////
  90. // Interrupcion por Recepcion de flanco de SUBIDA en ccp2
  91. ////////////////////////////////////////////////////////////////////////////////////
  92.  
  93. #int_ccp2
  94. void llego_flanco_ccp2()
  95. {
  96.    numero_de_flanco_subida_ccp2++;             // Cuento flanco que nos llega
  97.    if (numero_de_flanco_subida_ccp2 == 1)      //es el primer flanco de subida dentro del conteo
  98.    {
  99.       veces_desbordado_ccp2 = 0;               //reinicio contador de desborde
  100.       set_timer1(0);                      //reinicio el TMR1
  101.    }
  102.    if (numero_de_flanco_subida_ccp2 == 2)      //ahora llego el segundo flanco de subida
  103.    {
  104.       periodo_alto_en_ticks_ccp2 = CCP_2;      //guardo el valor de ccp_1
  105.       cantidad_de_ticks_ccp2 = (65536 * veces_desbordado_ccp2) + periodo_alto_en_ticks_ccp2;
  106.       if (cantidad_de_ticks_ccp2<41667) //   1000000/(0.2*41667)=120Hz -->MAX F QUE MEDIREMOS
  107.       {                                //  esto es para evitar conteos por ruidos....
  108.          cantidad_de_ticks_ccp2=0; //ultima_cantidad_de_ticks_ccp2; //para evitar un poco el posible ruido
  109.       }
  110.       //ultima_cantidad_de_ticks_ccp2=cantidad_de_ticks_ccp2;
  111.       numero_de_flanco_subida_ccp2=0;
  112.       veces_desbordado_ccp2=0;
  113.       periodo_alto_en_ticks_ccp2=0;
  114.       conteo_control_ccp2=0;
  115.    }
  116. }
  117.  
  118. void main()
  119. {
  120.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  121.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  122.    set_tris_b(0b01111111);
  123.    set_tris_c(0b10011111); //5out,4in
  124.    output_high(PIN_B7);
  125.    delay_ms(100);
  126.    output_low(PIN_B7);
  127.    delay_ms(100);
  128.    output_high(PIN_B7);
  129.    delay_ms(100);
  130.    output_low(PIN_B7);
  131.    setup_ccp1(CCP_CAPTURE_RE);      //pongo para q espere flanco de SUBIDA el CCP1 y el CCP2
  132.    setup_ccp2(CCP_CAPTURE_RE);
  133.    set_timer1(0);
  134.    enable_interrupts(INT_CCP1);     //habilito todas las interrupciones necesarias
  135.    enable_interrupts(INT_CCP2);
  136.    enable_interrupts(INT_TIMER1);
  137.    enable_interrupts(INT_TIMER0);
  138.    enable_interrupts(GLOBAL);
  139.    while (true)
  140.    {
  141.       if(desbordes_tmr0>12500) //calculado para q pase 1.5seg es 7500000*0.2us=1500000
  142.       {                       //si quiero cada 250ms --> 12500*.2us=2500
  143.          output_toggle(PIN_B7);
  144.          printf("@%Lu#",cantidad_de_ticks_ccp1);
  145.          delay_ms(5);
  146.          printf("$%Lu#",cantidad_de_ticks_ccp2);
  147.          desbordes_tmr0=0;
  148.       }
  149.    }
  150. }

El proximo paso es realizar un codigo con el q funcionen los 2 CCP y a su vez hacer lo mismo con el RB0 (int_ext) para poder tener 3 entradas capaces de medir el perídodo de una señal... ya lo hare en algun momento...

Saludos desde CBA, ARG!
...::: Un feliz usuario de Debian Linux (e17) y amante de los PIC :::...

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #13 en: 25 de Mayo de 2008, 23:19:27 »
Saludos.

Gracias por compartirlo y muchas felicitaciones, se ve muy interesante tu proyecto amigo julietgolf
El papel lo aguanta todo

Desconectado CEAUGO

  • PIC10
  • *
  • Mensajes: 13
Re: Medidor de Frecuencia con CCP1 y CCP2 (Problema con ello)
« Respuesta #14 en: 26 de Mayo de 2008, 00:49:17 »
Hola ps yo soy novato en c y respecto a las interrupciones he visto que el programa tiene varias interrupciones mi pregunta es no deberia hacer una prioridad de interrupciones como se hace en ASM. Gracias exitos...


 

anything