📄 table.c
字号:
//*****************************************************************************
//
// 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 + -