Contar pulsos con CCP en modo captura

#1
Hola que tal amigos del foro !!!!! estoy leyendo tanto este foro que bueno aveces toca preguntar ja ja les escribo a ver si alguien me puede ayudar con lo siguiente( soy principiante autodidacta) y quiero hacer un cuenta vueltas pero usando el modulo ccp en modo de captura del pic 16f876a , ya hice uno haciendolo por interrupcion de timers y funciona pero me dijeron que con el ccp es mucho mas facil y preciso, y quiero aprender a usarlo, el tema es que he leido lo que encontre sobre este tema pero no logro comprenderlo hay muchos ejemplos de medir ancho de pulso capturando el flanco de subida y despues el de bajada y haciendo la cuenta..... , pero lo que yo quiero supongo es medir el tiempo entre dos flancos de subida y eso pasarlo a rpm (revoluciones por minuto) mostrandolo en una lcd , pero se me ha hecho una ensalada terrible . Uso el compilador ccs si alguien me puede mostrar algun ejemplo sencillo o alguna pagina donde buscar les estare muy agradecido Saludos !!!! ...
 
#2
esta podria ser una forma de contarlos:
Código:
#include <16F876A.h>
#device adc=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT, RESERVED
#use delay(clock=20000000)
#include <lcd.c> 

int time,ltime;

#int_CCP1
void  CCP1_isr(void) 
{
 time= ccp_1-ltime;
 ltime=ccp_1;	
 clear_interrupt(int_ccp1);	
}

void main()
{
 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
 setup_ccp1(CCP_CAPTURE_RE);
 enable_interrupts(INT_CCP1);
 enable_interrupts(GLOBAL);

 lcd_init(); 
while(true){
lcd_gotoxy(1,2);
printf(lcd_putc,"%u s", time);
delay_us(50);
} 
}
en rc2 va el pulso a medir
 
Última edición:
#4
Hola. Estoy haciendo una medición a través de RB0 del tiempo del ancho de pulso de una señal cuadrada.
Me gustaría que alguien me ayudara a realizar la medición a través del módulo CCP.
En el ejemplo que adjuntaré en Proteus aparecen dos señales desfasadas, las cuales al pasar por una compuerta XOR me resulta la señal cuadrada desfasada(5V, 60Hz).
Dicha señal es la cual quiero medir su ancho de pulso(t2-t1) pero no sé como hacerlo.
Tengo un código pero no se si está bueno.

Agradecería mucho que alguien me ayudara.


Código:
#include <16f877a.h>

#use delay(clock=4M)

#fuses HS,NOWDT
#include <LCD420D.C>

int16 TFB;                                     //Tiempo flanco de bajada
float PW;                                      //Valor final del ancho de pulso
int1 nuevopulso=0;                            //Entra otro pulso
int1 cambio=0;                          

#INT_EXT
void funcion_ext_int()
{                                              //Funcion Interrupcion
 if(cambio==0)                                 //Flanco de subida
 {
  set_timer1(0);                               //Inicializa TMR1
  ext_int_edge(0,H_TO_L);                      //Configura para flanco de bajada
  cambio=1;
 }
 else{
  TFB=get_timer1();                            //Valor del Timer 1 para flanco de bajada
  ext_int_edge(0,L_TO_H);                      //Configura para flanco de subida
  cambio=0;                                    //Control de cambio de flanco
  if(nuevopulso==0)                             //Fin de pulso
  {
   nuevopulso=1;                               //Pulso a calcular
  }
 }
}

void main(void)
{
 
 lcd_init();
 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);           //Configuracion TIMER1
 ext_int_edge(0,L_TO_H);                         //Configura para flanco de subida
 cambio=0;                                       //Control de cambio de flanco
 enable_interrupts(int_ext);                      //Habilitacion interrupcion RB0
 enable_interrupts(global);                       //Habilitacion general
 do
 {
  if(nuevopulso==1)                               //Si ¿nuevo pulso?
  {
   PW=TFB*1.0;                              //Ancho de pulso en us de TIMER1 a 4MHZ el T=1us*Timer1
    printf(lcd_putc,"\f");
   printf(lcd_putc,"\n\n\tPulso=%6.1fus",PW);      //Visualiza medida en LCD
   delay_ms(1000); 
  }
   nuevopulso=0;                                  //Pulso medido
 } 
     
      while(TRUE); 
}
 

