View previous topic :: View next topic |
Author |
Message |
young
Joined: 24 Jun 2004 Posts: 285
|
how to measure a 6600hz signal? |
Posted: Wed Dec 01, 2004 6:02 pm |
|
|
I used the following program to measure a signal range from 6300-6800hz. however, my output is always like this, with some occasional change even when I changed the frequency? axccording to timer1 ticks, it should be around 579-597
what is the problem?
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 282\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
\0A131 163\0D
Code: |
#if defined(__PCM__)
#include <16F76.h>
#include <stdio.h>
#fuses XT,WDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400, parity=N, xmit=PIN_C6, rcv=PIN_C7)
//for frequency
int overflow_count;
unsigned int32 start_time, end_time;
int32 pulse_ticks;
#int_TIMER1
TIMER1_isr()
{
++overflow_count; //increment whenever an overflow occurs;
}
#int_CCP1
CCP1_isr()
{
end_time=get_timer1(); //read captured timer ticks
pulse_ticks=(0x10000*overflow_count)-start_time+end_time;
start_time=end_time;
overflow_count=0; //clear overflow counts
}
void main()
{
setup_port_a(AN0_AN1_AN3);
setup_adc( ADC_CLOCK_INTERNAL );
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_CCP1);
enable_interrupts(global);
while(1)
{
set_adc_channel( 0 );
delay_us(50);
temperature = Read_ADC();
printf("%u %lu\r\n",temperature, pulse_ticks);
delay_ms(150);
}
}
|
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Dec 01, 2004 6:59 pm |
|
|
If you are using the capture module, why not use the CCPR1 value instead of the timer1 value? That is what its purpose is for. It also negates the interrupt latency. I suspect you real problem is the fact that overflow_count is 8 bits. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Wed Dec 01, 2004 7:35 pm |
|
|
thank you mark:
You are right, I changed get_timer1() into CCP_1 and it seems it is make some changes when the frequency. Do you think I should use a high frequency crystal to increase the resolution? |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Wed Dec 01, 2004 7:42 pm |
|
|
In my hand, I have a 20mhz crystal, I am thinking to try it, but since this is a four pin crystal, I do not know how to connecte it. I search the web, I could not find the datasheet. could you help me with this also?
and also do you think, the timer1 interrupt would affect stable rs232 communication?
Thanks a lot. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Wed Dec 01, 2004 7:48 pm |
|
|
What are all the markings on the "crystal" Is it a flat square package with a pin under each corner |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Dec 02, 2004 7:33 am |
|
|
Quote: | What are all the markings on the "crystal" Is it a flat square package with a pin under each corner |
yes, it is a flat square crystal with four pins, on the surface of the crystal, it is XO-543BE
20.000M
Dale 0428H |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Dec 02, 2004 8:36 am |
|
|
This doesn't look like a resolution or crystal frequency problem to me. You should be able to read consistently +/- 1 count. Since you output is always less than 0x10000 does this mean overflow_count is always zero? Try:
Code: |
pulse_ticks=0x80000+(0x10000*overflow_count)-start_time+end_time;
|
and see if you get the same result offset by 0x80000. Maybe zero-start_time is causing grief. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 02, 2004 8:57 am |
|
|
Quote: | axccording to timer1 ticks, it should be around 579-597 |
Not sure how you figured this.
(4000000/4)/6300 = 158
(4000000/4)/6800 = 147
Try this
Code: |
#if defined(__PCM__)
#include <16F76.h>
#include <stdio.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400, parity=N, xmit=PIN_C6, rcv=PIN_C7)
//for frequency
unsigned int16 lastvalue, pulse_ticks;
int1 GotValue = 0;
#int_CCP1
CCP1_isr()
{
GotValue = 1;
pulse_ticks = CCPR1 - lastvalue;
lastvalue = CCPR1;
}
void main()
{
setup_port_a(AN0_AN1_AN3);
setup_adc( ADC_CLOCK_INTERNAL );
setup_ccp1(CCP_CAPTURE_RE);
lastvalue = 0;
enable_interrupts(INT_CCP1);
enable_interrupts(global);
while(1)
{
if (GotValue)
{
GotValue = 0;
printf("Pulse Width - %lu\r\n", pulse_ticks);
}
}
}
|
|
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Dec 02, 2004 9:26 am |
|
|
What I am thinking is like this:
for a 4mHz crystal, Timer 1 ticks frequency will be 1mhz which is 1/4 of the crystal frequency. so the timer 1 will ticks /1m=1 micro second per ticks.
for a signal as 6600hz, it will be 1/6600hz=151 micro second, so the frequency read will be around 151, what my current output from the terminal is around 142-151. I think this is right.
However, if I have a crystal frequency higher than 4mhz, for example, 40MHz, the timer1 ticks 0.1 micro second per tick. so the frequency will get reading as 10 times higher than 151, it will be 1510, so what ever frequency, the reading will be 10 times higher. so for a range of frequency of 6300-6800khz frequency at 4mhz it will be get reading of (147-158), at 40mhz it will get reading at (1470-1580);
This is why I am think the crystal frequency is critical.
Please correct if I am wrong. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Dec 02, 2004 9:30 am |
|
|
Mark:
you are right, I corrected in my last post, do you agree that if I have a high speed crystal, I could get higher resolution when the signal frequency various. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 02, 2004 9:41 am |
|
|
You are correct but I don't think there are any 16's capable of 40MHz. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Dec 02, 2004 9:43 am |
|
|
Thank you mark:
What you mean 16's, I am ordering a 20mhz crystal angway, and currently, I have a Dale 20Mhz crystal, I do not know how to wire it to the microchip. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 02, 2004 9:57 am |
|
|
PIC10,PIC12, PIC16, PIC18...
16's mean PIC16F family. You example used 40MHz and you are using a PIC16 which isn't capable of 40MHz. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Dec 02, 2004 9:58 am |
|
|
Quote: | What you mean 16's, |
He meant the PIC16 series of processors. There are currently no PIC16 processors running above 20MHz (as far as I know).
Quote: | I have a Dale 20Mhz crystal, I do not know how to wire it to the microchip. |
Two minutes of Google gave me:
http://www.vishay.com/docs/35038/xo543.pdf
It took me longer to write this message than than it would have taken you to try google yourself.... |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 02, 2004 10:05 am |
|
|
Quote: | Two minutes of Google gave me:
|
Come on now, 2 minutes! Aren't you being conservation More like 20 seconds But seriously really easy to find. That's why I am selective about some posts. People do have to do some of the work! |
|
|
|