1.4.2 CLC + NCO + TimerX

Table 1-12. NCO + CLC + TimerX Code Calculations
Modules Limit High Resolution
CLC 65.54 ms 62.5 ns
NCO
TimerX

This method uses the CLC to clock the NCO accumulator when the pulse is high. Any timer can be used to increment when the other modules are running. For best accuracy, this should be used to measure duty cycles of a waveform over an extended period of time of at least 100 periods.

OVERVIEW

When the timer is enabled, immediately enable the NCO to start accumulating with an increment value of one. When the waveform is high, the NCO will increment with every clock edge until the waveform goes low.

The NCO is disabled to conclude the measurement and can be initiated in multiple ways such as an interrupt on the timer or NCO accumulator overflow. If an overflow has occurred, the maximum value of that register should be used and not its current value since the interrupt would not stop it from incrementing from zero.

It is important that the same clock source (FOSC) is used between the CLC and timer to avoid post processing. For example, Timer2 can only utilize FOSC/4 as its clock input. Two left shifts on the resultant timer value can compensate for this by multiplying its value by 4.

Figure 1-16. High Level View of the Interaction Between CLC1 and NCO. All of the Connections are Internal to the Processor Except the Pulse

The duty cycle is subsequently the 20-bit NCO value divided by the timer value (assuming both the timer and NCO increment by 1 on the same clock source with a 1:1 ratio).

Equation 1-3. Duty Cycle Calculation for NCO
D u t y C y c l e = A c c u m u l a t o r V a l t i m e r V a l

One important consideration is the timer rollover length. The timer must not expire before the waveform makes a complete period.

SETUP

  1. Set up the NCO in FDC or PFC mode with CLC1OUT as the clock source
  2. Set up CLC as a 4-input AND gate
    1. Inputs 1 and 2 set to VDD (invert Gate 1 and 2 output)
    2. Input 3 is the clock source (HFINTOSC)
    3. Input 4 is the Pulse

CLC NCO Operation Code

    NCO1ACCU = NCO1ACCH = NCO1ACCL = 0x00;    // Clear NCO Accumulator 
    TMR1H = 0x00;                             // Clear Timer1 H/L Bytes
    TMR1L = 0x01;                                    
    PIR1bits.TMR1IF = 0;                      // Clear Timer1 Flag
    PIR2bits.NCO1IF = 0;                      // Clear NCO1 Flag
    uint16_t cycles = 0;                      // Clear the cycles count
    reset_CLC2_CLC3();                                      
    
    T1CONbits.TMR1ON = 1;                 // Enable TMR1 to start counting
    NCO1CONbits.EN = 1;                   // Enable NCO1 to start counting

if (PIR1bits.TMR1IF || cycles > 99){
    NCO1CONbits.EN = 0;                   // Disable NCO1 to stop counting
    T1CONbits.TMR1ON = 0;                 // Disable TMR1 to stop counting
}
else {
    cycles++;    // Increment cycles for every cycle through the code.
}                // Eventually enough cycles occur that 
                 // NCO1 and Timer1 will stop.
                 // Then measurements can be taken and 
                 // a duty cycle can be calculated.

Figure   3 shows a timing diagram as an implementation of Figure   1.

Figure 1-17. Measurement of Duty Cycles is the Ratio of the NCO Accumulator Value and Timer Value

The measured duty cycle is then:

Equation 1-4. Duty Cycle Calculation for NCO
D u t y C y c l e = A c c u m u l a t o r V a l t i m e r V a l = 158 255 ( 100 ) = 62 %

There is uncertainty associated with this measurement due to when the timer starts and stops incrementing relative to when the waveform period starts and ends. This uncertainty fluctuates with the placement of the timer overflow. If the timer is disabled just before the start of the second pulse (not pictured), then the duty cycle would appear to be much less than it is.

For this reason, this method should be employed to be counting during as much of the waveform as possible. As an example, a 50 kHz square wave that goes through 100 periods, will have an accuracy of one percent, or rather one period length. This would require that the timer be counting for at least 2 ms.

Equation 1-5. Accuracy of this Method is Dependent on the Number of Periods Measured

A c c u r a c y = # o f p e r i o d s 1 # o f p e r i o d s ( 100 )

T i m e r L e n g t h = 1 P e r i o d * # o f p e r i o d s