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

CCP / 24 bit timer / 1hz to 150 hz range
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Wed Jan 02, 2008 2:29 am     Reply with quote

I will investigate further on this tomorrow too, i will have access to a scope.

Maybe (the problem) it's just fan signal related. We'll see!


Laurent
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Wed Jan 02, 2008 1:26 pm     Reply with quote

Hi,

I have some good result on the signal side here's the screenshot of the ccp pin (with the 5v pull-up)

Note: the probe was set to X1 instead of X10 , i didnt make the change in the scope setting ,, so its 5V per division instead of 50V as seen on the screenshot.

As you can see the CCP precision is very good!



Code:

95 Hz  96 Hz  95 Hz  95 Hz  95 Hz  96 Hz  0 Hz  95 Hz  95 Hz  96 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  0 Hz  95 Hz  95 Hz  96 Hz  95 Hz  95 Hz  95 Hz  96 Hz
96 Hz  95 Hz  95 Hz  95 Hz  96 Hz  96 Hz  0 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  96 Hz  95 Hz  95 Hz  0 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  94 Hz  95 Hz
95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  0 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  94 Hz  95 Hz  95 Hz  95 Hz  96 Hz  96 Hz  95 Hz  95 Hz 
95 Hz  0 Hz  95 Hz  96 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  96 Hz  95 Hz  95 Hz  95 Hz  95 Hz  0 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz 
95 Hz  0 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  96 Hz  95 Hz  95 Hz  0 Hz    95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz  95 Hz


If you pay attention to the terminal output you can see that the 0hz value always happen at the same moment (at 9 sec interval followed by a 14 sec interval and vice-versa ....1000 ms per reading)

Timer overflow problem ?

Give your opinions about that Smile

thank you!

Laurent
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 03, 2008 2:37 am     Reply with quote

I don't have any time to work on this until Sunday. I just don't.
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Thu Jan 03, 2008 4:04 am     Reply with quote

Dear PCM Programmer,

Take your time! You know, it's already nice that you have taken the time to help me since my first post.

I'm aware that most people on this board do electronics as a hobby when they have time to (including me).

I don't want to rush anybody ... but i have to admit it ,,, that it would be awesome if a fix could be found... I trying as most of my knowledge about CCP know. I have to do trials and errors!

Have a nice day! Smile

Laurent
deepakomanna



Joined: 06 Mar 2007
Posts: 92
Location: Pune,India

View user's profile Send private message AIM Address Yahoo Messenger

how to calculate frequency....
PostPosted: Fri Jan 04, 2008 4:09 am     Reply with quote

Dear sir,
I gone through your code but one line not undestand.
Quote:

g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);

Quote:
frequency = (int16)((12000000L + (current_ccp_delta >> 1)) /
current_ccp_delta);

1)How you calculate "0x1000000" value ?
2) ((12000000L + (current_ccp_delta >> 1)) why to shift right ?

In my application i am using external crystal of 32.768khz with prescaler 1.So what value should i have to put there then only i get exact frequency.
_________________
Thank You,
With Best Regards,
Deepak.
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Fri Jan 04, 2008 7:32 am     Reply with quote

>>1)How you calculate "0x1000000" value ?

It was already there never touched this...

