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....

Code:
@ __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.