View previous topic :: View next topic |
Author |
Message |
docp
Joined: 17 Nov 2011 Posts: 3
|
Code explanation |
Posted: Thu Nov 17, 2011 7:09 am |
|
|
I have been out of coding for some time and wanted to find out if someone can fully explain the code below.
Code: |
#INT_TIMER1
void TIMER1_isr(void)
{
++overflow_count;
}
#INT_CCP1
void CCP1_isr(void)
{
end_time = (int32)CCP_1;
period = ((int32)0x1000 * (int32)overflow_count) - (int32)start_time + (int32)end_time;
freq = (int32)1/period;
start_time = end_time;
overflow_count = 0;
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Thu Nov 17, 2011 9:16 am |
|
|
It is just extending the size of the counter.
The CCP, records in hardware an INT16 count of when events happen based on a timer. Here the CCP is being used to measure an interval between 'start_time', and 'end_time'. However what happens if this interval is longer than int16 counts?.
So the answer is to extend the counter. A separate int16 counter 'overflow_count', is being maintained, which increments whenever the timer overflows. Then the 32 bit counter, is 16bits of 'overflow_count', catenated to 16bits from the CCP. The maths moves this 16bit word up to the top 16bits in a 32bit value, adds it to 'end_time', and subtracts the 'start_time' (remember reversing the order of an addition does not matter).
Best Wishes |
|
|
docp
Joined: 17 Nov 2011 Posts: 3
|
|
Posted: Fri Nov 18, 2011 12:03 am |
|
|
Many thanks.
I am trying to find out this part particularly,
Code: |
period = ((int32)0x1000 * (int32)overflow_count) - (int32)start_time + (int32)end_time; |
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Nov 18, 2011 2:19 am |
|
|
docp wrote: |
I am trying to find out this part particularly,
Code: |
period = ((int32)0x1000 * (int32)overflow_count) - (int32)start_time + (int32)end_time; |
|
Ttelmah said it:
Quote: |
The maths moves this 16bit word up to the top 16bits in a 32bit value, adds it to 'end_time', and subtracts the 'start_time' (remember reversing the order of an addition does not matter).
|
That code could also have been written:
Code: |
period = ((int32)overflow_count << 16) + end_time - start_time; |
Its the same thing as the original code, without the paranoid casts (which confuse the code) and doing the sums in a different order, as the original was perhaps somewhat peculiar doing it another way round for no gain, and simply adding to a code reader's confusion. All its doing is using timer 1 and CCP1 as a long counter: timer 1 is counts the overflows of CCP1.
What's causing the confusion? The C, the maths, or the use of hardware?
RF Developer |
|
|
docp
Joined: 17 Nov 2011 Posts: 3
|
|
Posted: Fri Nov 18, 2011 2:35 am |
|
|
Quote: |
What's causing the confusion? The C, the maths, or the use of hardware?
RF Developer |
I just wanted some more clarification of that line of code, I see that you explained there is a shift of the overflow_count |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Nov 18, 2011 3:23 am |
|
|
Note that code should be:
Code: |
period = ((int32)overflow_count << 12) + end_time - start_time; |
The original code, as presented to us, multiplied by 0x1000, which is a *12* bit shift, not a 16 bit shift which would be * 0x10000.
The CCS compiler is probably clever enough to know to implement 0x1000 * overflow_count as a shift. If not then the code will be very inefficient as we ll as unclear as it will implement a full on 32 bit multiply instead of a shft.
I'm not sure if the original code is correct, i.e. whether it should have been 0x10000 or 0x1000 as written. I've not used the CCPs much.
RF Developer |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Fri Nov 18, 2011 3:33 am |
|
|
Yes, to both parts from RF_Developer:
1) The compiler is smart enough to implement any constant binary multiplication, as a shift.
2) The original code is wrong. The CCP records a 16bit timer value. I'd suspect a 0 has been lost....
Best Wishes |
|
|
|