⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.c

📁 CNC.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
//! Multiplies a number by a fraction specified as a numerator and denominator.
//!
//! \param ulValue is the value to be multiplied.
//! \param ulNum is the numerator of the fraction.
//! \param ulDenom is the denominator of the fraction.
//!
//! This function take an integer and multiplies it by a fraction specified by
//! a numerator and denominator.  Assuming infinite precision of the operands,
//! this would be "(ulValue * ulNum) / ulDenom", though with the fixed
//! precision of the processor the multiply would overflow if performed as is.
//!
//! \return The result of the multiplication.
//
//*****************************************************************************
static unsigned long
MulDiv(unsigned long ulValue, unsigned long ulNum, unsigned long ulDenom)
{
    //
    // Perform the multiplication in pieces to maintain the full accuracy and
    // return the result.
    //
    return(((((ulValue / 65536) * ulNum) / ulDenom) * 65536) +
           (((((ulValue / 65536) * ulNum) % ulDenom) * 65536) / ulDenom) +
           (((ulValue % 65536) * ulNum) / ulDenom));
}

//*****************************************************************************
//
//! Divides two numbers, returning the result in 24.8 fixed-point notation.
//!
//! \param ulNum is the numerator for the division.
//! \param ulDenom is the denominator for the division.
//!
//! This function takes two integers and divides them, returning the results in
//! 24.8 fixed-point notation (with full accuracy).  Assuming infinite
//! precision of the operands, this would be "(256 * ulNum) / ulDenom", though
//! with the fixed precision of the processor the multiply would overflow if
//! performed as is.
//!
//! \return The result of the division.
//
//*****************************************************************************
static unsigned long
LongDiv256(unsigned long ulNum, unsigned long ulDenom)
{
    //
    // Perform the division in pieces to maintain the full accuracy and return
    // the 24.8 fixed-point result.
    //
    return(((ulNum / ulDenom) * 256) + (((ulNum % ulDenom) * 256) / ulDenom));
}

//*****************************************************************************
//
//! The timer handler for the table homing operation.
//!
//! This is the timer handler that is called after each step delay during the
//! table homing operation.  There are four phases to the homing operation:
//!
//! - In the first phase, the tool is rapidly raised until the home limit
//!   switch engages.
//!
//! - In the second phase, the table is rapidly jogged until the home limit
//!   switches engage.
//!
//! - In the third phase, the tool is slowly lowered until the home limit
//!   switch disengages.
//!
//! - In the final phase, the table is slowly moved away from the home position
//!   until the home limit switches disengage.
//!
//! Once complete, this becomes the home position.  Since there may be some
//! positional overshoot when rapidly moving toward the home position (since
//! it might not be possible to immediately stop the table once the limit
//! switch engages), the slow move until the limit switches disengage is
//! performed at a speed that can be reliably stopped immediately.  This
//! provides a more accurate and repeatable home position (subject to the
//! mechanical variablility of the limit switches themselves).
//!
//! \return None.
//
//*****************************************************************************
static void
TableHomeHandler(void)
{
    unsigned long ulSwitches;
    tBoolean bContinue;

    //
    // Set the continuation indicator to false.
    //
    bContinue = false;

    //
    // Read the limit switches.
    //
    ulSwitches = SwitchesLimitRead();

    //
    // See if the first or second phase of the homing operation is in progress.
    //
    if(g_ulHomeState == STATE_HOMING1)
    {
        //
        // See if the Z home limit switch is engaged.
        //
        if((ulSwitches & SWITCH_LIMIT_Z_MINUS) == 0)
        {
            //
            // Step the Z axis in the negative direction.
            //
            g_sZAxis.pfnStep(-1);
        }
        else
        {
            //
            // Move the phase two of the homing operation.
            //
            g_ulHomeState = STATE_HOMING2;

            //
            // Set the inter-step delay such that the second phase of the
            // homing operation happens slowly.
            //
            g_sXAxis.ulC = GET_C0(30000);
            g_sXAxis.lDenom = 5;
        }

        //
        // Indicate that the homing operation should continue.
        //
        bContinue = true;
    }

    else if(g_ulHomeState == STATE_HOMING2)
    {
        //
        // See if the X home limit switch is engaged.
        //
        if((ulSwitches & SWITCH_LIMIT_X_MINUS) == 0)
        {
            //
            // Step the X axis in the negative direction.
            //
            g_sXAxis.pfnStep(-1);

            //
            // Phase one of the homing operation should continue.
            //
            bContinue = true;
        }

        //
        // See if the Y home limit swtich is engaged.
        //
        if((ulSwitches & SWITCH_LIMIT_Y_MINUS) == 0)
        {
            //
            // Step the Y axis in the negative direction.
            //
            g_sYAxis.pfnStep(-1);

            //
            // Phase one of the homing operation should continue.
            //
            bContinue = true;
        }

        //
        // See if phase two of the homing operation has completed.
        //
        if(!bContinue)
        {
            //
            // Move the phase three of the homing operation.
            //
            g_ulHomeState = STATE_HOMING3;

            //
            // Set the inter-step delay such that the second phase of the
            // homing operation happens slowly.
            //
            g_sXAxis.ulC = GET_C0(30000);

            //
            // Indicate that the homing operation should continue.
            //
            bContinue = true;
        }
    }

    else if(g_ulHomeState == STATE_HOMING3)
    {
        //
        // See if the X home limit switch is still engaged.
        //
        if(ulSwitches & SWITCH_LIMIT_X_MINUS)
        {
            //
            // Step the X axis in the positive direction.
            //
            g_sXAxis.pfnStep(1);

            //
            // Phase two of the homing operation should continue.
            //
            bContinue = true;
        }

        //
        // See if the Y home limit switch is still engaged.
        //
        if(ulSwitches & SWITCH_LIMIT_Y_MINUS)
        {
            //
            // Step the Y axis in the positive direction.
            //
            g_sYAxis.pfnStep(1);

            //
            // Phase two of the homing operation should continue.
            //
            bContinue = true;
        }

        //
        // See if phase three of the homing operation has completed.
        //
        if(!bContinue)
        {
            //
            // Move the phase four of the homing operation.
            //
            g_ulHomeState = STATE_HOMING4;

            //
            // Set the inter-step delay such that the fourth phase of the
            // homing operation happens slowly.
            //
            g_sXAxis.ulC = GET_C0(30000);

            //
            // Indicate that the homing operation should continue.
            //
            bContinue = true;
        }
    }

    else
    {
        //
        // See if the Z home limit switch is still engaged.
        //
        if(ulSwitches & SWITCH_LIMIT_Z_MINUS)
        {
            //
            // Step the Z axis in the positive direction.
            //
            g_sZAxis.pfnStep(1);

            //
            // Phase two of the homing operation should continue.
            //
            bContinue = true;
        }
    }

    //
    // See if the homing operation should continue.
    //
    if(bContinue)
    {
        //
        // See if the first or second phase of the homing operation is process.
        //
        if((g_ulHomeState == STATE_HOMING1) ||
           (g_ulHomeState == STATE_HOMING2))
        {
            //
            // For the first phase of the homing operation, restart the timer
            // and compute a new value for the inter-step delay.
            //
            g_sHomeTimer.ulTimeOut += (g_sXAxis.ulC + 128) >> 8;
            VirtualTimerAdd(&g_sHomeTimer);

            //
            // See if the inter-step delay has reached the minimum.
            //
            if(g_sXAxis.ulC != g_sXAxis.ulCMin)
            {
                //
                // Compute the new value of the inter-step delay.  Treat the
                // first step specially to account for the relatively large
                // error that would otherwise occur.
                //
                if(g_sXAxis.lDenom == 5)
                {
                    g_sXAxis.ulC = MulDiv(g_sXAxis.ulC, 4056, 10000);
                }
                else
                {
                    g_sXAxis.ulC -= (2 * g_sXAxis.ulC) / g_sXAxis.lDenom;
                }

                //
                // Limit the inter-step delay to the minimum value.
                //
                if(g_sXAxis.ulC < g_sXAxis.ulCMin)
                {
                    g_sXAxis.ulC = g_sXAxis.ulCMin;
                }

                //
                // Increment the denominator so that the next inter-step delay
                // is computed correctly.
                //
                g_sXAxis.lDenom += 4;
            }
        }
        else
        {
            //
            // For the second phase of the homing operation, keep the same
            // inter-step delay so that the table is moved slowly.
            //
            g_sHomeTimer.ulTimeOut += (g_sXAxis.ulC + 128) >> 8;
            VirtualTimerAdd(&g_sHomeTimer);
        }
    }
    else
    {
        //
        // The homing operation is complete.
        //
        g_ulHomeState = STATE_HOMED;
    }
}

