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 support@ccsinfo.com

PIC24 CCP module

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
desert eagle



Joined: 27 Sep 2013
Posts: 7
Location: Frankfurt, Germany

View user's profile Send private message

PIC24 CCP module
PostPosted: Fri Sep 27, 2013 3:14 am     Reply with quote

Hi,

I'm currently working with PIC24FV32KA301 and I am trying to use input capture module to measure an average time period over 4 rising edges in my input capture routine. I have taken help from earlier posts as well. I am able to generate pulses of 1ms pulse width using Output compare but I want to use the avg time period calculated from Input capture module. This means if input capture gives an avg time of a wave as 20ms, I want to generate a pulse of 1ms which repeats every 20ms using Output compare. How can I do it?
_________________
Asghar
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Sep 30, 2013 11:44 am     Reply with quote

Why not use the PWM module?

Should be a piece of cake.

Mike
desert eagle



Joined: 27 Sep 2013
Posts: 7
Location: Frankfurt, Germany

View user's profile Send private message

PIC24 CCP module
PostPosted: Tue Oct 01, 2013 12:51 am     Reply with quote

@Mike well the problem is, I don't want the output pulse width to change. I want to have it fixed, say at 250us. Only the frequency should vary depending upon the input frequency. But I want to measure average period first, since the input pulses appear with variable frequency.
_________________
Asghar
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Oct 01, 2013 1:53 am     Reply with quote

I don't have PIC24's but I do have PIC18's

On PIC18's, set_pwmx_duty(value) fixes the PWM ON_PERIOD not the DUTY_RATIO.
Changing the PWM frequency then alters the DUTY_RATIO but has no effect on the PULSE WIDTH.
This appears to be exactly what you want.
It would be rather perverse if PIC24's worked differently.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Tue Oct 01, 2013 2:10 am     Reply with quote

OK.

On the old PIC18, this is obvious, and pretty simple. You'd have the CCP, using the same clock source as the timer feeding the PWM, and leave the pulse 'width' programmed to a fixed value, then change the timer reset point to match the recorded CCP value.

So how do we do the same on the PIC24?.

Now first thing with these chips, is that the data sheet, has only the 'chip specifics' in it. The general data is at:
<http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2575>

These are the 'module reference manuals' for each part, and are vital.

Now, if you pull section 16, this covers how to use the output compare ability to generate a PWM. 16.3.3, for a simple PWM. Now the key here is if you setup the PWM, using the CCS functions, for the longest period time you want, all that has to be changed to give the shorter repeat period, is the value in the PRy register. The OCxRS register defines the 'on' time, which can be left unchanged.

So, I'd suggest doing exactly that. Use #word, and 'getenv', to give you a direct definition of the PR register for the PWM you are using. Calculate your period from your recorded times (sounds as if you want to record four, sum them, and divide by four to give a slight 'averaging'?), then write this value, to the PR register to update the PWM period.

Since TyIF is set when the timer resets at the end of the period, this should be used as the point to update the value.

Best Wishes
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Tue Oct 01, 2013 2:19 am     Reply with quote

I see Mike posted while I was posting.

The PIC24's, are different, but similar. All the timers are individually programmable for a reset count. There is then an option to set or clear the output pin at this reset. Then you have a function similar to the PIC18 'output compare', which allows you to change the output pin at the compare match. So the timer resets to zero, and counts till it reaches it's 'reset' point, and keeps doing this to give the 'period'. Then you use the 'compare' function to reset the output pin at the count required for the pulse width.

So only the period setting for the timer being used needs to change, but to do this without interfering with the pulse train, I'd suggest just updating the register directly, when the interrupt for a completed cycle is seen.

Best Wishes
desert eagle



Joined: 27 Sep 2013
Posts: 7
Location: Frankfurt, Germany

View user's profile Send private message

PostPosted: Tue Oct 01, 2013 5:48 am     Reply with quote

Thanks guys for your replies. Can u please have a look at the following code? I wrote it a couple of days back and it works fine. But when i try to calculate Period of the input waveform in the input capture ISR, the output compare generates pulses after every 2nd rising edge of input(it shud generate after every rising edge as Input capture is configured for it)but without the 'period' calculation in the ISR, the program works fine. I dont understand the problem. Is it bec of the delay caused by the execution of calculation? Also I want to use this 'period' value further to control the period of output as in real, the input period is not constant. so i want to take average input period




[code]

#include <24FV32KA301.h>


#define Out PIN_B1
#define In PIN_B9


#fuses FRC,NOWDT,PROTECT,MCLR // Konfigurationswort
#use fast_io(B)
#use delay(clock=8000000)



unsigned int period;
unsigned int flag_counter=0;
unsigned int multiple;
static unsigned long pre_timervalue=0;
unsigned long new_timervalue;

long int OCR_3 =0x0000; //1ms Pulse generation start value for output compare mode

long int OCRS_3=0x0005; //0.25ms Pulse
//Pulse stop value 0.25ms/(2/8MHz*256) where 256 is Timer 3 prescalar

unsigned int flag_counter1=0;

void main(void)

{
// INITIALIZATION
SETUP_WDT(WDT_OFF);
SETUP_OSCILLATOR(OSC_INTERNAL);
SETUP_ADC(ADC_OFF);
SET_TRIS_B(0x0200); //Input and Output pin definition (0000 0010 0000 0000)
//FEDC BA98 7654 3210

//Interrupt initialization

ENABLE_INTERRUPTS(INTR_GLOBAL);
ENABLE_INTERRUPTS(INT_TIMER2);
ENABLE_INTERRUPTS(INT_IC2);
ENABLE_INTERRUPTS(INT_OC3);

// ENABLE_INTERRUPTS(INT_TIMER4);


//Capture module initialization

SETUP_TIMER2(TMR_INTERNAL); //Timer 2 with System clock as a source for IC
SETUP_CAPTURE(2, CAPTURE_RE|CAPTURE_TIMER2|INTERRUPT_EVERY_CAPTURE); //capture mode capturing every rising edge for period measurement

while(1)
{};

}


#INT_IC2
void IC2_isr(void)
{

/* multiple=flag_counter;
flag_counter=0;
period = get_capture(2,TRUE);


// period=(new_timervalue)-(pre_timervalue);
period=((new_timervalue)-(pre_timervalue)+(65536*(multiple+1))) ; //multiple indicates 16-bit timer overflow count


pre_timervalue=new_timervalue; */

SETUP_TIMER3(TMR_INTERNAL|TMR_DIV_BY_256);
SET_COMPARE_TIME(3,OCR_3, OCRS_3); //Output pulse width

//but we need a dynamic value from Input Capture
SETUP_COMPARE(3,COMPARE_SINGLE_PULSE | COMPARE_TIMER3);
clear_interrupt(INT_IC2); //clear IC flag to run for next edge

}

#INT_TIMER2
void TIMER2_isr(void) //timer2 interrupt
{
flag_counter++; //this is a counter for timer2 overflows
clear_interrupt(INT_TIMER2); // clear timer2 interrupt's flag
}
_________________
Asghar
temtronic



Joined: 01 Jul 2010
Posts: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Oct 01, 2013 6:00 am     Reply with quote

quick answer yes....
ISR must be short! having any kind of 'math' inside an ISR is,well, terrible. Just set a flag, record some data, and get out...fast...

in 'main', do the math...

also
you do not need to clear_ints inside the ISR( CCS does that for you)

and
usually you 'enable' interrupts, then 'enable' the global interrupt.

hth
jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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