12.4.7.3.2 Pulse Width and Duty Cycle Measurement

The clock monitored module is also capable of measuring the pulse width of the monitored clock source. By allowing only the high pulse time period of the monitored clock source to define the accumulation time window, see WIDTH, the pulse width can be measured in the number of reference clock cycles. This is given that the reference clock frequency is higher than the monitored clock frequency, so the operation is similar to that of the CCP module.

Clocking Configurations:

Monitored Clock ≥ Time Window Generator

Reference Clock ≥ Counter

In pulse measurement, give slower clock to time window (reference clock) and faster clock to counter (monitor clock).

There is no accumulation window (WINPR= 0), Rising Edge to Next Falling Edge of the reference clock will be the window for CMxBUF to get loaded.

Pulse Width shows LPRC as reference clock and FRC as monitor clock.

Each Rising Edge to Next Falling Edge of LPRC (32KHz) will be 15.625 µs.

15.625 µs * 8M = 0x007D is the expected count in CMxBUF register.

Similarly, clock period measurement can also be accomplished by allowing the time period of the monitored clock source to define the accumulation time window.

With the clock set-up given above, the pulse width or clock period represented by the number of reference clock cycles and captured at every accumulation lapsed time can simply be read out of the Data Buffer register, BUF[31:0], for further processing as follows:

  • Conversion into unit of time
  • Duty cycle calculation (with period measurement)
Table 12-35. Module Control
FunctionClock SourceControl
win_clk[*:0]cnt_clk[*:0]ON/WIDTH
Monitorreferencemonitored1/0
Measurement - SWreferencereference1/0
Measurement - PWmonitoredreference1/1

Pulse Width

IFS0bits.C2FAILIF = 0;     // enable clock Monitor2 failure interrupt
    IEC0bits.C2FAILIE = 1;

    IFS0bits.C2MONIF = 0;          // enable clock saturation failure interrupt
    IEC0bits.C2MONIE = 1;

    IFS0bits.C2WARMIF = 0;         // enable clock Warning failure interrupt
    IEC0bits.C2WARMIE = 1;

    IFS0bits.C2RDYIF = 0;         // enable clock ready  failure interrupt
    IEC0bits.C2RDYIE = 1;

    CM2CONbits.ON = 0;            // disable clock monitor

    //Select monitor clock source
    CM2SELbits.CNTSEL = 4;        // Monitoring clock clock-gen-5
    //[0] = cru_clkgen_clk[1] = System clocks 
    //[1] = cru_clkgen_clk[2]
    //...
    //[10] = cru_clkgen_clk[11]
    //[11] = cru_pll_fout_clk[1]
    //[12] = cru_pll_vcodiv_clk[1]
    //[13] = cru_pll_fout_clk[2]
    //[14] = cru_pll_vcodiv_clk[2]
    //[15] = 1?b0 (reserved)
    //[16] = Serial Test Mode clock (PGC)
    //[17] = FRC - Internal 8 MHz RC oscillator
    //[18] = BFRC - Internal Backup 8 MHz RC oscillator
    //[19] = POSC - Primary crystal oscillator (4-32 MHz)
    //[20] = LPRC or BRFC/256
    //[25] = REFI1 - user definable clock source
    //[26] = REFI2 - user definable clock source

    //Select reference clock source
    CM2SELbits.WINSEL = 20; //reference clock LPRC
    //[0] = cru_clkgen_clk[1] = System clocks 
    //[1] = cru_clkgen_clk[2]
    //...
    //[10] = cru_clkgen_clk[11]
    //[11] = cru_pll_fout_clk[1]
    //[12] = cru_pll_vcodiv_clk[1]
    //[13] = cru_pll_fout_clk[2]
    //[14] = cru_pll_vcodiv_clk[2]
    //[15] = 1?b0 (reserved)
    //[16] = Serial Test Mode clock (PGC)
    //[17] = FRC - Internal 8 MHz RC oscillator
    //[18] = BFRC - Internal Backup 8 MHz RC oscillator
    //[19] = POSC - Primary crystal oscillator (4-32 MHz)
    //[20] = LPRC or BRFC/256
    //[25] = REFI1 - user definable clock source
    //[26] = REFI2 - user definable clock source


    //Counter Divider Selection
    CM2CONbits.CNTDIV = 0;
    //    10 = Divide-by 4
    //    01 = Divide-by 2
    //    00 = Divide-by 1

    CM2WINPR = 0x0000; //monitor clock pre scale 
    //Accumulation Time (in cycles) = WINPR[31:0] + 1

    CM2HFAIL = 0x90;         //CLOCK MONITOR HIGH THRESHOLD FAILING
    CM2LFAIL = 0x70;         //CLOCK MONITOR LOW THRESHOLD FAILING

    CM2HWARN = 0x85;         //CLOCK MONITOR HIGH THRESHOLD WARNING
    CM2LWARN = 0x75;         //CLOCK MONITOR LOW THRESHOLD WARNING

    CM2SAT = 0x100;         //CLOCK MONITOR COUNTER SATURATION


    CM2CONbits.WIDTH = 1;   // 0 - Frequency Measurement
    // 1 - Pulse Width and Duty Cycle Measurement

    CM2CONbits.ON = 1;     //enable clock monitor
    while (CM2CONbits.ON);