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

📄 table.c

📁 CNC.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
//*****************************************************************************
//
// table.c - Table control functions.
//
// Copyright (c) 2006-2007 Luminary Micro, Inc.  All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws.  All rights are reserved.  Any use in violation
// of the foregoing restrictions may subject the user to criminal sanctions
// under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 220 of sw01246.
//
//*****************************************************************************

#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "debug.h"
#include "gpio.h"
#include "interrupt.h"
#include "pwm.h"
#include "sysctl.h"
#include "isqrt.h"
#include "stepper.h"
#include "switches.h"
#include "virtualtimer.h"

//*****************************************************************************
//
//! \page main_table_intro Introduction
//!
//! A set of stepper motors are grouped together to draw lines in
//! three-dimensional space, based on the layout of the CNC table.  Since the Z
//! axis has a different thread density on its lead screw than the X and Y
//! axes, moves in the Z axis are not allowed to have moves in the X or Y axes
//! at the same time.
//!
//! Acceleration of the stepper motors is handled by the line drawing
//! algorithm.  A constant acceleration is used until the maximum speed is
//! reached, at which point the acceleration becomes zero.  At the appropriate
//! amount of time before the final step, a constant negative acceleration
//! (which is double the startup acceleration) is used to slow the speed down
//! to zero.  The inter-step delay is computed based on the algorithm described
//! by David Austin in the January 2005 issue of Embedded Systems Design.  It
//! can be found online at
//! <a href="http://www.embedded.com/showArticle.jhtml?articleID=56800129">
//! http://www.embedded.com/showArticle.jhtml?articleID=56800129</a>.
//!
//! By accelerating the motors instead of directly jumping to the desired
//! speed, higher speeds are achievable without loosing steps.  Higher speeds
//! are desirable since the line will be drawn quicker, and not loosing steps
//! is paramount since the steppers are run open-loop and therefore a lost step
//! will not be detected.
//!
//! Two methods are used for drawing lines.  For lines that are within ~10
//! degrees of the X or Y axes, Bresenham's line drawing algorithm is used (as
//! originally presented at the 1963 ACM national convention).  In this case,
//! the major axis (i.e. the one that the line is closest to, and therefore has
//! the furthest move to make) is run through the speed profile as if it were
//! the only axis being moved.  Then, as determined by Bresenhams' algorithm, a
//! move is occasionally made along the minor axis, the result being a
//! "straight" line (it would take a magnifying glass to detect the stair step
//! nature of the line).
//!
//! For all other lines, the two axes are controlled independently.  By scaling
//! back the speed (and acceleration) proportional to the distanced moved along
//! each axis (relative to the length of the diagonal), the two motors can be
//! controlled "independently" such that they cause the tool to move in a
//! straight line.
//!
//! For each line drawning method, the speed and acceleration is scaled such
//! that the tool travels at the requested speed along the line being drawn.
//! If! this were not done, then the tool could travel at up to 1.414 times the
//! requested speed when traveling at a 45 degree angle (i.e. both axes running
//! at the requested speed, resulting in the tool running along the diagonal at
//! sqrt(2) =~ 1.414 time faster).
//!
//! The position of all lines are based upon the home position of the table.
//! Homing the machine consists of moving all axes in the negative direction
//! until the home limits switches are engaged.  Once all axes are back in the
//! home position, each one is slowly moved out until the switch disengages;
//! this becomes the home position.
//!
//! The code for the table handling routines is contained in
//! <tt>main_micro/table.c</tt>, with <tt>main_micro/table.h</tt> containing
//! the API definitions for use by the remainder of the application.
//
//*****************************************************************************

//*****************************************************************************
//
//! \defgroup main_table_api Definitions
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
// Forward declarations for the virtual timer handlers.
//
//*****************************************************************************
static void TableHomeHandler(void);
static void TableXHandler(void);
static void TableYHandler(void);
static void TableZHandler(void);

//*****************************************************************************
//
//! This structure contains the state information for a single axis of the CNC
//! machine.
//
//*****************************************************************************
typedef struct
{
    //
    //! A pointer to the function used to step the axis.
    //
    void (*pfnStep)(long lDir);

    //
    //! A pointer to the function used to set the winding current of the axis.
    //
    void (*pfnCurrent)(unsigned long ulCurrent);

    //
    //! A virtual timer used for inter-step delays along this axis.
    //
    tVirtualTimer sTimer;

    //
    //! A boolean that is true if this axis is currently being moved.
    //
    tBoolean bMoving;

    //
    //! The current position of this axis.
    //
    long lPos;

    //
    //! The direction this axis is being moved.  This value is only valid if
    //! bMoving is true.
    //
    long lDir;

    //
    //! The number of steps left to move along this axis.
    //
    unsigned long ulSteps;

    //
    //! The step number at which the initial acceleration is complete.  This is
    //! used to determine how to stop the move if an early stop is requested.
    //
    unsigned long ulStartStep;

    //
    //! The step number at which the final negative acceleration should start.
    //
    unsigned long ulStopStep;

    //
    //! The time between the current step and the next, expressed in 24.8
    //! fixed-point notation, and indicating the number of processor clocks
    //! between steps.
    //
    unsigned long ulC;

    //
    //! The minimum delay between steps, computed based on the maximum speed.
    //! This is also expressed in 24.8 fixed-point notation.
    //
    unsigned long ulCMin;

    //
    //! The denominator used for calculating a new time delay from the old time
    //! delay.
    //
    long lDenom;
}
tAxisState;

