Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Frequency measurement using input capture module in dspic30f5011

Status
Not open for further replies.

saikiran@ees

Member level 3
Joined
Oct 2, 2015
Messages
58
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
Hyderabad
Activity points
455
Hi,
I am using dspic30f5011 controller and I configured the input capture module to measure the frequency by capturing the every rising edge.But I am getting only KHz frequencies and not getting the frequencies in Hz.So,what is the reason?



Thanks and Regards
M SAI KIRAN.
 

Hi,

I wonder how you get Hz or kHz, usually you get counter values.

The counter values depend on input frequency (we don´t know) and on counter prescaler (we don´t know).

For sure there may be a lot of configuration and/or programming issues. We dn´t see your code.

****
Review your post and you will see with the given informations it is impossible to find a solution.

Klaus
 

Hi KlausST,
Actually I captured values from capture buffer (IC2BUF) and then I made the calculations as per my code.

Here is my input capture function
Code:
 unsigned int timePeriod;
 float freq = 0;
/************************** main function *********************************/
main()
{
	
	uart1_init();
	timer_init();
	IC_INIT();	
	while(1);	
}

/***********************Input Capture init function ***************************/
void IC_INIT(void)
{
	  
	IC2CONbits.ICM     = 0b010;				// Input Capture Mode Select (Every rising edge)
	IC2CONbits.ICBNE  =0;				// Input Capture Buffer Empty Status (Read Only)
	IC2CONbits.ICOV    =0;				// Input Capture Overflow Status Flag (Read Only)
	IC2CONbits.ICI       = 00;				// Select Number of Captures per Interrupt bits (00 = Interrupt on every capture event)
	IC2CONbits.ICTMR  =0;				// Input Capture Timer Select bits (0=TMR3 contents are captured on captured event)
	IC2CONbits.ICSIDL =0;    			// Input Capture Module Stop in Idle Control(0=Input capture module will continue to operate in CPU Idle mode)
	IPC1bits.IC2IP        = 5;	
	IFS0bits.IC2IF        = 0;       			// Input Capture Channel 2 Interrupt Flag Status )0=Interrupt bit is cleared
	IEC0bits.IC2IE        = 1;     			// Input Capture Channel 2 Interrupt Enable bit (1 = Interrupt request enabled) 
	
}

/***************** ISR function ***********************/
void __attribute__((__interrupt__,no_auto_psv)) _IC2Interrupt(void)
{
	timePeriod        =IC2BUF;	
	T3CONbits.TON	= OFF;							// disable timer3
	TMR3		= 0X0000;						// TIMER3 REGISTER
	T3CONbits.TON	= ON;							// enable timer3
	count++;
	if(count == 2)
	{			
		timePeriod = current_value; 
		freq = (float)(8000000/timePeriod);			// 8Mhz is my operating frequency
		printf("freq =%f\n",(double)freq);	
		count = 0;
	}
	IFS0bits.IC2IF= 0; //Clear bit IC1IF (IFS<2>)

}


/************************* Timer3 init funct ***************************/
void timer_init(void)
{
 
	T3CON			= 0;					//desabling timer3
	TMR3			= 0X0000;				// TIMER3 REGISTER
	PR3			        = 0xffff;				// time period  maximum value 
	T3CONbits.TSIDL	= 0;					// configuring timer3
	T3CONbits.TCKPS	= 0b00;	                 	// 1:1 prescaler						
	IFS0bits.T3IF		= 0;					// clear interrupt flag 
	IPC1bits.T3IP		= 7;					// set interrupt priority
	IEC0bits.T3IE		= 1;					// interrupt enable
	T3CONbits.TON		= ON;				// enable timer3
	
	
}


void __attribute__((__interrupt__,no_auto_psv)) _T3Interrupt(void)
{
	IFS0bits.T3IF	= 0;
}

From this Code i'm able to read the higher frequencys. when ever i'm trying to read low frequencys (1Hhz - 1Khz) i'm getting random counter values.

I have given 65535 as timer3 period value.

Regards
Sai
 

Hi,

i see some problems with your code:

1) setting the counter value to zero within an ISR causes some timing errors: Your frequency mesurement will have fluctuations. Especially when other ISRs are running.

2) 8MHz, prescaler = 1: obviously the counter will overflow as soon as the time from one event to the next is 65536/8000000 = 8.2ms.

3) "timePeriod = current_value;" current_value is never defined nor updated.

