4 Ekim 2017 Çarşamba

Measure Period and Duty Cycle using CCP2 and TIMER1

We will use the same circuit to measure duty cycle together with the period.  Period is the time difference between two rising edges (t3-t1). Duty cycle is the difference between the first rising edge and next falling edge (t2-t1).


MCC: MCC settings are the same as previous example, 1MHz internal osc, 1:1 prescaler, CCP interrupt enabled for every rising edge.

XC8:   while(!CCP2IF) statement to capture the interrupt case  inside the main.c did not work (there are many examples of it in internet). Thus I put conditions inside ccp2.c ISR  such as
...
extern uint16_t  t1,t2,t3;
int c=0;

void CCP2_CallBack(uint16_t capturedValue)
{
    // Add your code here

       
    if ( c==2) {
      t3=capturedValue;  
      CCP2CON=0x00;   //second rising edge
      c=0;        
    } else if (c==1) {
      t2=capturedValue; // falling edge
      CCP2CON=0x00;
      CCP2CON=0x05;
      c=2;
    } else {    
      t1=capturedValue;  //first rising edge
      CCP2CON=0x00;
      CCP2CON=0x04;
      c=1;        
    }
   
}

transition from rising to falling edge did not work. Thus I disabled interrupt first and enabled with new state. t1,t2,t3 are defined as extern to use in main.c, c integer is local for toggling between cases.

statement inside main.c enables rising edge, waits for interrupt stop then calculated duty and period, prints on LCD

        CCP2CON=0x05;  
        while(CCP2CON!=0);
        d=t2-t1;
        if (d<0) d=d+65536;
        d=d*4.0/1000.0;
        f=t3-t1;
        if (f<0) f=f+65536;
        f=f*4.0/1000.0;
        
        sprintf(s1,"%3.3fms", f); 
        sprintf(s2,"%3.3fms", d); 

This code was able to measure between 1-262 ms with 1MHZ oscillator. Below 1ms yields multiple captured values and wrong results. We can increase the osc frequency (8MHZ or 16MHz) or use 16th rising edge etc for lower values. we can add timer1 overflow interrupt to measure values above 262ms, too. 


Hiç yorum yok:

Yorum Gönder