In this tutorial, we will explain how to drive a stepper motor using DC motor outputs.

About stepper motors

Stepper motors are widely used in many daily use devices requiring moves of a known and predictable amplitide, for instance printers.


StepperA stepper motor consists in a rotor made of a magnetic material and several coils. The figure at the left shows a simplified stepper motor. The coils are also called phases. This is a 2-phase motor. Let's suppose that the current flows in an arbitrary direction that we will call positive. In this case, the rotor will spin and stabilize so that it fits the magnetic orientation of the coils. If we then stop powering phase 0 and power phase 1, the rotor will spin a quarter turn to be aligned with phase 1 generated field. If we further stop powering phase 1 and power phase 0 with a negative current, the magnet will again spin a quarter turn and so on.


TamagawaThe stepper motor that we are going to use is a 200 steps / turn motor. As it's a 3V device, it's easy to use in small robotic developments.

In the last chapter about controlling a motor, we have explained how to power a DC motor in either way, forwards or backwards. We are going to use this feature and power both phases with DC motor outputs. One drawback of stepper motors is that they need two control circuits. In our case, we are going to use 2 DC motor outputs to control this motor.



The power sequence

From the above explaination, we can foresee the powering sequence.

  Phase 1 Phase 2
Step 1 + 0
Step 2 0 +
Step 3 - 0
Step 4 0 -

We can arbitrarily decide that phase 1 will be connected to motor 1 output, and phase 2 to motor 2.

Similarily, we can arbitrarily decide that phase 1 positive will be port1 pin5 = 1 and port1 pin 4 = 0. Similarily for phase 2, the positive way will be port1 pin3 = 1 and port 1 pin2 = 0.

The array becomes:

  P1.2 P1.3 P1.4 P1.5
Step 1 0 0 0 1
Step 2 0 1 0 0
Step 3 0 0 1 0
Step 4 1 0 0 0

Programming the sequence

Basically, we have to send the following sequence to port 1: 0x20, 0x08, 0x10, 0x04 or the reverse sequence if we want to go backwards. This can be easily done with a constant array:

const char PowSeq[4] = {0x20, 0x08, 0x10, 0x04};

Then we can hold a step variable incrementing cyclically from 0 to 3 (0, 1, 2, 3, 0, 1, 2, 3, et...). Incrementing step and setting port 1 to PowSeq[step] will achieve exactly what we intend..

Controlling speed

When we were controlling the speed of a DC motor, we were altering the duty ratio of the signal. Now we need to alter the frequency itself. Therefore we will change the timer's CCR0, not CCRx.

The program

The new thing in this program is that we will have 2 different interrupt routines. One will be for analog / digital interrupt and the othe will be for actually setting the motor pins at the right level. Unfortunately, this cannot be done automatically, and we have to use a timer with interrupt (i.e. we cannot use the PWM to do it automatically).

These 2 interrupt functions must be kept mutually exclusive. Otherwise, an interrupt may occure while processing another interrupt.

It will look like this (in pseudo-code):

--------------------void interruptADC(void) {    _DINT();    // Disable interrupts    // ADC specific code goes here    _EINT();    // Enable interrupts}void interruptStepper(void) {    _DINT();    // Disable interrupts    // Stepper specific code goes here    _EINT();    // Enable interrupts}--------------------

Both timers are set with interrupt (TxxCCTL0 |= CCIE;). The code is pretty straightforward. It should be noted that this is a simple multitask software and there is no need for a loop to make it run.

Here is a screen copt of the 4 wires states

4PhasesTraces 1 and 2 relate to the first coil, and 3, 4 relate to the second coil.

In this case, the duty ratio is always (almost) 25%. The 4 signals are simply time-shifted and mutually exclusive.





Some more comments:

  • If you stop the motor, you may choose to power all the phases off. It saves power, but the drawback is that the axis can be easily moved by the load. If you still power the last phase, then the motor is blocked, and the torque necessary to move it would be a lot higher.
  • Like any motor, it's possible to do half steps. In the principle explanation above, the motor had 4 steps per turn. If you power 2 phases at the same time, then the resulting field would be at 45 degrees, half way between the two steps. Similiarily, by controlling the current, you can move by quarter steps.

Download the C code

A summary of the first tutorials has been added as a downloadable zip file here.