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

Little help needed for frequency meter with CCP

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



Joined: 24 Nov 2010
Posts: 19

View user's profile Send private message

Little help needed for frequency meter with CCP
PostPosted: Fri Jul 19, 2013 11:21 am     Reply with quote

I have a simple frequency meter adapted by the example provided in this thread (by PCM programmer) and it works great.
http://www.ccsinfo.com/forum/viewtopic.php?t=41172&highlight=freq

However I have other stuff running in the same PIC and disabling global INT causes problem to other function. Is there any alternative to that?
Thanks

Code:

while(1)
  {
   disable_interrupts(GLOBAL);   //<------ causes problem
   current_ccp_delta = isr_ccp_delta;
   enable_interrupts(GLOBAL);
   
   frequency = (int16)((5000000L/8) / current_ccp_delta);

   printf(lcd_putc,"F: %5lu ", frequency);

   delay_ms(500);
  }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 19, 2013 11:56 am     Reply with quote

If you're running a 16F PIC at 20 MHz, which is the setup used in that link,
those 3 lines will disable global interrupts for only 2 usec at most.
What is the rest of your code doing, so it will be hurt by a 2 usec latency
possibly added to some other interrupts ?

What's your PIC and compiler version and your oscillator frequency ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Fri Jul 19, 2013 3:02 pm     Reply with quote

There is an alternative though:
Code:

//Instead of
   disable_interrupts(GLOBAL);   //<------ causes problem
   current_ccp_delta = isr_ccp_delta;
   enable_interrupts(GLOBAL);
//use
   do
   {
       current_ccp_delta = isr_ccp_delta;
   while (current_ccp_delta != isr_ccp_delta);


This will force the value to 're-read' until it does not update during the read.

However It is very rare for such a short disable to cause problems.

Best Wishes
leaveme



Joined: 24 Nov 2010
Posts: 19

View user's profile Send private message

PostPosted: Fri Jul 19, 2013 11:03 pm     Reply with quote

It is 18F452 with 8M oscillator.

Code:

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
...
...
freq = (int16)(250000L + (current_ccp_delta >>1) / current_ccp_delta);


There is phase control for motor control. I have random jerk (one or two times in 5 minutes) in motor speed. After several experiments, it is identified that disabling global INT disturbs other INT's.

@Ttelmah:
Jerk seems gone with your solution. I haven't noticed it within last 10 minutes. However frequency count is not correct now. My generator is tuned for 2000Hz. But the count fluctuates from 1999...2001. Though it is steady 2000 with disabled global int.
Any other thoughts...?
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Sat Jul 20, 2013 4:45 am     Reply with quote

The count should fluctuate by a count!....
If it doesn't, then the sampling would have to be completely synchronous to the incoming clock....
Draw yourself a short section of 'square wave', on graph paper, and cut a mask corresponding to a 'sample interval'. Try putting the mask over the wave. Will you always get the same count?....
It's sounding suspiciously as if your loop time to the point where the interrupts are disabled, may be close to exactly the same as the interval between some interrupt event, so disabling the interrupts serves to 'synchronise' the loop to the event. Then I'd suspect this sync is lost every few seconds, resulting in the glitch you are seeing.

Best Wishes
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Jul 22, 2013 1:57 am     Reply with quote

leaveme wrote:
After several experiments, it is identified that disabling global INT disturbs other INT's.


There are two levels of interrupt mask. There are masks for each interrupt source - UART Rx, I2C, etc., and the global interrupt mask that affects ALL interrupt sources without altering the individual interrupt masks. So disabling int_global masks out all interrupt sources until its reenabled, disabling a single source just maks out that surce, and leaves the others able to generate interrupts. This is not something special to PICs, many procesors have two or more levels of interrupt control.

In general if interrupts are required in an application, global interrupts should only be disabled when absolutely neccesary and for the shortest time possible. Also, if a single interrupt source can be disabled its better than disabling all interrupts. For example a serial buffer access routine might well need to disable interrupts for that UART, but can leave other interrupt sources active. For simplicity, most example code will show global interrupts disabled, but that is not always the best for real applications.
temtronic



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

View user's profile Send private message

PostPosted: Mon Jul 22, 2013 5:15 am     Reply with quote

points to ponder..
from you post a bit back ..
"My generator is tuned for 2000Hz. But the count fluctuates from 1999...2001"

That is quite normal and should be expected.Any digital reading will be x+-1 count, so 2000+1=2001, 2000-1=1999.

Without knowing the details and spec of your 2000 generator, it can be 'off' by 1 Hz.Now it it's designed for say 2000.001 Hz, then it wouldn't be the source of error.

Digital display of data will alway be +-1 count,nature of the beast.Can be a rounding error as 2000 is not a 'nice' binary number.Try displaying the data as 'raw hex' and see what appears...


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