//*****************************************************************************
//
//! Finds the table home position.
//!
//! This function moves the table until it is in the home position.  After
//! finding the home position, any required table move can be made in a
//! repeatable manner.
//!
//! \return None.
//
//*****************************************************************************
void
TableHome(void)
{
    //
    // Set the current of each motor to running.
    //
    g_sXAxis.pfnCurrent(CURRENT_RUNNING);
    g_sYAxis.pfnCurrent(CURRENT_RUNNING);
    g_sZAxis.pfnCurrent(CURRENT_RUNNING);

    //
    // Set the state to the first phase of the homing operation.
    //
    g_ulHomeState = STATE_HOMING1;

    //
    // Setup the acceleration for the homing operation.  Arbitrarily use the X
    // axis to store the information.
    //
    g_sXAxis.ulC = GET_C0(30000);
    g_sXAxis.ulCMin = GET_CMIN(1200);
    g_sXAxis.lDenom = 5;

    //
    // Start the homing operation timer.
    //
    g_sHomeTimer.ulTimeOut = VirtualTimeGet() + ((g_sXAxis.ulC + 128) >> 8);
    VirtualTimerAdd(&g_sHomeTimer);

    //
    // Wait until the homing operation is complete.
    //
    while(g_ulHomeState != STATE_HOMED)
    {
    }

    //
    // Reset the position of each axis.
    //
    g_sXAxis.lPos = 0;
    g_sYAxis.lPos = 0;
    g_sZAxis.lPos = 0;

    //
    // Set the current of each motor to holding.
    //
    g_sXAxis.pfnCurrent(CURRENT_HOLDING);
    g_sYAxis.pfnCurrent(CURRENT_HOLDING);
    g_sZAxis.pfnCurrent(CURRENT_HOLDING);
}

//*****************************************************************************
//
//! The step handler for an axis.
//!
//! \param pAxis is a pointer to the axis to be stepped.
//!
//! This is a generic axis step handler; it will perform a step operation on
//! the given axis.
//!
//! \return None.
//
//*****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -