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 by the number of reference clock cycles. It 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 a slower clock to a time window (reference clock) and a faster clock to a counter (monitor clock).

There is no accumulation window (WINPR= 0). The rising edge to the next falling edge of the reference clock will be the window for CMxBUF to get loaded.

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

Each rising edge to the next falling edge of LPRC (32KHz) will be 15.625 µs.

15.625 µs * 8M = 0x007D is the expected count in the 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 setup 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-9. 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

    //Select reference clock source
    CM2SELbits.WINSEL = 20; //reference clock LPRC
 
    //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);