CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Measuring pulse width using CCP
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

Measuring pulse width using CCP
PostPosted: Mon Mar 24, 2014 12:32 pm     Reply with quote

I have used a sample code by "PCM PROGRAMMER" to fit my requirement but I am stuck and the code is not functioning properly. My requirement is that I have a incoming pulse that is 2.6ms high and 7.0 ms low, period of 9.6 ms. I simply want to measure the pulse and if the pulse matches the requirement (with some tolerance ) then turn on the LED. I want to use only CCP1 to do this task. Once i get this part working i have another incoming pulse that i will use the CCP2 for.

Using MPLAB IDE V8.70

Code:


#include <16F886.h>
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)

int8 capture_rising_edge;
int8 got_pulse_width;
int16 ccp_delta;
   
#int_ccp1                     //Interrupt Name
  void isr_ccp1()               //Interrupt Function
  {

static int16 t1_rising_edge;

//If current interrupt is for rising edge.
if(capture_rising_edge)
   {
   setup_ccp1(CCP_CAPTURE_FE);
   capture_rising_edge = FALSE;
   t1_rising_edge = CCP_1;
   }
else
   {
   setup_CCP1(CCP_CAPTURE_RE);
   capture_rising_edge = TRUE;
   ccp_delta = CCP_1 - t1_rising_edge;
   got_pulse_width = true;
   }

}

//+++++++++++++++++

void main()   ///
{
int16 local_ccp_delta;
int16 pulse_width_ms;

got_pulse_width = FALSE;
capture_rising_edge = TRUE;

setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);

while(1)
{
   if(got_pulse_width)
   {
   disable_interrupts(GLOBAL);
   local_ccp_delta = ccp_delta;
   enable_interrupts(GLOBAL);

   pulse_width_ms = local_ccp_delta/125;
      if(pulse_width_ms)
      {
      (=>2)&&(=<3);   //is the measured pulse greater then 2 and less than 3, If yes than turn on LED at C5
      output_high(pin_c5);
      }
      else
      {
      output_low(pin_c5);
      }
   got_pulse_width = FALSE;

}
}
}




[img] file:///C:/Users/ppala/Desktop/sim.png [/img]
[/code]


Last edited by Aragon on Mon Mar 24, 2014 1:33 pm; edited 1 time in total
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Mon Mar 24, 2014 12:54 pm     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=47549
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Mar 24, 2014 1:02 pm     Reply with quote

You are creating no friends by using Proteus - read the sticky at the top of the forum. Proteus's simulation of PIC's is fundamentally poor.

However you main problem is a syntax error:
Code:

      if(pulse_width_ms==2)
      {
            output_high(pin_c5);
      }
      else
      {
            output_low(pin_c5);
      }


The statement immediately after the 'if' is what is evaluated for true/false - nothing else.

Then pulse_width_ms value is an integer, so your description in the 'comment': "is the measured pulse greater then 2 and less than 3, If yes than turn on LED at C5"
Can never be true. I've just shown it being tested for being 2.

Better really to test for:
if (local_ccp_delta>250 && local_ccp_delta<375)

Which will give the range you talk about in the comment.

To make it friendly:
Code:

#define MS_2 (250)
#define MS_3 (375)

    if (local_ccp_delta>MS_2 && local_ccp_delta<MS_3)
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Mon Mar 24, 2014 1:03 pm     Reply with quote

Thanks Ttelmah. I will change my code accordingly.
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Mon Mar 24, 2014 2:30 pm     Reply with quote

I tested the chip on a circuit board. The LED turns ON as soon as I provide the PWM signal. However when I turn off the input Pulse the LED stays ON for several seconds before it turns off. It seems that I have to play with the prescaler? so that when signal is not there the LED turns off. Am I right with changing the prescaler?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Mar 24, 2014 3:01 pm     Reply with quote

No....

The interrupt only triggers when there is a pulse. As it stands, it won't detect the lack of a pulse. It detects pulses of different lengths. There has to be a pulse.
What you could do, is add a software timeout to the loop, so if a pulse is _not_ seen, it switches to a required state.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Mar 24, 2014 3:09 pm     Reply with quote

In this thread I give a written description of how to detect
a loss of input signal:
http://www.ccsinfo.com/forum/viewtopic.php?t=18034
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 5:47 am     Reply with quote