Adjuntos

Última edición por un moderador:
#5
esta podria ser una forma de contarlos:
Código:
#include <16F876A.h>
#device adc=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT, RESERVED
#use delay(clock=20000000)
#include <lcd.c> 

int time,ltime;

#int_CCP1
void  CCP1_isr(void) 
{
 time= ccp_1-ltime;
 ltime=ccp_1;	
 clear_interrupt(int_ccp1);	
}

void main()
{
 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
 setup_ccp1(CCP_CAPTURE_RE);
 enable_interrupts(INT_CCP1);
 enable_interrupts(GLOBAL);

 lcd_init(); 
while(true){
lcd_gotoxy(1,2);
printf(lcd_putc,"%u s", time);
delay_us(50);
} 
}
en rc2 va el pulso a medir
Este código esta contando los flancos de subida?
Como hago para contar de una señal los pulsos de subida mostrarlo en lcd y contar los de bajada y mostrarlo?
 
#6
No es mejor la interrupción de un timer? Arriba comentan que es mejor en modo captura, pero es debido al registro Timer1 (16 bits). Con el timer0 tienes 8 bits con un prescalar 1:256, y el registro prácticamente te regala la configuración, solo debes calcular el valor de TMR0. Si vas a contar un pulso no te recomiendo usar delays porque se pierde precisión. Mejor dale una leída al datasheet del PIC.
 
#7
Yo quiero hacer de una señal cuadrada de una bobina que enciende y apaga tomar los flancos para medir duty con flancos ascendentes y cps con flancos descendente y me estoy volviendo loco para saber como medir cada flanco
 
Última edición:
#9
Quieres generar una señal cuadrada para conmutar una bobina? Y medir los flancos ascedentes y descendentes para asi obtener la frecuencian y a que duty cycle esta?
Y si vas a usar PIC, no es mejor usar el modulo CCP en modo PWM?
 
#11
Y si proporcionas un diagrama? No sera mas fácil ayudarte? Pero bueno.

Solo debes contar los pulsos ascendentes ('1') o descendentes ('0') que ocurren en un segundo, y para obtener el duty cycle debes comparar voltajes, si 5V corrsponden al 100%, entonces 2.5V son el 50%.

En el libro Compilador CCS y Proteus biene un ejemplo de medir frecuencia con el módulo CCP del PIC, que coincidencia no? :unsure:
 
Última edición:
#16
¿Si podéis mirar el ejemplo para decirme dónde me equivoco?
En todo. Si ya estás usando un microcontrolador, no necesitas el LM2907
El LM2907 es un conversor de frecuencia a voltaje, y con el microcontrolador puedes medir la frecuencia de una señal directamente y al mismo tiempo obtener el periodo. P = 1 / F
No entiendo la parte de medir el duty.
Para obtener el ciclo activo, necesitas medir el tiempo en nivel alto y el tiempo en nivel bajo, de los pulsos de entrada.
Al usar los timers, ésto lo podrás hacer hasta cierto limite de frecuencia, porque los timers desbordan.
(Para cambiar el factor de división cuando un timer desborda, se usan comparaciones.)

¿En sí, qué es lo que quieres hacer?
Si explicaras mejor el objetivo de tu proyecto, se te podría orientar mejor.
 
#17
Estoy tratando de medir las veces que enciende Y apaga una máquina de tatuar y usan Lm2907 para tomar las variaciones de la línea negativa y usando esos pulsos que son un prende y apaga de la bobina miden el cps y el duty de la maquina
 
#18
Ok. Si dices que lo usan para eso, es porque deben usar otro medio que no es un microcontrolador.
El microcontrolador es para minimizar hardware y con él se puede sustituir al LM2907.

En fin, para lo que quieres hacer ya se te dieron las bases, sólo debes implementarlas en tu programa.

 
#20
Eso es aún más fácil de hacer si el mismo instrumento genera la frecuencia.
Si conoces el rango para el registro CCPRXL, puedes mostrarlo como porcentaje con un simple cálculo.
 
Arriba