//*****************************************************************************
//
//! The state structure for the X axis.
//
//*****************************************************************************
static tAxisState g_sXAxis =
{
    StepperXStep,
    StepperXCurrent,
    { TableXHandler, 0 },
    false,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
};

//*****************************************************************************
//
//! The state structure for the Y axis.
//
//*****************************************************************************
static tAxisState g_sYAxis =
{
    StepperYStep,
    StepperYCurrent,
    { TableYHandler, 0 },
    false,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
};

//*****************************************************************************
//
//! The state structure for the Z axis.
//
//*****************************************************************************
static tAxisState g_sZAxis =
{
    StepperZStep,
    StepperZCurrent,
    { TableZHandler, 0 },
    false,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
};

//*****************************************************************************
//
//! This variable is used when drawing a line using Bresenham's line drawing
//! algorithm.  If X is the major axis, this is the amount of accumulated error
//! that results in a step in the Y axis.  If Y is the major axis, this is the
//! error for each step in the Y axis.
//
//*****************************************************************************
static long g_lTableDeltaX;

//*****************************************************************************
//
//! This variable is used when drawing a line using Bresenham's line drawing
//! algorithm.  If Y is the major axis, this is the amount of accumulated error
//! that results in a step in the X axis.  If X is the major axis, this is the
//! error for each step in the X axis.
//
//*****************************************************************************
static long g_lTableDeltaY;

//*****************************************************************************
//
//! This variable is used when drawing a line using Bresenham's line drawing
//! algorithm.  This is the accumulated error as a result of stepping along the
//! major axis.
//
//*****************************************************************************
static long g_lTableError;

//*****************************************************************************
//
//! The virtual timer used for timing the steps of the homing operation.
//
//*****************************************************************************
static tVirtualTimer g_sHomeTimer =
{
    TableHomeHandler,
    0
};

//*****************************************************************************
//
//! The homing state of the CNC machine.  This will be one of
//! #STATE_NEEDS_HOMING, #STATE_HOMING1, #STATE_HOMING2, #STATE_HOMING3,
//! #STATE_HOMING4, or #STATE_HOMED.
//
//*****************************************************************************
static volatile unsigned long g_ulHomeState;

//*****************************************************************************
//
//! This homing state, for use in #g_ulHomeState, indicates that the table is
//! in an unknown position and a homing operation is required.
//
//*****************************************************************************
#define STATE_NEEDS_HOMING      0

//*****************************************************************************
//
//! This homing state, for use in #g_ulHomeState, indicates that a homing
//! operation is in progress and that the Z axis is being rapidly moved toward
//! the home position.
//
//*****************************************************************************
#define STATE_HOMING1           1

//*****************************************************************************
//
//! This homing state, for use in #g_ulHomeState, indicates that a homing
//! operation is in progress and that the X and Y axes are being rapidly moved
//! toward the home position.
//
//*****************************************************************************
#define STATE_HOMING2           2

//*****************************************************************************
//
//! This homing state, for use in #g_ulHomeState, indicates that a homing
//! operation is in progress and that the Z axis is being slowly moved away
//! from the limit switch.
//
//*****************************************************************************
#define STATE_HOMING3           3

//*****************************************************************************
//
//! This homing state, for use in #g_ulHomeState, indicates that a homing
//! operation is in progress and that the X and Y axes are being slowed moved
//! away from the limit switches.
//
//*****************************************************************************
#define STATE_HOMING4           4

//*****************************************************************************
//
//! This homing state, for use in #g_ulHomeState, indicatea that the table does
//! not require a homing operation and that the table position is therefore
//! known.
//
//*****************************************************************************
#define STATE_HOMED             5

//*****************************************************************************
//
//! Computes the initial value of C.
//!
//! \param w is the rate of acceleration, specified in steps per second^2.
//!
//! From David Austin's article, the starting inter-step delay is based on the
//! acceleration.
//!
//! \note This explicitly depends upon the processor clock being 50 MHz and
//! does not automatically adjust as most other things do.
//!
//! \return Returns the initial value of C, in 24.8 fixed-point notation.
//
//*****************************************************************************
#define GET_C0(w)               LongDiv256(70710678, isqrt(w))

//*****************************************************************************
//
//! Computes the number of steps to to accelerate to speed.
//!
//! \param s is the target speed, specified in steps per second.
//! \param w is the rate of acceleration, specified in steps per second^2.
//!
//! From David Austin's article, the number of steps to accelerate at the given
//! rate up to the given speed.
//!
//! \return Returns the number of steps required to reach the given speed at
//! the given constant rate of acceleration.
//
//*****************************************************************************
#define GET_NUM_STEPS(s, w)     ((((s) * (s)) + (w)) / (2 * (w)))

//*****************************************************************************
//
//! Computes the minimum inter-step delay.
//!
//! \param s is the target speed, specified in steps per second.
//!
//! From David Austin's article, the minimum inter-step delay based on the
//! maximum speed.
//!
//! \note This explicitly depends upon the processor clock being 50 MHz and
//! does not automatically adjust as most other things do.
//!
//! \return Returns the minimum value of C, in 24.8 fixed-point notation.
//
//*****************************************************************************
#define GET_CMIN(s)             LongDiv256(50000000, s)

//*****************************************************************************
//

⌨️ 快捷键说明

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