//***************************************************************************** // // This function is called to handle the GPIO edge interrupt from the // quadrature encoder. // //***************************************************************************** void QEI1IntHandler(void) { unsigned long ulNow; // // Save the time. // ulNow = SysTickValueGet(); // // Clear the encoder interrupt. // GPIOPinIntClear(QEI_ROLL_PHA_PORT, QEI_ROLL_PHA_PIN); ulstatus1 = QEIIntStatus(QEI1_BASE,false); if ( (ulstatus1 & QEI_INTDIR) == QEI_INTDIR) { // // clear Interrupt Bit QEIIntClear(QEI1_BASE, QEI_INTDIR); // //code for Direction change //.............. } if ( (ulstatus1 & QEI_INTINDEX) == QEI_INTINDEX) { // // clear Interrupt Bit QEIIntClear(QEI1_BASE, QEI_INTINDEX); // //code for Index change //.............. } if ( (ulstatus1 & QEI_INTERROR) == QEI_INTERROR) { // // clear Interrupt Bit QEIIntClear(QEI1_BASE, QEI_INTERROR); // //code for Phase ERROR //.............. } // // Determine the number of system clocks between the previous edge and this // edge. // if(g_ulEncoder1Previous > ulNow) { g_ulEncoder1Clocks = g_ulEncoder1Previous - ulNow; } else { g_ulEncoder1Clocks = (SYSCLK_50MHZ - ulNow) + g_ulEncoder1Previous; } // // Save the time of the current edge as the time of the previous edge. // g_ulEncoder1Previous = ulNow; // // Indicate that an edge has been seen. // HWREGBITH(&g_usEncoder1Flags, ENCODER_FLAG_EDGE) = 1; // // If the previous edge time was valid, then indicate that the time between // edges is also now valid. // if(HWREGBITH(&g_usEncoder1Flags, ENCODER_FLAG_PREVIOUS) == 1) { HWREGBITH(&g_usEncoder1Flags, ENCODER_FLAG_VALID) = 1; } // // Indicate that the previous edge time is valid. // HWREGBITH(&g_usEncoder1Flags, ENCODER_FLAG_PREVIOUS) = 1; }
//***************************************************************************** // // Handles the QEI velocity interrupt. // // This function is called when the QEI velocity timer expires. If using the // edge counting mode for rotor speed determination, the number of edges // counted during the last velocity period is used as a measure of the rotor // speed. // // \return None. // //***************************************************************************** void QEIIntHandler(void) { unsigned long ulPrev, ulCount; // // Clear the QEI interrupt. // QEIIntClear(QEI0_BASE, QEI_INTTIMER); // // Increment the accumulated time to extend the range of the QEI timer, // which is used by the edge timing mode. // g_ulSpeedTime += SYSTEM_CLOCK / QEI_INT_RATE; // // See if edge counting mode is enabled. // if(HWREGBITW(&g_ulSpeedFlags, FLAG_COUNT_BIT) == 0) { // // Edge timing mode is currenting operating, so see if an edge was seen // during this QEI timing period. // if(HWREGBITW(&g_ulSpeedFlags, FLAG_EDGE_BIT) == 0) { // // No edge was seen, so set the rotor speed to zero. // g_ulRotorSpeed = 0; // // Since the amount of time the rotor is stopped is indeterminate, // skip the first edge when the rotor starts rotating again. // HWREGBITW(&g_ulSpeedFlags, FLAG_SKIP_BIT) = 1; } else { // // An edge was seen, so clear the flag so the next period can be // checked as well, and restart the edge reset counter. // HWREGBITW(&g_ulSpeedFlags, FLAG_EDGE_BIT) = 0; } // // There is nothing further to do. // return; } // // Get the number of edges during the most recent period. // ulCount = QEIVelocityGet(QEI0_BASE); // // Get the count of edges in the previous timing period. // ulPrev = g_ulSpeedPrevious; // // Save the count of edges during this timing period. // g_ulSpeedPrevious = ulCount; // // See if this timing period should be skipped. // if(HWREGBITW(&g_ulSpeedFlags, FLAG_SKIP_BIT)) { // // This timing period should be skipped, but an edge count from a // previous timing period now exists so the next timing period should // not be skipped. // HWREGBITW(&g_ulSpeedFlags, FLAG_SKIP_BIT) = 0; // // There is nothing further to be done. // return; } // // Average the edge count for the previous two timing periods. // ulCount = (ulPrev + ulCount) / 2; // // Compute the new speed from the number of edges. Note that both // edges are counted by the QEI block, so the count for a full revolution // is double the number of encoder lines. // SpeedNewValue((ulCount * QEI_INT_RATE * 30) / (UI_PARAM_NUM_LINES + 1)); // // See if the number of edges has become too small, meaning that the edge // time has become large enough. // if(ulCount < (((MAX_EDGE_COUNT - EDGE_DELTA) * 2) / QEI_INT_RATE)) { // // Edge timing mode should be used instead of edge counting mode. // HWREGBITW(&g_ulSpeedFlags, FLAG_COUNT_BIT) = 0; // // Indicate that the first edge should be skipped in edge timing mode. // HWREGBITW(&g_ulSpeedFlags, FLAG_SKIP_BIT) = 1; // // Enable the GPIO interrupt to enable edge timing mode. // IntEnable(INT_GPIOC); } }