PDA

View Full Version : Oscillators, counts, clock cycles, config settings ......& women



HankMcSpank
- 13th September 2010, 12:04
Ok, so I put in 'women' to shamfully get a few more 'curiousity' hits - lol.

Women are quite nice - I enjoy some aspects of them very much.

Ok, that's that bit covered off. To the oscillator related stuff.

In my cosy little noobesque world, I've until now being running nice copycat config settings with the internal oscillator @4Mhz. But alas, for my needs there wasn't enough resolution so I pushed th boat out & bought a 20Mhz cermaic resonator for the princely so of 20p (30c).

I'm using a 16f690 - so connected the resonator to pins 2 & 3.

Fine so what's the problem? Well, counting clock pulses is the problem....there doesn't seem to be enough of them!

I'm using a 1Khz signal to 'trigger' a comparator internally withing my PIC, this in turn generates a comparator interrupt, which I've setup to start Timer1 running.

When the next comparator trigger arrives (ie 1ms later for the 1khz signal I'm feeding into the comparator)...I store the timer1 count.

With me so far?

Ok, the count I'm getting is 2,500 (it's rock solid - that said if I change the input 'trigger' frequency the timer1 count moves, so this confirms the chain is all working !)

But with a 20Mhz clock, I should be getting a whole heap more 'clock counts' between the comparator firing off successive interrupts.

with a 1khz comparator input - by my calculations that should yield an interrupt every 1ms....so I worked out how many clocks there should be during that time (timer1 count). At 20Mhz there should be 20,000 rx'ed in 1ms.

But I'm only seeing 2,500?!!!

Now Jerson helpfully queried whether I had a prescaler set (x8 would tie up with what I'm seeing....I'm expecting the clock count to be 20,000, but I'm seeing 2,500) - I don't believe so.

So how do I get to the bottom of this discrepancy?

Is it a Osc config setting? (remember this is the first time I've used an External oSicllator - it's highly conceivable I've perhaps configured the PIC wrong). Here's my associated config (I use MPASM)....




@ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF

DEFINE OSC 20 ' set Oscillator at 20Mhz
OSCCON.0 = 0


Is it a problem with my approach?

Is it a problem with my maths?



As an aside, is there a prescribed method for confirming the clock is running at the frequency you want it to run at?!!!

Many thanks in anticipation!

Acetronics2
- 13th September 2010, 12:25
Hi, Hank

Let 's see ...

@ 20Mhz clock ( better say : Xtal ) ...

you have .200µs for a timer 1 without prescaler increment ... ( internal clock is 1/4 the Xtal Freq ... )

so, 1000/.200 = 5000 ... ( let's forget Interrupt duration for the moment )

if my math still " not so bad " ... :rolleyes:

now ... just a 1:2 ratio to dig out ...

So, IF you sure your Xtal is a 20 Mhz one ... :rolleyes:

only your settings ( full listing SVP !!! ) AND your interrupt stubb could enlight this 3rd millenium mystery ...

Alain

HankMcSpank
- 13th September 2010, 13:05
Hi Alain.... thanks for getting involved!



you have .200µs for a timer 1 without prescaler increment ... ( internal clock is 1/4 the Xtal Freq ... )


Aha [the sound of a small penny dropping on a hard surface]...how naive of me - I thought that for my 20p investment, I'd get a positive whizzy PIC...but now you're breaking the news to me that I'm actually only getting 5Mhz of 'doing stuff' speed?!

Damnit...I want my 20p back.

The full code/config will have to wait until tonight (I left it at home!)...so the universe will need to wait with baited breath for 6 hours or so before establishing where the other 2,500 'clock count' total @1khz went (my wife is presently checking behind the sofa)

To paraphrase Arnie "I'll be back"

Merci beaucoup

Acetronics2
- 13th September 2010, 14:19
but now you're breaking the news to me that I'm actually only getting 5Mhz of 'doing stuff' speed?!

Damnit...I want my 20p back.




yes ... you " only " *** laughing *** get 5 million ops a sec ... :rolleyes: What a pity ... isn't it ???

looking a bit further ... 16F devices generally can reach 32 Mhz , 16F193x are 32Mhz Nominal ... MalcC realized officially last week 64 Mhz with a 18F45xx ... ( 40 Mhz nominal ) and the new 18F2xK20 are 64Mhz Nominal ...

so, there's room to play somewhat ... before using higher range devices :D

BUT ... may be you simply could open your datasheed and see what the stuff explained in chapter 6 ( Gated Timer 1 W/ Comp2 ) can do for you ...


Alain

HankMcSpank
- 13th September 2010, 14:32
BUT ... may be you simply could open your datasheed and see what the stuff explained in chapter 6 ( Gated Timer 1 W/ Comp2 ) can do for you ...


Yeah I saw that feature & thought "cool, it's got a gate that I can use" - but I then read that part of the datasheet four or five times, & had to lay down in a darkened room for 2 hours, with a cold wet towel across my forehead.

In a few weeks it'll likely be a doddle to see what they're getting at (working on the principle that a few weeks ago, just getting the comparators working &/or DT's interrupts working...seemed like having to read the hubble space telescope service manual reflected in a mirror - whereas today they're a veritable breeze), but for now, I'll curl up in the foetal position & just be content with how far I'm pushing the McSpank envelope at present.


PS re 5 million instruction per second - lol, talk about value for money ....£1.50! (I could launch a lunar mission with less)

HankMcSpank
- 13th September 2010, 19:41
Ok, so it was like 2.00am this morning when I retired from this conundrum & I guess my mind was fogged this morning when I posted - the number I'm seeing is 4500 (not 2500). Here's what I'm seeing withrt comparator 'counts' when feeding a 1Khz signal in...

comp1=4500 comp2Time=489
comp1=4495 comp2Time=489
comp1=4499 comp2Time=490
comp1=4501 comp2Time=490
comp1=4498 comp2Time=486
comp1=4502 comp2Time=490
comp1=4497 comp2Time=487
...and so on.

Now in the light of your info Alain, I'm actually only looking for a count of 5000 (vs the 20,000 I'd erroneousy calculated @1khz incoming signal), this sheds new light on the situation.

I now think my Oscillator is working correctly at 20Mhz! (that's the good news bit)

But the bad news....my comparator1 count still has a 500 count shortfall.

I reckon the 500 'count' shortfall is due to the way I'm setting the comparators to count becuase if if you add the two together is as near as damint to 5,000, so there's an issue with the way I'm counting (or in other words my code sucks)

I want comparator1 to count the time between incoming signal 1khz signal 'cycles' (so, 5000 for 1khz input) & the second comparator to time how many clocks before a second lagging signal arrives....



@ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF

DEFINE OSC 20 ' set Oscillator at 4Mhz.
DEFINE NO_CLRWDT 1 ' PBP doesn't clear WDT automatically
DEFINE HSER_TXSTA 24h ' Enable transmit
DEFINE HSER_SPBRG 129 ' set USART to 9600 baud @20Mhz


'************************************************* **********************************************

'16F690 Pin Connections....
' PIN# NAME USE & CONNECTION
' 1 Vdd +5VDC power supply
TRISC.4 = 0 ' 6 RC4 C2OUT
TRISC.3 = 1 ' 7 RC3 C12IN3- (external comparator1 input)
TRISC.2 = 1 ' 14 RC2 C12IN2- (external comparator2 input)
TRISC.0 = 1 ' 16 RCO C2IN+
TRISA.2 = 0 ' 17 RA2 C1OUT
TRISA.1 = 1 ' 18 RA1 External VREF In.
TRISA.0 = 1 ' 19 RCO C1IN+
' 20 Vss Ground
'************************************************* *********************************
OSCCON.0 = %0001000
txsta = %10100100 'setup the tx register
RCSTA.7 = 1 ' Enable RB7 for TX USART
INTCON.0 = 0 ' clears the RABIF Flag (to 0), COULD be 1 on reset (unique to F690)
ANSEL = 0 'disable AtoD.
ANSELH = 0 'disable AtoD.

'Turn on & Set up Comparator 1
CM1CON0.7 = 1 'Comparator 1 on.
CM1CON0.6 = 0 'C1OUT POLARITY BIT
CM1CON0.5 = 1 '1 = C1OUT is present on the C1OUT pin (pin 17)
CM1CON0.4 = 1 'C1OUT logic - 0 is not inverted (1 for inverted)
CM1CON0.3 = 0 'unimplemented
CM1CON0.2 = 1 'Connect internally to the output of C1VREF (or 0 for the the associated comp in pin)
CM1CON0.1 = 1 'this bit with bit 1 set the external incoming pin - in this case c12in3- (pin 7)
CM1CON0.0 = 1 'this bit with bit 1 set the external incoming pin - in this case c12in3- (pin 7)

'Turn on & Set up Comparator 2
CM2CON0.7 = 1 'Comparator 2 on.
CM2CON0.6 = 0 'C1OUT POLARITY BIT
CM2CON0.5 = 1 '1 = C2OUT is present on the C2OUT pin (pin 6)
CM2CON0.4 = 1 'C1OUT logic is not inverted (1 for inverted)
CM2CON0.3 = 0 'unimplemented
CM2CON0.2 = 1 'Connect internally to the output of C1VREF (or 0 for the the associated comp in pin)
CM2CON0.1 = 1 'this bit with bit 1 set the external incoming pin - in this case c12in2- (pin 14)
CM2CON0.0 = 0 'this bit with bit 1 set the external incoming pin - in this case c12in2- (pin 14)


VRCON.7 = 1 'Comparator1 CV Ref enable bit
VRCON.6 = 1 'Comparator2 CV Ref enable bit
VRCON.5 = 0 'high or low range 0 = High Range, 1 = low range
VRCON.4 = 0 '0.6V Reference Enable bit ....0 is disabled
VRCON.3 = 0 'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
VRCON.2 = 1 'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
VRCON.1 = 1 'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
VRCON.0 = 1 'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC


Comp1Time var word ' used to amalgamate TMR1 High & Low Bytes.
Frequency var word 'used to convert the count to frequency.
Comp2Time VAR WORD
PHASE var word


' the following is pretty much a straight lift from the compiler manual (DIV32 section)
a Var Word
b Var Word
c Var Word
dummy Var Word
b = 10000
c = 5000


INCLUDE "DT_INTS-14.bas" ' Base Interrupt System PO90OOO9
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler CMP1_INT, _Comp1_Int, PBP, yes
INT_Handler CMP2_INT, _Comp2_Int, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
T1CON.0= 1 'start timer

@ INT_ENABLE CMP1_INT ; enable Comparator 1 interrupts

Comp1Time = 0 'clear down Comp1Time, prior to starting.
comp2Time = 0 'clear down Comp2Time, prior to starting
T1CON = %00001101

'Main body of Code********************************************** ***********************************************
Main:

HSEROUT ["comp1=",dec Comp1Time,9,"comp2Time=", dec comp2time, 13, 10]
PAUSE 500
goto Main
end
'Comparator1 Interrupt Handler+++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++

Comp1_Int:
@ INT_DISABLE CMP1_INT
Comp1Time.Lowbyte = TMR1L 'puts the timer's low byte in MyTime's lower 8 bits
Comp1Time.Highbyte = TMR1H 'puts the timer's high byte in MyTime's upper 8 bits
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
@ INT_ENABLE CMP2_INT
'Comp1Time =Comp1Time +4
'dummy = b * c '5,000,000
'frequency = div32 Comp1time
'frequency =frequency/2
'HSEROUT ["mytime = ", dec mytime,9, dec frequency/10,".",dec frequency//10,"Hz",13, 10]

@ INT_RETURN

Comp2_Int:
@ INT_DISABLE CMP2_INT
Comp2Time.Lowbyte = TMR1L 'puts the timer's low byte in MyTime's lower 8 bits
Comp2Time.Highbyte = TMR1H 'puts the timer's high byte in MyTime's upper 8 bits
'b = 50000
'c = 1000
'phase_shift = div32 Comp1time
'dummy = b * c '5,000,000
'Comp1Time = Comp1Time
'phase_shift = Comp2Time *10
'phase_shift = phase_shift/Comp1Time
'phase_shift = phase_shift*4
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
@ INT_ENABLE CMP1_INT
@ INT_RETURN


I reckon it's all to do with the first comparator interrupt being started when the program initially runs 'at a time unknown' in respect to the incoming signal. Comp1 interrupts are enabled at the top of the porgram - that could be midway through a cycle, then a leading edge from the incoming signal arrives at comparator 1 & the comparator1 handler self disables any further comparator1 interrupts.

I need a way of starting comparator1 interrupts synced to the actualy incoming signal.

hey...ho - one problem solved another one (which I thought I'd nailed) starts!


Many thanks anyway..... I'll get me coat.

Acetronics2
- 13th September 2010, 20:04
the number I'm seeing is 4500 (not 2500). Here's what I'm seeing withrt comparator 'counts' when feeding a 1Khz signal in...


Now in the light of your info Alain, I'm actually only looking for a count of 5000 (vs the 20,000 I'd erroneousy calculated @1khz incoming signal), this sheds new light on the situation.

.

Ok Hank ...

4500 looks fine ... and you won't get much better using such discrete interrupt.
remember ??? :


let's forget Interrupt duration for the moment

Aaaarghhhh ... time to care of it ...

PBP interrupt save and restore all the system vars ... and it takes TIME.
So, you have to compensate ...

or use TMR1 in " rolling mode " ...

Alain

HankMcSpank
- 13th September 2010, 22:49
Ok, I've now stripped both comparator interrupt handlers right back to the minimum - there's something very peculiar going on - which I don't just don't understand.

First here's a scope trace of what I'm feeding into the comparators...

green trace = comp1 input 1khz signal (the leading signal)
yellow trace = comp2 input 1khz signal (the lagging signal)

http://img714.imageshack.us/img714/9297/scopetrace.jpg (http://img714.imageshack.us/i/scopetrace.jpg/)

ok, when I enable just comp1 interrupts on their own,I get as near as damnit a count of 5,000 between comparator 1 interrupts (ie a perfect counting of clocks @1Khz).....


comp1=5002 comp2Time=0
comp1=5000 comp2Time=0
comp1=5001 comp2Time=0
comp1=5002 comp2Time=0
comp1=5002 comp2Time=0
comp1=5001 comp2Time=0


Here's the associated code snippets ...



@ INT_ENABLE CMP1_INT ; enable Comparator 1 interrupts
'@ INT_ENABLE CMP2_INT

Comp1_Int:
Comp1Time.Lowbyte = TMR1L +2 'Store away the timer1 count.
Comp1Time.Highbyte = TMR1H 'Store away the timer1 count.
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
@ INT_RETURN


Comp2_Int:
Comp2Time.Lowbyte = TMR1L 'puts the timer's low byte in MyTime's lower 8 bits
Comp2Time.Highbyte = TMR1H 'puts the timer's high byte in MyTime's upper 8 bits
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
@ INT_RETURN


*BUT*

when I then enable comp2 interrupts (by uncommenting the enable comp2 interrupt line above - also commenting out the TMR1H = 0 & TMRLl = 0 in the comp1 interrupt, so that the timer now resets in the comp2 handler), it all goes wonky....



comp1=2959 comp2Time=4999
comp1=2956 comp2Time=4999
comp1=2956 comp2Time=4993
comp1=2959 comp2Time=4999
comp1=2954 comp2Time=4994
comp1=2955 comp2Time=4995
comp1=2958 comp2Time=4994
comp1=2956 comp2Time=4996


So comp1 count should be stored...the timer contunes on

I can't really account for what's going on here - there's almost nothing inthose interrupt handlers. equally there's plenty of time between the two signals for both handlers to easily finsih what they need to do before the next comparator interrupt arrives.

Perplexed :confused:

Jerson
- 14th September 2010, 01:52
Hi Hank

The second comp int should not reset the timer to 0. Comp1 int is your reference point and you zero the timer in there. Comp2 int will not come if there is no comp1 signal. This is from your circuit.

So, if you see my previous postings on the other thread,
COMP1 int
read the timer (gets you frequency counts)
Timer Reset

COMP2 Int
read the timer (gets you phase counts)


These should be the only steps involved. I think you will be successful in this :)

Regards

HankMcSpank
- 14th September 2010, 09:58
BINGO! .....I've got it working at about 1.30am this morning shortly after making that last post

Jerson - many thanks ....re your post above - you were bang on the money.

In conclusion to brigng the thread back on topic, for anyone wanting a pointer wrt configuring their PIC to run on an external clock - well, for a 16f690 @20Mhzthese settings work for me....



@ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF

DEFINE OSC 20 ' set Oscillator at 20Mhz.
OSCCON.0 = %0001000


(for the above to work, you need to be using MPASM)

And if you're doing anything with timers/counting clocks, bear in mind what Alain said above ....ie that the number of clocks counted during your own particular timeframe will be the oscillator frequency divided by 4. (which caught me out nicely)


Many thanks to both Alain & Jerson for taking the time to help me out......you've made a happy man very old (or should that be the other way round?)

Got to start learning about LUTs & arrays now - there's no end to all this learning!

Jerson
- 14th September 2010, 10:26
Hehehe - I guess you saw the color red in that post ;)

Congratulations on a job well done.

HankMcSpank
- 14th September 2010, 23:58
Oh dear - I spoke to soon! :o (5 nights & counting for this seemingly simple task! Eek!)

by & large the overall process works, however.....

If I take the phase shift control of my all pass filter circuit down to as near as damnit zero degrees phase shift (ie no lag for the second signal feeding into comparator 2), then there ought to be almost a zero count when the second comparator interrupts, alas, in actual fact there appears to be count of about 325 for comparator2 in this scenario (@1khz). If I take the tst frequency down to 100Hz, I see a comparator2 count of a whopping 3000 (albeit comparator1 reads 50,000 in this scenarion - so it's pro rata)

this means @1khz, with that error I'm getting a phase shift of about 23 degrees being erroneouly calculated - ie 5000 (1st timer count) divided by 360 (degrees) muyltiplied by 325 (second timer count) - but I know for a fact there's actually no phase shift present at all (I can see this on my scope).

Now I know I'm relatively new to all this, but I can't help feeling there something going seriously wrong 'behind the scenes' (or a config register setting?).... my reasoning is that there's virtually no code for me to screw up with here!

here's my interrupt handler...



Comp1_Int:
Comp1Time.Lowbyte = TMR1L 'Store away the timer1 count
Comp1Time.Highbyte = TMR1H 'Store away the timer1 count.
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
@ INT_RETURN

Comp2_Int:
Comp2Time.Lowbyte = TMR1L 'Store away the timer1 count
Comp2Time.Highbyte = TMR1H 'Store away the timer1 count
@ INT_RETURN


Anyone got any ideas?!

Jerson
- 15th September 2010, 03:32
Hi Hank

Assuming the phase difference is near zero. There is still a finite amount of time it takes for Comp1Int to complete(CPU cycles) and Comp2Int to be services. It is possible you are seeing the interrupt latency values.

AFAIK there is no config register setting that should mess things up.

Regards

rsocor01
- 15th September 2010, 07:04
If I take the phase shift control of my all pass filter circuit down to as near as damnit zero degrees phase shift (ie no lag for the second signal feeding into comparator 2), then there ought to be almost a zero count when the second comparator interrupts,

Hi HankMcSpank,

I think that is a wrong assumption. If both triggering pulses for Comp1 and Comp2 are traveling at the same time (0 degrees phase diference) then by the time the Comp1_Int interrupt is finished, then the triggering part (rising or falling edge) of the Comp2 pulse has already being gone. So, the interrupt Comp2_Int has to wait for the next triggering event. This is pretty much what Jerson is trying to tell you in the previous post.

Now, if you are getting a reading of 325 for Comp2, that is a reading for 65 microsecs. So, having a period of 1 ms for your triggering pulses this means that all the interrupt latency values that Jerson is talking about are (1,000 uSecs - 65 uSecs) = 935 uSecs. This is assuming the next pulse is triggering Comp2. This latency value could be 935 uSecs or 1,935 uSecs or 2,935 uSecs or ....

Does anybody know how long the DT interrupts take to execute?

Robert

HankMcSpank
- 15th September 2010, 07:31
Thanks for both your comments - re latency of the interrupts.......remember, here that the comp1 count is rock solid....ie at 1khz into comparator1, I'm seeing a steady count of 5,000 (plus or minus 4) .....if DT's interrupts had latency.....wouldn't it show up there too?

remember all I'm doing here...


Comp1 interrupts....store count
comp1 interrupts again....store count reset timer

Comp2 interrupts....store count.

Therefore the only thing that differs is resetting the timer - does it really take soo long (in clock cycle terms) to reset a timer?

Also, I wanted to avoid any situation where there was almost no time span between the comp1 interrupting & comp2 interrupting (& causing diffs), so as an experiment, I've also put the tiniest amount of lag (as visible on a scope) in to avoid this too....no change - that 325 doesn't move until I take the all pass filter lag way up past 23 degrees....at which point comp2 count starts incrementing as I'd expect.

(also why would the comp2 count move when I take the frequency down - the period for 100hz is much longer so comp1 count is 10 times higher at 50,000, but the comp2 count also went 10 times higher at 100Hz to approx 3,000. weird.)

rsocor01
- 15th September 2010, 08:38
Thanks for both your comments - re latency of the interrupts.......remember, here that the comp1 count is rock solid....ie at 1khz into comparator1, I'm seeing a steady count of 5,000 (plus or minus 4) .....if DT's interrupts had latency.....wouldn't it show up there too?

The 5,000 are being counted when the program is out of the interrupt routine --> So, no interrupt lag.

HankMcSpank
- 15th September 2010, 08:46
The 5,000 are being counted when the program is out of the interrupt routine --> So, no interrupt lag.

I guess I'm not grasping that - why is comp1 out of the interrupt routine?

here's the sequence...

Comp1 interrupts - store a number (an interrupt)

(returns to main program)

Comp1 interrupts again - clear a timer (another interrupt)

(returns to main program)

Comp2 interrupts - store a number (another albeit different interrupt)

(returns to main program)


could it be something specific to the Comp2 interrupt? incurring extra delay? (but that said, it's clearly not a static delay - seems to be pro rata to the incoming frequency on comp2....ie at 1000hz, the lowest number comp2 will go is 325, at 100hz the lowest number comp22 will go is about 3,000)

rsocor01
- 15th September 2010, 09:11
Well, I think it goes like this (please, somebody correct me if I'm wrong)

(main program) --> Do the counting (5000 for Comp1Time) Uses TMR1 to count
Comp1 interrupts: store Comp1Time -> clear TMR1
(returns to main program) --> Do the counting (X for Comp2Time) Uses TMR1 to count
Comp2 interrupts: store Comp2Time
(returns to main program) --> Do the counting (5000 for Comp1Time) Uses TMR1 to count
Comp1 interrupts: store Comp1Time -> clear TMR1

and so on ..... This is for the last code that you have posted.

Robert

Jerson
- 15th September 2010, 09:28
Hi Hank

I think You and Robert got the sequence correct.

Now, the counts between 2 Comp1 ints is proportional to the frequency and you have no problems here.

The counts2 that you refer, are these raw counts? or are they converted as per the formula you showed in an earlier post?


this means @1khz, with that error I'm getting a phase shift of about 23 degrees being erroneouly calculated - ie 5000 (1st timer count) divided by 360 (degrees) muyltiplied by 325 (second timer count) - but I know for a fact there's actually no phase shift present at all (I can see this on my scope).

If it is this formula you are using, I think you will need to revise this like so
Phase(degrees) = ( Phase (Counts) * 360 degrees ) / Frequency (Counts)
The sequence of operation is significant and I have bracketed them on purpose.

As to why you cannot go below 325, I was wrong earlier. The latency cannot be so high. The explanation is like this
for a freq count of 500 (100Hz) the equation breaks down to 500/360 * 325
Now, Using integer math, 500/360 = 1, so 1*325

HankMcSpank
- 15th September 2010, 12:09
Hi Robert - yes, that's my take on the overall flow of things - so why on earth does the timer1 count not get any lower than 325 @1khz when the lagged signal causes an interrupt on comp2?(pretty much immediately after comp1 finishes it's interrupt routine)

Hi Jerson - just to confirm - those were raw counts.

The reason being, while debugging this, I didn't want incur any extra PIC 'overhead' calculating the phase in the PIC program itself (ie causing problems with the overall flow of things) ....so I stripped it back bare (for now, I calculate the phase separately on a spreadsheet based on the two timer counts I see onscreen)

My program is very small I'm at work & don't have it with me) but it's literally just ..

set registers up
set interrupts up (as per standard for DT's routines)
a Tiny main program loop ....just to get the stored timer1 count info out the HSEROUT pin onto my PC screen.
the two comp interrupts (as posted in my earlier post)

HankMcSpank
- 16th September 2010, 00:10
Ok, I think I've got to the bottom of the problem - & rather than have the soltuion posted in a thread with an unrelated title, I've tagged it on the end of a more appropriate on that I started...

http://www.picbasic.co.uk/forum/showthread.php?t=13690&p=94006#post94006

rsocor01
- 16th September 2010, 00:26
Ok, I think I've got to the bottom of the problem - & rather than have the soltuion posted in a thread with an unrelated title, I've tagged it on the end of a more appropriate on that I started...

http://www.picbasic.co.uk/forum/showthread.php?t=13690&p=94006#post94006

Hmmm, that explains the phase shift part. But, how do you explain getting a reading of 3000 instead of 329 on Comp2 when you change the frequency at Comp1 to 100Hz? :confused:

Robert

HankMcSpank
- 16th September 2010, 09:36
Hmmm, that explains the phase shift part. But, how do you explain getting a reading of 3000 instead of 329 on Comp2 when you change the frequency at Comp1 to 100Hz? :confused:

Robert

I've not had time to revisit (only had a short while on this again last night), but here's what I was reckon was happening.

I hadn't 'squared' the analogue sine wave signals going into the schmitt trigger (this will be my first port of call wrt solving this) - the schimtt will 'trip' at a predetermined level - and unless it is fed a square wave (with the fastest rising edge possible), then with a signal such as a sine wave, there'll inevitably there'll be some delay (or even 'lead') wrt the timing of the two respective signals coming out of the schmitt - and timing is obviously key if you're trying to measure phase difference!

The shcmitt 'triggers' as a function of signal level & in this case (due to this area being somewhat new ground) I was feeding the two schmitts different signal amplitude levels, it was therefore triggering at different respective times (wrt to one another) & introducing a triggering 'time difference' - this is being picked up as phase delay by my PIC timers.

At 1000Hz, the comp2 count was 329 (which is 32.9%%) at 100hz the comp2 count was 3000 (which is 30%) - the fact it wasn't a set percentage error suggests that this is related to schmitt incurred triggering 'time point' changing with input frequency.

I need to 'square up' the analogue sine waves by feeding them through an identical circuits, prior to feeding them into the schmitt. I'm then in the realm of slew rates for the circuit that squares the sine waves up.....obviously I need the fastest rising edge possible to ensure that the schmitts don't add in their own lags betwen the two signals.

Still...I learnt a whole heap ....& thank you (as ever) for those whoe chimed in....this truly is a great forum.

I'll post results once I crack the all new improved phase measuring method (though the base 'floor' count of 29 when the same signal is "Y"'ed into both PIC comparators - as mentioned in my other thread - is troublesome). Whilst it would have been a bother for other to replicate what I was doing with all pass filters etc, there is something here that others could easily replicate on their own - feed an identical square wave (ie a PWM signal, clock ...whatever) into both PIC comparators use the comp1 & comp2 interrupts as above & see what base floor count you get....it's higher than I'd imagined it would be.

rsocor01
- 16th September 2010, 16:52
Still...I learnt a whole heap ....& thank you (as ever) for those whoe chimed in....this truly is a great forum.

It is not my project, but I'm learning from it too :cool:.