Contar pulsos con CCP en modo captura

Ya casi esta me falta un poco de ayuda para que corra mejor el programa, ya sube y baja rápido pero no logro reflejar la muestra en el adc, lo demás funciona bien no se si estoy aplicando bien las memorias pero hace lo que necesito.
Buenas.
No puedo compilar tu código porque falta el la librería "Flex_lcd416.c", pero te paso tu codigo con algunas modificaciones para que lo pruebes:
PHP:
#include <16f883.h>
#device ADC=10
#use     delay(internal = 8MHz)                           
#include <flex_lcd416.c>
#define led PIN_B5
#include <internal_eeprom.c>


int1 flagHayDatos=0; 
float const ticks_us = 4.0;          // microsegundos por Tick del Timer 1 @ 8 MHz. (Osc. Interno)
//float const ticks_us = 8.0;          // microsegundos por Tick del Timer 1 @ 8 MHz. (Osc. Cristal)
long int var1=0, var2=0;
int8 flancos;
int8 flag_flanco;
int16 periodo1,periodo2,periodo3;
int16 tiempo_alto,tiempo_bajo,tiempo_total;
float us_alto,us_bajo,us_total, valor,volt,valor2,amper, duty;
   int porcentaje,porcentaje1;
   int frecuencia;
   
int16 valor_adc;
   float voltaje;
int8 porcentaje2,  ciclo_activo=1;
void voltaje(void);
   
   
   
#INT_EXT
void sdi_externa_RB0 (void)
{
   flancos++;                          // Incrementar la variable "flancos"
   
   if(!flag_flanco)                    // Si el flanco del pulso es bajo...
   {
      if(flancos == 1)                 // Si el conteo de flancos es 1...
      {
         set_timer1(0);                // Limpiar el Timer 1
         periodo1 = get_timer1();      // "periodo1" tendrá el tiempo del pulso en alto.
      }
      if(flancos == 3)                 // Si el conteo de flancos es 3...
         periodo3 = get_timer1();      // "periodo3" tendrá el tiempo del pulso en alto.
         
         EXT_INT_EDGE(H_TO_L);         // Establecer la interrupción por flanco de bajada.
         flag_flanco = 1;              // Indicar que el próximo flanco será de bajada.
   }
   else                                // Caso contrario. (Pulso en estado alto)...
   {
      periodo2 = get_timer1();         // "periodo2" tendrá el valor del pulso en bajo.
      EXT_INT_EDGE(L_TO_H);            // Establecer la interrupción por flanco de subida.
      flag_flanco = 0;                 // Indicar que el próximo flanco será de subida.
       if(flagHayDatos==0){       // Si los datos anteriores han sido procesados ...
      flagHayDatos=1;          // Indico que ya hay nuevos datos de flancos para calcular
    }
   }

   if(flancos > 2)flancos = 0;         // Si la variable "flancos" llega a 3, ponerla a 0.
}


void establecer_ciclo (int8 ciclo)
{
   
 
   set_pwm1_duty(ciclo);   // Establecer el ciclo activo
   lcd_gotoxy(10,3);
   // Obtener el porcentaje del ciclo activo.
   porcentaje2 = (ciclo / 24.5) *10;
   // Mostrar el porcentaje del ciclo activo para la carga.
   printf(lcd_putc,"C:%03u%c",porcentaje2,37);
   voltaje();       
     
}

void voltaje (void)
{
int16 valor_adc;
float voltaje;
 set_adc_channel(10); // Establecer la lectura del canal ADC 10
   delay_us(50);
   valor_adc = read_adc(); // Tomar la lectura del voltaje.
   voltaje = ((valor_adc * 20.0) / 1023);
  lcd_gotoxy(1,1);
  printf(lcd_putc,"%4.1fV ",voltaje);
    lcd_gotoxy(1,2);
   printf(lcd_putc,"C:%03u%c",porcentaje2,37);
delay_ms(30);
}  