Thanks for the great advice guys. I will implement the "no input" with a software timer. Smile
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Wed Oct 08, 2014 10:37 am     Reply with quote

Hello,
Sorry to Re-Vamp this post. This has been a side project that I am working on. The code worked properly using CCP1 and Timer1. However when I tried to use CCP2 and Timer0 in parallel with CCP1 and Timer1, The CCP2 was not working. I will post the code later in the evening when I get home.
The question I have is, Can I use both CCP1 and CCP2 simultaneous with different timers to measure two different pulses coming in?

Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Oct 08, 2014 2:32 pm     Reply with quote

With your chip, you can't.

The data sheet is your friend. Table 11-1, and 11-2

Capture, and compare modes, _only_ use timer1.

Several of the later chips with timer3, allow this to be used as an alternative, but on your chip, only one timer can be used.
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Wed Oct 08, 2014 4:20 pm     Reply with quote

Thanks for the reply. I have to start looking for a different chip now.
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Wed Oct 15, 2014 8:48 am     Reply with quote

Hello,

The PIC i found is PIC18F2550. The code is working for 16F886 but when i use the same code for 18F2550 it doesnt work. For now I only want the Timer1 to work first so its the same code as 16F886. I had a look at the timer 1 control register for both the pics and only register 6 and 7 are different.
for 18F2550 I guess, I have to enable the 16 bit operation for bit7? and for bit 6 user timer1 oscillator?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Oct 15, 2014 11:10 am     Reply with quote

The CCP stuff is basically the same, except for the added commands to use timer3. It defaults to timer1. Have you actually checked the chip is running, and running at the speed you expect?. The old 'flash an LED' test. The thing that is a lot more complex on this chip, is the clock setup. Timer1, only works as a 16bit timer. The only timer that can switch between 8bit and 16bit, is Timer0. The bit you are looking at controls how it is _accessed_, not how it runs. Don't touch this bit. The setting for bit 6, is the same as for the 16 chip. Controlled by whether you select T1_INTERNAL or EXTERNAL (you want INTERNAL).
Aragon



Joined: 19 Mar 2014
Posts: 20

View user's profile Send private message

PostPosted: Wed Oct 15, 2014 12:06 pm     Reply with quote

Code:

#include <18F2550.h>
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

int8 capture_rising_edge1;
int8 got_pulse_width1;
int16 ccp_delta1;

#define MS_2 250
#define MS_3 375

   
#int_ccp1                     //Interrupt Name
  void isr_ccp1()               //Interrupt Function
  {

static int16 t1_rising_edge;

//If current interrupt is for rising edge.
if(capture_rising_edge1)
   {
   setup_ccp1(CCP_CAPTURE_FE);
   capture_rising_edge1 = FALSE;
   t1_rising_edge = CCP_1;
   }
else
   {
   setup_CCP1(CCP_CAPTURE_RE);
   capture_rising_edge1 = TRUE;
   ccp_delta1 = CCP_1 - t1_rising_edge;
   got_pulse_width1 = true;
   }

}


//+++++++++++++++++

void main()   ///
{

int16 local_ccp_delta;
int16 pulse_width_ms;

got_pulse_width1 = FALSE;
capture_rising_edge1 = TRUE;

setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);


while(1)
{
   if(got_pulse_width1)
   {
   disable_interrupts(GLOBAL);
   local_ccp_delta = ccp_delta1;
   enable_interrupts(GLOBAL);

   pulse_width_ms = local_ccp_delta/125;
    printf("%lu ms \n\r", pulse_width_ms);
   got_pulse_width1 = FALSE;
}
if(local_ccp_delta>MS_2 && local_ccp_delta<MS_3)
{
   output_high(pin_c5);
}
else
{
   output_low(pin_c5);
}
   delay_ms(500);
}
}


I have attached the code. I have checked the chip and it's running ok. I did a small test. Enabled "high" on some ports and it seemed to work. I am using the internal clock for now. any errors in my code? Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 15, 2014 1:28 pm     Reply with quote

Quote:
Enabled "high" on some ports and it seemed to work.

You're not using "some ports". You're using pin C5. Blink an LED on
that one. It's the one you're using, so it's the logical choice for the test.
If it doesn't work, then look at the pin descriptions in the PIC data sheet.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group