View previous topic :: View next topic |
Author |
Message |
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
how to measure frequency for fixed period? |
Posted: Wed May 15, 2013 2:50 am |
|
|
I'm using PIC18F2520. I want to measure the number of rising edges occurred in a specific period of time(say about 100msec).
In the main loop, i have configured CCP1 as rising edge. But i don't know how to count the rising pulses occured.
Please help!
Thanks in advance. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19590
|
|
Posted: Wed May 15, 2013 3:47 am |
|
|
Code: |
int16 count;
CCP_1=0; //reset the CCP counter
//Now wait for your time period
delay_ms(100); //Or use whatever other form of delay you want
count=CCP_1;
//count is now the number of edges seen by CCP1 in the period.
|
It really is that simple!....
Best Wishes |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
|
Posted: Wed May 15, 2013 4:36 am |
|
|
It looks simple. But when i implement in my program, it is showing some other values which are not related to the values calculated. say for example, from function generator, I'm producing the 1Khz and i fed it to CCP1. For 100ms, it captures the CCP1 value and the display shows 100. But it shows, some random values and keeps changing. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 15, 2013 7:00 am |
|
|
Several things:-
1) What does your signal generator output look like?
2) Is generator signal a nice rail to rail square wave?
3) What sort of other values are you getting?
4) What are the "random" values?
Mike |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed May 15, 2013 7:19 am |
|
|
post your program -
with the schematic for your circuit:
then maybe we can see where your problem lies |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 15, 2013 4:09 pm |
|
|
Why does this look very much like the thread you ran in April this year?
Mike |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 15, 2013 4:15 pm |
|
|
In addition to Mike's comments about your input signal characteristics,
there are software filters in the forum archives that allow you to remove
or reduce the effects of noise in your samples. Search for:
and
Remember to set it to: Search for All Terms
Search page:
http://www.ccsinfo.com/forum/search.php |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
|
Posted: Wed May 15, 2013 11:11 pm |
|
|
Quote: | Why does this look very much like the thread you ran in April this year? |
Yes mike. It is similar to the post which i created a thread last month.
But the intention was quite different,
I was reading some microchip notes for frequency measurement and in a note #AN895, they have given FIXED TIME METHOD and FIXED CYCLE METHOD. Now I'm trying FIXED TIME METHOD. In that, they have given "counting the number of pulses within a specific time window, such as
100 ms". But i don't know how to count the pulses for the time period 100ms. That's why i have created a thread.
Sorry If it's not allowed to create a thread.
I can create the delay for 100ms with timer. But i'm feeling difficult how to count the rising edges of pulse during that period.
This is the code I'm using now,
Code: | #include "18f2520.h"
#include "f2420_regs.h"
#fuses XT,NOWDT,PROTECT,NOLVP,CPB
#use delay(clock=4000000)
#define RS PIN_A2
#define EN PIN_A1
void lcd_init();
void lcd_cmd(unsigned char);
void lcd_data(unsigned char);
int16 current_ccp_value;
int16 frequency;
void timer_ccp_init();
int16 read_frequency();
int16 current_ccp;
#int_ccp1
void ccp1_isr(void)
{
CCP_1 = 0;
delay_ms(100);
current_ccp = CCP_1; // Read the 16-bit hardware CCP1 register
}
void main()
{
TRISB = 0x00;
PORTB = 0;
TRISC = 0b01101111; // configure C4, C7 as outputs and rest as inputs
PORTC = 0; // configure PORT C as low
ADON = 0; // disables A/D module.
lcd_init();
timer_ccp_init(); // Call timer_ccp_init function
delay_ms(150);
while(1)
{
read_frequency();
lcd_cmd(0x80);
printf(lcd_data,"%6lu Hz ", frequency);
delay_ms(500);
}
}
void timer_ccp_init()
{
set_timer1(0); // Timer value to 0
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer1 internal & 1:1 Prescaler
setup_ccp1(CCP_CAPTURE_RE); // Looks for Rising edge
clear_interrupt(INT_CCP1); // disables the CCP1 interrupt
enable_interrupts(INT_CCP1); // enables the CCP1 Interupt
enable_interrupts(GLOBAL); // Enables global interrupt
}
int16 read_frequency()
{
enable_interrupts(GLOBAL);
current_ccp_value = current_ccp; // copy the value in isr_ccp_value to current_ccp_value
disable_interrupts(GLOBAL);
frequency = (int16)((current_ccp_value));
return frequency;
}
void lcd_init()
{
lcd_cmd(0x30); // Configure the LCD in 8-bit mode, 1 line and 5x7 font
lcd_cmd(0x0c); // display on and cursor off
lcd_cmd(0x01); // clear display screen
lcd_cmd(0x06); // increment cursor
lcd_cmd(0x80); // set cursor to 1st line
}
void lcd_cmd(unsigned char c)
{
output_b(c);
output_low(RS);
output_high(EN);
delay_ms(15);
output_low(EN);
}
void lcd_data(unsigned char z)
{
output_b(z);
output_high(RS);
output_high(EN);
delay_ms(15);
output_low(EN);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19590
|
|
Posted: Thu May 16, 2013 2:48 am |
|
|
There are several things massively wrong.....
First, you are not using fast_io, so as soon as you execute:
PORTC = 0;
Your TRIS setting on the previous line is being overridden.
Then you are doing some really odd things with interrupts. Exactly the opposite of what is needed when you read the value. You should either disable the interrupt during the read, and immediately re-enable it afterwards, or use the read and test approach.
Then you have major problems because of using delays inside an interrupt. Means interrupts will be disabled everywhere else using delays.
Finally though the big one. Your approach is completely wrong. The CCP register records the value in the timer register when an 'event' occurs. You are configuring the timer to count using the internal clock, so instead of counting pulses, you are counting the clocks on timer1, that occur between successive edges of the input. To use the CCP to count an external clock over a time, you need to be setting timer1 up to be running off this clock. Then you need to setup a trigger coming from a 1/10th second source, to 'fire' the CCP. You then delay for the same or fractionally longer time interval, and read the CCP register which then contains the count recorded by timer1. The CCP itself does not count, it _records_ the count in timer1 (or 3). It is the timer that needs to be counting your clock....
Best Wishes |
|
|
|