void pulsadores() 
{   
   if (input(PIN_A0)==0)
   {
    while(!input(pin_a0)){
      ciclo_activo ++;  // Incrementar el ciclo activo.
      if (ciclo_activo > 249) ciclo_activo = 249;   // No permitir que el ciclo activo suba de 249
      delay_ms(10);
      establecer_ciclo(ciclo_activo);
   }
   }
   if (input(PIN_A1)==0)
   {
    while(!input(pin_a1)){
      ciclo_activo --;  // Disminuir el ciclo activo.
      delay_ms(10);
       if (ciclo_activo <= 1) ciclo_activo = 2;  // No permitir que el ciclo activo baje de 1
      establecer_ciclo(ciclo_activo);
   }
   
}
}

   
void memoria()
{
 int8 cont;     
   if(input(pin_a2)==0){
          while(!input(pin_a2)){
          cont++;
          delay_ms(10);
          if (cont >80){
          write_eeprom(00,ciclo_activo ); // guardo el dato ciclo activo
         delay_ms(50);
    lcd_gotoxy(2,1);
         printf(lcd_putc, "\fMEMORIA GRABADA");
         delay_ms(1000);
         CONT = 0;
          }
          }
           ciclo_activo =read_eeprom(00); // paso el dato a la variable ciclo_activo
           lcd_gotoxy(2,1);
           printf(lcd_putc, "\fMEMORIA LEIDA");
           delay_ms(1000);
           printf(lcd_putc,"\f"); 
           cont=0;
            delay_ms(50);
             establecer_ciclo(ciclo_activo);
            }
}  

  void memoria1()
{     
 int8 cont;     
   if(input(pin_a3)==0){
          while(!input(pin_a3)){
          cont++;
          delay_ms(10);
          if (cont >80){
          write_eeprom(01,ciclo_activo ); // guardo el dato ciclo activo
         delay_ms(50);
    lcd_gotoxy(2,1);
         printf(lcd_putc, "\fMEMORIA GRABADA");
         delay_ms(1000);
         CONT = 0;
          }
          }
           ciclo_activo =read_eeprom(01); // paso el dato a la variable ciclo_activo
           lcd_gotoxy(2,1);
           printf(lcd_putc, "\fMEMORIA LEIDA");
           delay_ms(1000);
           printf(lcd_putc,"\f"); 
           cont=0;
            delay_ms(50);
             establecer_ciclo(ciclo_activo);
            }
} 
  

void main()
{
     
 setup_ccp1(CCP_PWM);
   setup_timer_2(T2_DIV_BY_4,249,1);   // 1000 Hz. @ 4 MHz.
   set_pwm1_duty(1);                   // Ciclo activo al mínimo
   
   setup_adc_ports(sAN10|san4);
   setup_adc(ADC_CLOCK_INTERNAL);
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   enable_interrupts(int_ext);
   ext_int_edge(0,L_TO_H);
   enable_interrupts(global);
 
   
   lcd_init();
    establecer_ciclo(ciclo_activo);
   #ZERO_RAM   // Limpiar RAM. (Variables en 0)

  
   
   while (true)
   {
   
   pulsadores(); 
   memoria();
   memoria1();
   voltaje();
    if(flagHayDatos==1){
    output_HIGH(led);
      if((periodo3 > periodo2) && (periodo2 > periodo1))
      {
         tiempo_alto = periodo2 - periodo1;                 // Obtener el periodo del pulso en estado alto.
         tiempo_bajo = periodo3 - periodo2;                 // Obtener el periodo del pulso en estado bajo.
         tiempo_total = tiempo_alto + tiempo_bajo;          // Obtener el periodo de la frecuencia.
         us_alto = ticks_us * tiempo_alto;                  // Obtener el periodo en microsegundos del pulso en alto.
         us_bajo = ticks_us * tiempo_bajo;                  // Obtener el periodo en microsegundos del pulso en bajo.
         us_total = ticks_us * tiempo_total;                // Obtener los microsegundos en total de la frecuencia.
         frecuencia = 1 / (us_total / 1000000);             // Obtener la frecuencia.
         duty = ((float) tiempo_bajo / (float)(tiempo_bajo + tiempo_alto));
          porcentaje = (duty * 100) + 10; // Físicamente el + 0.5 puede no ser necesario. (Ajusta desviación pero consume ROM)       
      } 
       flagHayDatos=0; 
    }
      lcd_gotoxy(10,1);
      printf(lcd_putc,"Hz:%03u ",frecuencia);
       if(porcentaje < 3)porcentaje = 0;
      if(porcentaje > 95)porcentaje = 99;
    
      lcd_gotoxy(10,4);
      printf(lcd_putc,"Duty:%02u%% ",porcentaje );
    
      
       flagHayDatos=0; 
       
      delay_ms(100); // Retardo para disminuir parpadeos en la pantalla. (No afecta interrupción externa.)
      if(flagHayDatos==0){
      frecuencia = 0;
      porcentaje=0;
      porcentaje1=0;
      output_low(led);
      }
      
      
   
   // set_adc_channel(10); // Establecer la lectura del canal ADC 10
   //   delay_us(20);
   //   valor_adc = read_adc(); // Tomar la lectura del voltaje.
      
     
   //   voltaje = ((valor_adc * 20.0) / 1024);
   //   
   //      lcd_gotoxy(1,1);
  // lcd_putc("Volt   "); 
  //lcd_gotoxy(1,2);
  //    printf(lcd_putc,"%4.1fV ",voltaje);   
 
  
  
  set_adc_channel(4); 
    delay_us(30);
   amper=0;
  for(var2=0;var2<300;var2++)
  {
    amper=amper+ read_adc();
    delay_us(62);  
  }

  valor2 = amper / 300;
  valor2 = valor2 * 21 / 1023;

  lcd_gotoxy(10,2);
  printf(lcd_putc,"A:%4.1f",valor2); 
  delay_ms(50);
   }
}
 
