Oscillators/PCA/Timers/SMBus/UART/SPI
  PCA capture event while CCFn is pendig - what will happen to already captured value?

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   PCA capture event while CCFn is pendig - what will happen to already captured value?
jacobk
New Member
posted August 04, 2010 08:47 AM     Click Here to See the Profile for jacobk     Edit/Delete Message
Hallo everyone,

I am using the C0851F500 and want to measure time with the PCA.
The PCA operation is set to 'capture on positive edge' mode.

Does any of you know what will happen to a already captured PCA value if all of the following conditions are true:
- the corresponding interrupt has not been serviced yet and therefore CCFn is still set
- another positive edge occurs on CEXn

Will the value in PCA0CPn be preserved or overwritten with the new value?

Thanks in advance,
Jacob

IP: Logged

Scotty
Member
posted August 04, 2010 11:46 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi jacobk,

excerpt from datasheet:
27.3.1. Edge-triggered Capture Mode
In this mode, a valid transition on the CEXn pin causes the PCA to capture the value of the PCA counter/timer and load it into the corresponding module's 16-bit capture/compare register (PCA0CPLn and PCA0CPHn).
...
When a capture occurs, the Capture/Compare Flag (CCFn) in PCA0CN is set to logic 1.
...

From this description I'd say that the value is always captured and therefore overwrites the value in the PCA register.
This question could be also answered with "there is no hardware buffering implemented".

But, from your question I assume that you're experiencing some data loss with your current software. Or is there another reason for your question? If so, post your code and describe the hardware circuit and the input signals.

Generally, a ISR should be kept as short as possible. In best cases a ISR saves the data to a buffer and informs the main application about the new data. This ensures that each interrupt can be serviced.

Regards,

Scotty

IP: Logged

jacobk
New Member
posted August 05, 2010 11:38 AM     Click Here to See the Profile for jacobk     Edit/Delete Message
Thanks for your reply Scotty.

The reason for my question is that i DON'T wont each of the PCA CCFn interrupts to be serviced.

I try to explain why.

The timestamps i want to measure are used by a subroutine to control a dc motor speed. This subroutine is called from within Timer2_ISR which is serviced all 10ms. I don't need the timestamps to be measured all the time but rather two times between each Timer2_ISR.
I programmed the PCA0_ISR to mask its interrupt flag once it captured two timestamps. At the end of Timer2_ISR this flag is unmasked again.

Now we assume that a capture event occurs at the execution time of Timer2_ISR. Even though the CCFn interrupt is masked a value will be captured in PCA0CPn.
If this value would be overwritten at each capture event the motor speed should be calculated correctly.
But when i debugged the code i found some numerical distortions of the speed value appearing periodically. So i assume that the value will NOT be overwritten unless the CCFn flag is cleared by software.

I solved the problem by clearing the CCFn flag at the end of Timer2_ISR. No more distortions so far.

Nevertheless, i'm not sure a about this. I hoped that someone would know a document which is clear about that point.

Regards,
Jacob

[This message has been edited by jacobk (edited August 05, 2010).]

[This message has been edited by jacobk (edited August 05, 2010).]

IP: Logged

erikm
Member
posted August 05, 2010 12:25 PM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
within Timer2_ISR which is serviced all 10ms. I don't need the timestamps to be measured all the time but rather two times between each Timer2_ISR.
there may be something in your post I do not get, but the above seems to have an obvious answer: why not a counter in the Timer2_ISR.

Erik

IP: Logged

jacobk
New Member
posted August 05, 2010 01:45 PM     Click Here to See the Profile for jacobk     Edit/Delete Message
Hi Erik,

i don't see your point. Why should i use a counter in the Timer2_ISR? What should i count there except how often this ISR has been serviced?

Besides, my code is working now as i expect it to work. So the answer to my original question is no longer essential to complete my task.

But i don't like it not to be really sure about such fundamental questions.

Just in case, in my timezone we have 8:50pm right now. So don't wonder about my delays of posting.

Regards,
Jacob

[This message has been edited by jacobk (edited August 05, 2010).]

IP: Logged

erikm
Member
posted August 05, 2010 02:16 PM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
Jacob,

I don't see your point. Why should i use a counter in the Timer2_ISR? What should i count there except how often this ISR has been serviced?
because
I don't need the timestamps to be measured all the time but rather two times between each Timer2_ISR.

if (count)
{
count--
}
else
{
timestamp
count = 2
}

Erik

IP: Logged

jacobk
New Member
posted August 06, 2010 06:43 AM     Click Here to See the Profile for jacobk     Edit/Delete Message
Hi Erik,

from your code snippet i would say that in this way a "timestamp" would be captured every third Timer2 interrupt.

But with the term "timestamp" i was referring to a PCA counter value captured at a time when a positive edge is sensed on a CEXn pin. This signal comes from the dc-motor quadrature encoder and is asynchronous to the Timer2_ISR intervals.

I already solved that problem like i have described in my second post:
I programmed the PCA0_ISR to mask its interrupt flag once it captured two timestamps. At the end of Timer2_ISR this flag is unmasked again.
The number of captured PCA0 values (timestamps) are counted inside the PCA0_ISR. When the PCA0_ISR captured its second value it deactivates itself. The corresponding interrupt enable bit can be used as a semaphore inside the Timer2_ISR to test if two values were captured. If so, the difference of the two values can be calculated. This difference represents the speed of the motor. At the end of Timer2_ISR the PCA0_ISR is activated again.

Here some pseudo code:

main {
while(1) {
SLEEP_AND_WAKE_ON_INTERRUPT;
}
}

Timer2_ISR{
if (PCA0 interrupt is off) {
calc speed;
}
edgecount = 0;
activate PCA0 interrupt;
clear capture flag;
}

PCA0_ISR{
if (edgecount == 0) {
save first captured value;
}
if (edgecount == 1) {
save second captured value;
deactivate PCA0 interrupt;
}
edgecount++;
}


Interrupt execution time plan:

Timer2_ISR|.|-----|...............|-----|
..........|..............................
PCA0_ISR..|........|--|..|--|............
..........|------------------------------> t

[This message has been edited by jacobk (edited August 06, 2010).]

[This message has been edited by jacobk (edited August 06, 2010).]

[This message has been edited by jacobk (edited August 06, 2010).]

IP: Logged

erikm
Member
posted August 06, 2010 07:36 AM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
in a previous post: "there may be something in your post I do not get"
evidently so

Erik

"if I heard what you thought you said we would understand each other"

IP: Logged

All times are CT (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | MCU User Forum

Have you seen our MCU Knowledge Base?


Ultimate Bulletin Board 5.47b