4) the IC2interrupt ISR takes a lot of time. I think interrupts are disabled during this time. Causing a lot of trouble.


Klaus
 

Thanks KlausST,
So where I have to clear the counter value and can I set the timer value 8.2ms. Tell me the process,what i have to do.

Thanks and Regards,
M SAI KIRAN.
 

Hi,

don´t clear TMR3 at all.
--> Just subtract the previous_counter value from the actual counter value.
Timer_period = actual_capture_value - previous_capture_value
previous_capture_value = actual_capture_value

Instead of using TMR3 there should be a capture_register contaning the actual_capture_value. Read documentation about capture periferal.

****
If you need to measure more than 8.2ms then you have to set prescale to the desired value.

Klaus
 

Just I did above changes as u said.
Code:
void __attribute__((__interrupt__,no_auto_psv)) _IC2Interrupt(void)
{
	
	current_value=IC2BUF;	
	
	timePeriod = current_value - previous_value;
	previous_value=current_value; 
	freq = (float)(8000000/timePeriod);
		
	IFS0bits.IC2IF= 0; //Clear bit IC1IF (IFS<2>)

}

I/P O/P
22.2 Hz - 250 Hz
46.2 Hz - 196 Hz
40.8 Hz - 124 Hz
 
Last edited:

Hi,

obviously:

22.2Hz = 45.05 ms --> this is more than 8.2ms. --> overflow.

Use the correct prescaler!

Klaus
 

Hi,
How we know the correct prescaler value.
when 3.84 KHz = 460 ms then this is also more than 8.2 ms,but i am getting the exact Hz.
 

Hi,

when 3.84 KHz = 460 ms

???

3.84 kHz = 260us = 0.26ms --> smaller than 8.2ms --> no overflow --> correct value

Klaus
 

ok i miscalculated.The prescaler that i have to change in the Timer right.I tried with all the values of it.Still i am not getting.
 

Hi,

I don´t know your prescaler options. (And I don´t want to download and read the datasheet.) So you should provide the informations .. if you need help.

The math is simple: t_overflow = 65536 * prescaler / 8000000

And I don´t know your desired frequency range.. and the desired resolution or error. The complete specification is missing.

Klaus
 
TCKPS<1:0>: Timer Input Clock Prescale Select bits
11 = 1:256 prescale value
10 = 1:64 prescale value
01 = 1:8 prescale value
00 = 1:1 prescale value
These are my prescale values and my operating freq is 8 MHz.So kindly help me.

- - - Updated - - -

Thank You KlausST,
I understood the calculations and I did the changes and finally I am getting the values.


Thanks and Regards,
M SAI KIRAN.
 

Hi klausST,
I am busy since from 2 days.Thanks for the support and I got one more problem that is, I want to measure the frequencies from 1 Hz to 1 MHz.But I can measure only certain frequencies according to the prescale value and timer value.So I want to measure the required frequencies.How to change the prescale and timer values in run time for the possible frequencies.Is there any chance to measure continuously by setting prescale and timer values.

Thanks and Regards,
M SAI KIRAN.
 

Hi,

I want to measure the frequencies from 1 Hz to 1 MHz.
This is the specification of what you want. You should give those infirmations at the very first post.