>>2) ((12000000L + (current_ccp_delta >> 1)) why to shift right ?

I dont know really , i'm new to CCP.

But ...for the correct equation are you running the pic @ 32.768 khz or the timer1 is running at this speed ?

If pic clock = 32.768 khz then timer1 would be running at 8.192khz (clock div by 4) so.... change it to : ((8192L + (current_ccp_delta >> 1))

or if timer1 external clock = 32.768 then ((32768L + (current_ccp_delta >> 1))

in overall its ((XL / Y+ (current_ccp_delta >> 1)

X= timer1 freq
Y = your prescaler but since your have a prescaler of 1 dont put it

i hope i have helped you !

laurent
deepakomanna



Joined: 06 Mar 2007
Posts: 92
Location: Pune,India

View user's profile Send private message AIM Address Yahoo Messenger

how to calculate frequency....
PostPosted: Fri Jan 04, 2008 9:15 am     Reply with quote

i am using external clock == 32.768khz & prescaler == 1 only for timer1 & CPU is running on internal oscillator 8 MHz == i.e. 8 Mhz/4 == 2 Mhz.
I did freq. calculation by,
Quote:
isr_ccp_delta = current_ccp - old_ccp;

but not getting correct value. sometimes the current_ccp is more than old_ccp & sometimes less.so getting incorrect result.I checked this by using ICD 2 debugger.
Thanks for helping.
any further solution is appriciated
_________________
Thank You,
With Best Regards,
Deepak.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: how to calculate frequency....
PostPosted: Fri Jan 04, 2008 11:12 am     Reply with quote

deepakomanna wrote:

Code:
isr_ccp_delta = current_ccp - old_ccp;

...but not getting correct value. sometimes the current_ccp is more than old_ccp & sometimes less...


If Timer 1 is free-running, then it is expected to wrap around from 0xffff to 0x0000. So it is entirely normal that current_ccp sometimes appears less than old_ccp. However, the subtraction, isr_ccp_delta should always be a correct representation of the time elapsed between on capture event and the next - unless that time is so long that Timer 1 can wrap more than once from one even to the next.

Robert Scott
Real-Time Specialties
Embedded Systems Consultling
Kenny



Joined: 07 Sep 2003
Posts: 173
Location: Australia

View user's profile Send private message

PostPosted: Fri Jan 04, 2008 3:47 pm     Reply with quote

Yes, timer 1 is free-running and is not synchronised to the input signal in any way. The input signal edge being detected can occur at any time. The extended timer 1 will wrap from 0xFFFFFF to 0x000000 and continue.

0xFFFFFF is a large value (16,777,199), so at higher input frequencies (ie. low period) for most times the new captured value will be greater than the old one, but if the extended timer wraps before the new value is captured then the new value will be less than the old one. The chances of this occurring increase as the input frequency is lowered and the period increases.

PCM programmer explained why subtracting the two int32 values causes a problem - the extended timer wraps at the 24 bit boundary, not the 32 bit one.

A way to handle this is to test whether the new value is less than the old one, and if it is we know that wrapping has occurred. In that case the real delta value is from the old value to the 24 bit boundary, plus the new value.

An example, using hex. The delta value in a practical application will be much higher, but the example illustrates the method.
old = 0xFFFFFE
new = 0x000002

The delta value is 4 (0xFFFFFE to 0xFFFFFF to 0x000000 to 0x000001 to 0x000002)

current_ccp + (0x1000000 - old_ccp)
is 0x000002 + (0x1000000 - 0xFFFFFE)
= 4

A limitation of the code is that the delta value must be lower than the range of the extended timer. If this exceeded, then the test whether the new value is greater than the old one will foul up. If the shaft is nearly stopped this can occur. To get around this problem I wait for the flag to occur in a while loop, doing other things, and use another timer to do a timeout. There's probably a more elegant way to do it. My programming skills are limited.


Re external clock to timer 1, capture may not work (see data sheet for pic).

Re
frequency = (int16)((12000000L + (current_ccp_delta >> 1)) /
current_ccp_delta);
This is a rounding method where half the denominator is added to the numerator.
deepakomanna



Joined: 06 Mar 2007
Posts: 92
Location: Pune,India

View user's profile Send private message AIM Address Yahoo Messenger

how to calculate frequency....
PostPosted: Fri Jan 04, 2008 11:56 pm     Reply with quote

Thanks kenny for replying,
But still now i not understand how you calculate the value "0x1000000 ",in your post.

Quote:
current_ccp + (0x1000000 - old_ccp)
is 0x000002 + (0x1000000 - 0xFFFFFE)
= 4

In my application i am using external crystal(32.768 khz) for timer1 and by using CCP1 interrupt i am calculating frequency from 10 Hz to 700 Hz.& internal oscillator for CPU.My defined statements are,
Quote:
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
setup_oscillator(OSC_8MHZ | OSC_INTRC);

But i read the device data sheet in that they cleared,Page 179 (15.1.2 TIMER1 MODE SELECTION).
Quote:
Timer1 must be running in Timer mode, or Synchronized
Counter mode, for the CCP module to use the
capture feature. In Asynchronous Counter mode, the
capture operation may not work.

I checked T1CON register and the value is T1CON = 0x8F.
_________________
Thank You,
With Best Regards,
Deepak.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: how to calculate frequency....
PostPosted: Sat Jan 05, 2008 8:36 am     Reply with quote

The problem is that a 24-bit timer wraps at 0xffffff while a 32-bit integer wraps at 0xffffffff. Here is a simple solution. Do the subtraction on 24-bit capture values as follows:
Code:

delta_ccp = current_ccp - old_ccp;

Then sign-extend delta_cpp from 24-bits to 32-bits as follows:
Code:

if(bit_test(delta_ccp,23))
    delta_ccp |= 0xff000000;
else
    delta_ccp &= 0x00ffffff;

Or, if you are confident that the result should always be positive, skip the test and simply do:
Code:

delta_ccp &= 0x00ffffff;

Hopefully the compiler will optimize this last line into a single PIC instruction that just clears the high-byte of delta_ccp.

Robert Scott
Ypsilanti, Michigan
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Sat Jan 05, 2008 9:26 am     Reply with quote

Dear RLScott,

Does my problem (0hz reading) because my timer is not syncronised with the input?

Your replies are for deepakomanna problem but what modification i need to do to get it to work ?

Code:

*** Error 12 "main.c" Line 109(11,20): Undefined identifier   delta_ccp
*** Error 12 "main.c" Line 111(13,22): Undefined identifier   delta_ccp
*** Error 51 "main.c" Line 113(1,5): A numeric expression must appear here
      3 Errors,  0 Warnings.


Code:
g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);


If i have understood , i replace this original code line by :

Code:

delta_ccp = current_ccp - old_ccp;

if(bit_test(delta_ccp,23))
    delta_ccp |= 0xff000000;
else
    delta_ccp &= 0x00ffffff;
   
old_ccp = current_ccp;



then declare delta_ccp as a int32 in the header ?

Have a nice day!

Laurent
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Sat Jan 05, 2008 10:27 am     Reply with quote

Tryed at slower clock speed ,,

INTRC_OI @ 8mhz
Code:

frequency = (int16)((2000000L/8 + (current_ccp_delta >> 1)) / current_ccp_delta);


EXACTLY 60sec reading (1000 ms per value)...

Code:

86 Hz  86 Hz  85 Hz  85 Hz  86 Hz  85 Hz
85 Hz  85 Hz  86 Hz  85 Hz  85 Hz  86 Hz
86 Hz  85 Hz  86 Hz  86 Hz  85 Hz  86 Hz
86 Hz  85 Hz  86 Hz  86 Hz  86 Hz  86 Hz
86 Hz  86 Hz  86 Hz  86 Hz  86 Hz  86 Hz
86 Hz  86 Hz  86 Hz  85 Hz  86 Hz  86 Hz
86 Hz  85 Hz  86 Hz  86 Hz  86 Hz  86 Hz
86 Hz   0 Hz  86 Hz  85 Hz  86 Hz  85 Hz
86 Hz  86 Hz  86 Hz  86 Hz  86 Hz  86 Hz
86 Hz  86 Hz  85 Hz  86 Hz  85 Hz  86 Hz


HS, 12mhz straight no PLL
Code:

frequency = (int16)((3000000L/8 + (current_ccp_delta >> 1)) / current_ccp_delta);


EXACTLY 60sec reading (1000 ms per value)...

Code:

87 Hz  87 Hz  87 Hz  87 Hz  86 Hz  87 Hz 
87 Hz   0 Hz  87 Hz  87 Hz  87 Hz  86 Hz
86 Hz  87 Hz  87 Hz  87 Hz   0 Hz  87 Hz
86 Hz  86 Hz  87 Hz  87 Hz  86 Hz  86 Hz
87 Hz   0 Hz  86 Hz  86 Hz  87 Hz  87 Hz
86 Hz  86 Hz  87 Hz  86 Hz  87 Hz  87 Hz
87 Hz  86 Hz  86 Hz  87 Hz  87 Hz  86 Hz
87 Hz  87 Hz  86 Hz  86 Hz  87 Hz  86 Hz
87 Hz  87 Hz  86 Hz  86 Hz  87 Hz  86 Hz
86 Hz  87 Hz  86 Hz   0 Hz  87 Hz  87 Hz


HSPLL, 48mhz from 12mhz quartz , PLL3,CPUDIV1,
Code:

frequency = (int16)((12000000L/8 + (current_ccp_delta >> 1)) / current_ccp_delta);


EXACTLY 60sec reading (1000 ms per value)...

Code:


 0 Hz  87 Hz   0 Hz   0 Hz  87 Hz  87 Hz
87 Hz  87 Hz  87 Hz  87 Hz  87 Hz  87 Hz
87 Hz  87 Hz  87 Hz  87 Hz  87 Hz  86 Hz
87 Hz  86 Hz  87 Hz  87 Hz  87 Hz   0 Hz
 0 Hz  87 Hz   0 Hz   0 Hz   0 Hz   0 Hz
 0 Hz   0 Hz   0 Hz   0 Hz   0 Hz   0 Hz
 0 Hz  87 Hz  87 Hz   0 Hz   0 Hz  87 Hz
87 Hz  87 Hz  87 Hz  87 Hz  87 Hz  87 Hz
87 Hz  87 Hz  86 Hz  87 Hz  86 Hz  86 Hz
87 Hz  86 Hz  87 Hz  86 Hz  87 Hz   0 Hz


it's even better @8mhz but what cause the 0hz reading ??? if i increase the clock speed , its getting worse and worse...

Laurent
Kenny



Joined: 07 Sep 2003
Posts: 173
Location: Australia

View user's profile Send private message

Re: how to calculate frequency....
PostPosted: Sat Jan 05, 2008 2:54 pm     Reply with quote

deepakomanna wrote:
But still now i not understand how you calculate the value "0x1000000 ",in your post.


The 0x1000000 is a construct. With unsigned arithmetic can't subtract from 0, so instead subtract from one higher than 0xFFFFFF in the unsigned int32 range, which is 0x1000000.

Re timer 1 oscillator problem, bit 2 of T1CON needs to be clear to enable the sync circuit.
Try
setup_timer_1(T1_EXTERNAL_SYNC|T1_DIV_BY_1|T1_CLK_OUT);

Not sure why you are using the timer 1 oscillator though.
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Sun Jan 06, 2008 8:30 am     Reply with quote

Dear CCS members,

I have changed my pic18f2550 to an 2553 just to see,

and it's the same problem ... can't be a schematic problem ... i have looked with an oscilloscope and everything was fine ... see the image on the top of the topic...


Anyone ???

Have a nice day,

Laurent

Mtl,Quebec
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 Previous  1, 2, 3, 4, 5, 6  Next
Page 2 of 6

 
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