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