I want to measure pulse duration using only one CCP model in capture mode with a pic 18f4550, so I try to detect the rising edge in first time, when a rising edge is detected the timer1 turn on and the capture mode change to falling edge, with this method I have to measure the pulse width, but the code I use doesn't work well!! it was good when I used two CCP model. if anyone could help, I will be grateful.
#include <stdio.h>
#include <stdlib.h>
#include "osc_config.h"
#include "LCD_8bit_file.h"
#include <string.h>
void main()
{
unsigned long comtage;
unsigned long DEPHASAGE[20];
float Deph_tempo;
TRISCbits.TRISC2=1;
IRCF0=1;
IRCF1=1;
IRCF2=1;
LCD_Init();
LCD_String_xy(0,0,"Deph.tempo");
PIE1bits.CCP1IE=1;
PIR1bits.CCP1IF=0;
CCP1CON=0b00000101;
CCPR1=0;
T1CONbits.RD16=1;
T1CKPS0=0;
T1CKPS1=0;
TMR1CS=0;
TMR1IF=0;
TMR1=0;
while(1)
{
if(PIR1bits.CCP1IF==1){
TMR1ON=1;
PIR1bits.CCP1IF=0;
CCP1CON=0b00000100;
while(!(PIR1bits.CCP1IF==1))
comtage= TMR1;
PIR1bits.CCP1IF=0;
Deph_tempo = (((float)comtage /30.518)/65536 );
sprintf(DEPHASAGE,"%.5f ",Deph_tempo);
LCD_String_xy(2,0,DEPHASAGE);
}
TMR1=0;
TMR1ON=0;
CCP1CON=0b00000101;
}
}
Reducing the number of instructions being exceuted while waiting for CCP1IF will increase precision. Have you tried this?
// ...
while (1)
{
CCP1CON = 0b00000101;
PIR1bits.CCP1IF = 0;
TMR1ON = 0;
TMR1 = 0;
// if your comms with the LCD use interrupts:
//
// disable interrupts here
while (!PIR1bits.CCP1IF)
;
TMR1ON = 1;
CCP1CON = 0b00000100;
PIR1bits.CCP1IF = 0;
while (!PIR1bits.CCP1IF)
;
compte = TMR1;
// if your comms with the LCD use interrupts:
//
// enable interrupts here
// refresh display
// if your comms with the LCD use interrupts:
//
// you may want to add a small delay here, to
// allow for comms to the LCD to end.
// this may not be necessary, depending on the
// signal frequency.
}
// ...
If that doesn't work, you should check that the LCD is NOT using interruots.
If it does, you should:
That's for a solution without using interrupts... I think you'll get better results using pin change interrupts and a free running timer.
EDIT: After writing this solution, I found the bug in your code, around these lines of code:
while(!(PIR1bits.CCP1IF==1)) // this is missing a ;
comtage= TMR1; // this line gets executed in the loop
// and adds instructions to the
// loop, this probably more than
// halves the precision of your
// results.
// the imprecision is increased with
// your code that runs after the if block