Created Wed, 25 Nov 2015 11:10:57 +0000 by nfdcasaleiro
Wed, 25 Nov 2015 11:10:57 +0000
I am work on a library to read and write PWM, frequency and duty cycle on max32. I am using module input capture to read PWM. Work fine to read frequency but some time detect first edge wrong and inverte value of duty cycle. Please any one can help me. I am using the following code:
uint8_t read_pwm( float *freq , float *duty) {
uint32_t timeout;
uint32_t clock_ref = 5000000;
pinMode(48, INPUT);
T3CON = 0;
T3CONbits.ON = 0; //turn OFF timer3
T3CONbits.TCKPS = 4; //1:16
TMR3 = 0; //clear timer3 counter
PR3 = 65535;
saved_PR3 = PR3;
// use a 16-bit timer with TMR3 as the source timer
IC1CONbits.C32 = 0;
IC1CONbits.ICTMR = 0;
IC1CONbits.SIDL = 0; //Continue to operate in Idle mode
// start capture on first rising edge followed by any edge after that
// interrupt on every 4th capture event to get pulse width and period
IC1CONbits.FEDGE = 1;
IC1CONbits.ICM = 6; // capture every edge starting with the above
IC1CONbits.ICI = 4;
// enable input capture interrupt with priority level 1 and subpriority 0
IPC1bits.IC1IP = 1;
IPC1bits.IC1IS = 0;
// turn on input capture & TMR3
IC1CONbits.ON = 1;
T3CONbits.ON = 1;
IEC0bits.IC1IE = 1; //Enable interrupt
T3CONbits.ON = 1; //turn ON timer3
timeout = millis();
float aux, duty_h, duty_l;
while ((timeout + 20) > millis())
{
if (flg_read == 1)
{
Serial.print("timea :");
Serial.println(timea , DEC);
Serial.print("timeb :");
Serial.println(timeb , DEC);
Serial.print("timec :");
Serial.println(timec , DEC);
Serial.print("timed :");
Serial.println(timed , DEC);
aux = ((float)timec - (float)timea);
*freq = (float)( clock_ref / aux);
duty_h = ( ( (float) timeb - (float) timea ) / aux);
duty_l = ( ( (float) timec - (float) timeb ) / aux);
Serial.print("freq :");
Serial.println(*freq , DEC);
Serial.print("duty+ :");
Serial.println( duty_h , DEC);
Serial.print("duty- :");
Serial.println( duty_l , DEC);
flg_read = 0;
return 1;
}
}
return 0;
}
extern "C" {
void __ISR(_INPUT_CAPTURE_1_VECTOR, ipl1) IC1Handler(void) {
// Is this an IC1 interrupt?
if (IFS0bits.IC1IF)
{
IFS0bits.IC1IF = 0;
IEC0bits.IC1IE = 0;
// read data four times to clear the buffer
timea = IC1BUF; // first value
timeb = IC1BUF; // second value
timec = IC1BUF; // third value
timed = IC1BUF; // fourth value
flg_read = 1;
}
}
}// end extern "C"
Thu, 26 Nov 2015 15:03:01 +0000
I found the bug under my code. If you disable the interrupt you will loss the synchronism from the rising edge and have to restart the module input capture.