Volví a pedir ayuda no me funciona las memorias cuando presionó el pulsador graba y lee siempre, no logro hacer que grabe cuando presionó 5 segundos y lea con el mismo pulsador cuando presionó 1 segundo
 
Volví a pedir ayuda no me funciona las memorias cuando presionó el pulsador graba y lee siempre, no logro hacer que grabe cuando presionó 5 segundos y lea con el mismo pulsador cuando presionó 1 segundo

Buenas.
Disculpa el codigo que te pase habia un error de calculos, solo tienes que aumentar la variable cont en tus rutinas de memoria, (tienes que aumentar o disminuir para obtener el tiempo deseado). Asi:
Código:
int16 cont;     
   if(input(pin_a3)==0){
          while(!input(pin_a3)){
          cont++;
          [COLOR="Red"][B]delay_ms(1);
          if (cont1 >5000){[/B][/COLOR]
          write_eeprom(01,ciclo_activo ); // guardo el dato ciclo activo
         delay_ms(50);

Tambien note que las variables:
int porcentaje,porcentaje1;
int frecuencia;
se desbordan al aumentar la frecuencia debes ver eso tambien.
Por ultimo te paso el ejemplo con modificaciones, tal vez tenga errores, no he tenido tiempo para analizar mejor, modifique también la libreria del lcd pero no lo he probado fisicamente.
 

Adjuntos

  • Nueva carpeta.rar
    311.7 KB · Visitas: 11
en EL BASIC se puede hacerlo de una sencilla manera hay una funcion COUNT pero como podria pasarlo al ccs ¿copiando el lenguaje en essamber? es lo unico que se me ocurre por que no necesita de un modulo para hacer esta funcion o alguien entiende su funcionamiento para hacer mas efectivo un pic y no necesitar de un pic con ccp que solo por un pin puede ejecutar esta funcion bueno e intentado hacerlo pero solo me llega hasta 200 hz pero en el BASIC ES 60 KHZ y se dice que los pics pueden llegar al orden de los MHZ seria cuention de que un sabio en los dos compiladores dara su respuesta
 
Contar pulsos? usas la entrada de reloj y el temporizador configurado a reloj externo, con eso directamente incrementas el contador con los pulsos, lo de medir el tiempo si está más complicado por que hay que sincronizar dos temporizadores.

El otro método es por interrupciones y se limita a que tan rápido puede el PIC procesar las cuentas en la CPU.
 
Atrás
Arriba