chipKIT® Development Platform

Inspired by Arduino™

Read duty Max32

Created Wed, 25 Nov 2015 11:10:57 +0000 by nfdcasaleiro


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"


nfdcasaleiro

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.