View previous topic :: View next topic |
Author |
Message |
leaveme
Joined: 24 Nov 2010 Posts: 19
|
Little help needed for frequency meter with CCP |
Posted: Fri Jul 19, 2013 11:21 am |
|
|
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
|
|
Posted: Fri Jul 19, 2013 11:56 am |
|
|
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: 19513
|
|
Posted: Fri Jul 19, 2013 3:02 pm |
|
|
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
|
|
Posted: Fri Jul 19, 2013 11:03 pm |
|
|
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: 19513
|
|
Posted: Sat Jul 20, 2013 4:45 am |
|
|
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
|
|
Posted: Mon Jul 22, 2013 1:57 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Jul 22, 2013 5:15 am |
|
|
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 |
|
|
|