Пример #1
0
//*****************************************************************************
//
// 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);
    }
}