1Hz to 1MHz is a ratio of 1:1000000. But your timer/capture most probably is only 16 bit wide.
(I assume this, because I don't know every periferal feature of every microcontroller...you should know)
16 bits means a ratio of 1:65536. This simply shows that it's impossible to achieve without additional effort.

Did you read about frequency measurement?
Then you should have find out, that:
* for higher frequencies it is best to count pulses fir a fixed, known time
* for lower frequencies it is best to measure the time from one edge to the next edge.

*****
Some examples:
Imagine you measure the time from one edge to the next edge. Counter frequency lets say is one MHz = 1 count every microsecond.
Now imagine the input frequency is 10kHz = 100us.
So the expected counter value is 100.
But expect an error of +/-1count. ..now follows error calculation:
With a count of 99 the calculated frequency is about 10,101Hz
With a count of 101 the calculated frequency is about 9,901Hz
You see the error is +/-1%, or the frequency resolution is about 100Hz.

Same counter, but 100Hz input frequency:
Expected counter value: 10,000. +/-1 count.
In short: error +/-0.01%, resolution 0.01Hz

A huge difference...
Now imagine what happens at input frequency of 1MHz, 600kHz, 300kHz, 200kHz....
Do you see the problem?

****
My recommendation:
If you want +/-1% precision you need to work with useful counter values of 100...65536.
This gives the limits of your measurement system. With a 1MHz clock the limits are:
15Hz...10kHz.
My conclusion is to change the prescaler. If possible divide by 16 (because of the 15Hz)
Then the conter frequency is 1MHz/16 and the resulting frequency range is 1Hz to 650Hz.

***
Now to the higher frequencies:
I said: count the pulses for a known time..
How to calculate the time?
The max expected frequency should not overflow the counter.
1MHz is the max frequency, 65535 is the max counter value.
So the max time is: 65.5ms.
To ease calculations i'd try with 10ms.
Range calculations: counter vales of 100 to 65535 give a frequency range of 10kHz to 6.5MHz.
6.5MHz probably is too high for the counter input, so it is limited by the microcontroller.

Now there is a gap between 650Hz and 10kHz.
What to do?
* decrease range
* decrease resolution
* additional software
* change hardware
...

Klaus
 
Last edited:

Hi,
I configured the Timer2 & Timer3 as a single 32 bit Timer as per the data sheet.In this Time2 contains 16 LSB values and Timer3 contains 16 MSB vlaues.So,as per 32 bit timer I think I can measure the frequencies from 1 Hz to 1 MHz.But Input capture buffer is 16 bit that means it can only capture the lsb of timer.If it is happen the timer will overflow.So how to capture the both lsb and msb values of a timer by using 16 bit input capture buffer.

Thanks and Regards,
M SAI KIRAN.
 

Hi,

you are using 32 bit timer.. you never mentioned this before.

**
I´m a bit confused.
I assume you have combined 16 bit timer2 and 16 bit timer3 to a 32 bit timer. Is this correct?

***
If timer3 contains the 16 bit MSB, then on capture_interrupt just read timer3 value per software.

There is a little change, that the timer2 overflows between capture_event and software read of timer3 value. Then the value of timer3 may be one count too high.
***

Is it possible to trigger the capture event on both timers at the same time?

Klaus
 

Hi,
After the discussion with you,I checked for 32 bit timer and then I configured the timer 2 and timer 3 as a 32 bit timer.My timer configuration is shown in below.
Code:
void timer_init(void)
{
 	T2CON				=0;							//disable Timer2
 	TMR2				=0x0000;					//Timer2 reg
 	PR2					=0xffff;						//PR reg of Timer2
 	T2CONbits.TSIDL	= 0;							// configuring timer3
	T2CONbits.TCKPS	= 0b10;	                 			// 1:64 prescaler	
	T2CONbits.T32		= 1;							//Timer2 & Timer3 Configured as 32-bit Timer	
//	T3CON				= 0;							//desabling timer3
	TMR3				= 0X0000;					// TIMER3 REGISTER
	PR3					= _t3_time;					// time period
//	T3CONbits.TSIDL	= 0;							// configuring timer3
//	T3CONbits.TCKPS	= 0b10;	                 			// 1:641 prescaler						
	IFS0bits.T3IF			= 0;							// clear interrupt flag 
	IPC1bits.T3IP		= 7;							// set interrupt priority
	IEC0bits.T3IE		= 1;							// interrupt enable
	T2CONbits.TON		= ON;						// enable timer2
//	T3CONbits.TON		= ON;						// enable timer3
	printf("Timer ready\n");
}

With this configuration and buffer values, I can read the frequencies like 15 Hz to 4 KHz. I set the prescale value as 1:64 bit.

Thanks and Regards,
M SAI KIRAN.
 

Hi,

I´m not familiar with your microcontroller, so the values don´t say much to me.
Maybe another member can verify your setting.

****
Now with the 32 bit option:
Use prescaler 1:1.

and calculate with the 32 bit values.

What´s the result?

***
My expectations:
Prescaler 1:1: Counter clock = 8MHz.

max. frequency for 1% precision: 8MHz / 100 = 80kHz. up to 800kHz with 10% precision.

lowest possible frequency 8MHz / 2^32 = 0.002 Hz

Klaus
 

Hi,
I set the timer as 16 bit and prescaler is 1:256 and I can't get the 100% accuracy in frequncy.I got the difference like 0.4 to 0.6 Hz.So,Is there any chance to get 100% accuracy. Suggest to me.

Thanks and Regards,
M SAI KIRAN.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top