1 /**************************************************************************/
4 @author Based on original code by Tom Igoe
5 Modified by K. Townsend (microBuilder.eu)
7 @brief Simple bi-polar stepper motor controller, based on the
8 Arduino stepper library by Tom Igoe. Includes simple
9 position handling methods to keep track of the motor's
10 relative position and the spindle's current rotation.
17 #include "core/systick/systick.h"
18 #include "drivers/motor/stepper/stepper.h"
22 systemInit(); // Configure cpu and mandatory peripherals
24 stepperInit(200); // Initialise driver for 200-step motor
25 stepperSetSpeed(60); // Set speed to 60 rpm (1 revolution per second)
29 stepperStep(400); // Move forward 400 steps
30 stepperStep(-200); // Move backward 200 steps
31 systickDelay(1000); // Wait one second
33 // Move 'home' after 10 loops (current position = 2000)
34 if (stepperGetPosition() == 2000)
36 stepperMoveHome(); // Move back to the starting position
37 systickDelay(1000); // Wait one second
45 Software License Agreement (BSD License)
47 Copyright (c) 2010, microBuilder SARL
50 Redistribution and use in source and binary forms, with or without
51 modification, are permitted provided that the following conditions are met:
52 1. Redistributions of source code must retain the above copyright
53 notice, this list of conditions and the following disclaimer.
54 2. Redistributions in binary form must reproduce the above copyright
55 notice, this list of conditions and the following disclaimer in the
56 documentation and/or other materials provided with the distribution.
57 3. Neither the name of the copyright holders nor the
58 names of its contributors may be used to endorse or promote products
59 derived from this software without specific prior written permission.
61 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
62 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
65 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
67 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
68 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72 /**************************************************************************/
76 #include "core/gpio/gpio.h"
77 #include "core/timer32/timer32.h"
79 static int64_t stepperPosition
= 0; // The current position (in steps) relative to 'Home'
80 static uint32_t stepperStepNumber
= 0; // The current position (in steps) relative to 0°
81 static uint32_t stepperStepsPerRotation
= 0; // Number of steps in a full 360° rotation
82 static uint32_t stepperStepDelay
= 0; // Delay in CPU ticks between individual steps
84 /**************************************************************************/
86 Private - Cause the motor to step forward or backward one step
88 /**************************************************************************/
89 void stepMotor(uint32_t thisStep
)
94 gpioSetValue(STEPPER_IN1_PORT
, STEPPER_IN1_PIN
, 1);
95 gpioSetValue(STEPPER_IN2_PORT
, STEPPER_IN2_PIN
, 0);
96 gpioSetValue(STEPPER_IN3_PORT
, STEPPER_IN3_PIN
, 1);
97 gpioSetValue(STEPPER_IN4_PORT
, STEPPER_IN4_PIN
, 0);
100 gpioSetValue(STEPPER_IN1_PORT
, STEPPER_IN1_PIN
, 0);
101 gpioSetValue(STEPPER_IN2_PORT
, STEPPER_IN2_PIN
, 1);
102 gpioSetValue(STEPPER_IN3_PORT
, STEPPER_IN3_PIN
, 1);
103 gpioSetValue(STEPPER_IN4_PORT
, STEPPER_IN4_PIN
, 0);
106 gpioSetValue(STEPPER_IN1_PORT
, STEPPER_IN1_PIN
, 0);
107 gpioSetValue(STEPPER_IN2_PORT
, STEPPER_IN2_PIN
, 1);
108 gpioSetValue(STEPPER_IN3_PORT
, STEPPER_IN3_PIN
, 0);
109 gpioSetValue(STEPPER_IN4_PORT
, STEPPER_IN4_PIN
, 1);
112 gpioSetValue(STEPPER_IN1_PORT
, STEPPER_IN1_PIN
, 1);
113 gpioSetValue(STEPPER_IN2_PORT
, STEPPER_IN2_PIN
, 0);
114 gpioSetValue(STEPPER_IN3_PORT
, STEPPER_IN3_PIN
, 0);
115 gpioSetValue(STEPPER_IN4_PORT
, STEPPER_IN4_PIN
, 1);
120 /**************************************************************************/
122 @brief Initialises the GPIO pins and delay timer and sets any
126 The number of steps per rotation (typically 200 or 400)
128 /**************************************************************************/
129 void stepperInit(uint32_t steps
)
131 // Setup motor control pins
132 gpioSetDir(STEPPER_IN1_PORT
, STEPPER_IN1_PIN
, 1);
133 gpioSetDir(STEPPER_IN2_PORT
, STEPPER_IN2_PIN
, 1);
134 gpioSetDir(STEPPER_IN3_PORT
, STEPPER_IN3_PIN
, 1);
135 gpioSetDir(STEPPER_IN4_PORT
, STEPPER_IN4_PIN
, 1);
137 gpioSetValue(STEPPER_IN1_PORT
, STEPPER_IN1_PIN
, 0);
138 gpioSetValue(STEPPER_IN2_PORT
, STEPPER_IN2_PIN
, 0);
139 gpioSetValue(STEPPER_IN3_PORT
, STEPPER_IN3_PIN
, 0);
140 gpioSetValue(STEPPER_IN4_PORT
, STEPPER_IN4_PIN
, 0);
142 // Set the number of steps per rotation
143 stepperStepsPerRotation
= steps
;
145 // Set the default speed (2 rotations per second)
146 stepperSetSpeed(120);
149 /**************************************************************************/
151 @brief Gets the current position (in steps) relative to 'Home'.
153 @return The difference (in steps) of the motor's current position
154 from the original 'Home' position. Value can be negative or
155 positive depending on the direction of previous movements.
157 /**************************************************************************/
158 int64_t stepperGetPosition()
160 return stepperPosition
;
163 /**************************************************************************/
165 @brief Gets the motor's current rotation (in steps) relative to
166 the spindle's 'Zero' position.
168 @return The current step (0 .. steps per rotation) on the motor's
169 spindle relative to 0°. Value is always positive.
171 /**************************************************************************/
172 uint32_t stepperGetRotation()
174 return stepperStepNumber
;
177 /**************************************************************************/
179 @brief Sets the motor's current position to 'Home', meaning that
180 any future movement will be relative to the current
183 /**************************************************************************/
184 void stepperSetHome()
189 /**************************************************************************/
191 @brief Moves the motor back to the original 'Home' position.
193 /**************************************************************************/
194 void stepperMoveHome()
196 stepperStep(stepperPosition
* -1);
199 /**************************************************************************/
201 @brief Saves the spindle's current angle/position as 0°. Each
202 step the spindle takes will now be relative to the spindle's
205 /**************************************************************************/
206 void stepperSetZero()
208 stepperStepNumber
= 0;
211 /**************************************************************************/
213 @brief Moves the motor to its original rotation value. For example,
214 if a 200-step motor is currently rotated to step 137, it
215 will move the motor forward 63 steps to end at step 0 or 0°.
217 /**************************************************************************/
218 void stepperMoveZero()
220 if (!stepperStepNumber
)
222 stepperStep(stepperStepsPerRotation
- stepperStepNumber
);
226 /**************************************************************************/
228 @brief Sets the motor speed in rpm, meaning the number of times the
229 motor will fully rotate in a one minute period.
232 Motor speed in revolutions per minute (RPM)
234 @warning Not all motors will function at all speeds, and some trial
235 and error may be required to find an appropriate speed for
238 /**************************************************************************/
239 void stepperSetSpeed(uint32_t rpm
)
241 uint32_t ticksOneRPM
= ((CFG_CPU_CCLK
/SCB_SYSAHBCLKDIV
) / stepperStepsPerRotation
) * 60;
244 stepperStepDelay
= ticksOneRPM
/ rpm
;
246 // Initialise 32-bit timer 0 with the appropriate delay
247 timer32Init(0, stepperStepDelay
);
251 /**************************************************************************/
253 @brief Moves the motor forward or backward the specified number
254 of steps. A positive number moves the motor forward,
255 while a negative number moves the motor backwards.
258 The number of steps to move foreward (positive) or
261 /**************************************************************************/
262 void stepperStep(int32_t steps
)
264 uint32_t stepsLeft
= abs(steps
); // Force number to be positive
266 while (stepsLeft
> 0)
268 // Wait 1 tick between individual steps
271 // Increment or decrement step counters (depending on direction)
274 stepperPosition
++; // Increment global position counter
275 stepperStepNumber
++; // Increment single rotation counter
276 if (stepperStepNumber
== stepperStepsPerRotation
)
278 stepperStepNumber
= 0;
283 stepperPosition
--; // Decrement global position counter
284 if (stepperStepNumber
== 0)
286 stepperStepNumber
= stepperStepsPerRotation
;
288 stepperStepNumber
--; // Decrement single rotation counter
291 // Decrement number of remaining steps
294 // Step the motor one step
295 stepMotor(stepperStepNumber
% 4);
This page took 0.061081 seconds and 5 git commands to generate.