Control of a UniPolar Stepping Motor

copyright, Peter H. Anderson, Baltimore, MD, Nov, '99

Program Stepper_1 illustrates how to control a unipolar stepping motor.

The lower nibble of PORTC (pins 12, 11, 10 and 9) are used to interface with four sections of a ULN2803 Octal Darlington driver which drives a unipolar stepper. Note that a logic one on a BX24 output turns on the Darlington transistor which causes current to flow in the corresponding stepping motor winding.

The stepper is controlled in the half-step mode by energizing one of four windings and then two adjacent, and then the second winding alone, etc. Array Patts() has been defined in this manner. Advancing the motor in one direction is then a matter of sequentially outputting each pattern moving down through the array and the other direction by sequentially outputting moving up through the array.

The amount of travel is determined by the number of steps which are output. For a 7.5 degree motor, a full revolution is 48 full steps or 96 half steps.

The speed of the motor is determined by the amount of time between outputting each pattern.

In program Stepper_1.Bas, PortC is configured for inputs on the high nibble and for outputs on the lower nibble using the DDRC register. (Note that the inputs are not used in this routine.

Note that in outputting the pattern on the low nibble without changing what is on the high nibble of PORTC is performed by reading PORTC, making the lower four bits to 0000 (using the AND operator) and then ORing the Patt into the lower nibble.

  Register.PORTC = (Register.PORTC AND bx11110000) OR Patts(Index)
In turning the motor in one direction, Index is incremented, but if it extends beyond the array (8), it is set to 1. In turning the motor in the other direction, Index is decremented, but if it is less than 1, it is set to 8.

' Stepper_1.Bas
' Turns stepper one revolution one way and then other way one-half 
' revolution.
' copyright, Peter H. Anderson, Baltimore, MD, Nov, '99

Const CW as Byte = 0
Const CCW as Byte = 1

Sub Main()

   Dim Patts(1 to 8) as Byte

   Patts(1) = bx00000001	' define stepping motor patts
   Patts(2) = bx00000011
   Patts(3) = bx00000010
   Patts(4) = bx00000110
   Patts(5) = bx00000100
   Patts(6) = bx00001100
   Patts(7) = bx00001000
   Patts(8) = bx00001001

   Register.DDRC = bx00001111	' high nib are input, low nib outputs

   Call TurnMotor(Patts, CW, 96, 0.01)	' 96 half steps
   Call TurnMotor(Patts, CCW, 48, 0.1)	' 48 half steps

End Sub

Sub TurnMotor(ByRef Patts() as Byte, ByVal Dir as Byte, _
              ByVal Steps as Integer, ByVal TimeStep as Single)

   Dim Index as Integer, N as Integer

   Index = 1

   For N = 1 To Steps
      Register.PORTC = (Register.PORTC AND bx11110000) OR Patts(Index)
      Call Delay(TimeStep)

      If (Dir = 0) Then
         Index = Index + 1
         If (Index > 8) Then
            Index = 1
         End If
         Index = Index - 1
         If (Index < 1) Then
            Index = 8
         End If
      End If         
End Sub