In this section you will find the essential knowledge you require to get you started with stepper motors. The example illustrated here does not serve any purpose other then to educate but is built on a platform where you can do anything you wish, from simply spinning up to 8-steppers to controlling the exact movement of your steppers via the serial port on your computer. The Atmel chip used is extremely powerful and versatile.
As you may already know, microcontrollers are only the brains of a circuit, and no muscle. What this means is that alone they cannot drive such a large load as a stepper motor, an incandescent lamp, a solenoid or anything with a low impedance, usually they barely have enough power to drive an LED. The Atmel AT90S8515 is good in the sense that it can drive an LED without any problem, but if you try to drive the motor directly, you will burn the internal pull-up circuit and then you'll have a crippled microcontroller on your hand that can only pull down or not use that port at all. This is why you need to design a driver circuit that can power the steppers and is itself controlled by the microcontroller. Below is a very simple schematic of how you'd do this.

To help place an overall picture of how things should loko like in the end, here are a two pictures of the finished circuit.
The transistor used was a MPS2222A, which is a general purpose NPN transistor, capable of sinking up to 600mA DC. Each one of these transistors can drive ONE coil of the stepper motor, so for the motor used in this example, 4 identical circuits are required. Your other option is to use a driver, which was specially design for this, but I believe this is more constructive and easier to work with. The driver is basically just an array of circuits like the one above, all built into an IC.
Here I assume you have a programmer (hardware not you) and also are using AVR Studio 4.0. If you don't know what I'm talking about, then consult the Atmel website for information and to get your free AVR Studio.
Before you go on, you need to understand how a stepper works, and why it is different then a regular motor. Firs of all, you should know that you cannot just spin a stepper by hooking it up to a battery, simply because it requires the driving circuit. What this circuit does, is it 'times' the coils inside the motor and by doing so (timing them properly is key) the shaft or the core of the motor advances and spins, the faster the timing the faster it spins. Each timing 'click' is a step, and the size of the step can tell you how smooth the motor can spin and also how slowly you can spin if before it starts jumping, rather then spinning. The motor used here, has a 1.8 deg step size, or it requires 200 steps to make one full revolution. The next thing you absolutely need to know about your motor is the stepping sequence, which is a table showing you which coil is powered, and when it is powered. This information is provided by the manufacturer or you need to figure it out somehow. (there are ways, but it is beyond the scope of this section)
The stepping sequence for the motor used here is shown in the table bellow.
| Coil | Coil 1 | Coil 2 | Coil 3 | Coil 4 |
| Step 0 | OFF | ON | OFF | ON |
| Step 1 | OFF | ON | ON | OFF |
| Step 2 | ON | OFF | ON | OFF |
| Step 3 | ON | OFF | OFF | ON |
| Step 4 | OFF | ON | OFF | ON |
Although the code is documented it can look a little intimidating if this is your first ASM program, but keep in mind that just like in C or BASIC the CPU goes through it one line at a time and so you can read it just like the CPU does, so don't let it scare you. If you do not know the syntax, then go to Atmel.com and download the specs for the ATMEL AT90S8515 and look on the Instruction Set Table.
The code really has two sections, the first and the most important when working with microcontrollers are the initializations and getting everything set up. In this case, you need to first set the port that drives the motors as an output using the DDR (data direction register) register. Then, you have to initialize the stack pointer, this is required if you do function or sub calls, such as RCALL. Once that is done, you get down to the real programming, first you need to understand that the microcontroller is much much too fast for the motor, so you need to write a delay function that just waists time, and gives the motor time to move and the coils stabilize. Then you need to write the code that 'steps' through the sequence table, this is just a 4 step loop, and really does nothing but go from step 1 to 3 and starts again, if you need to make the motor go backwards, you step through the table backwards, step 3 to 1.
Here is the code, you can just cut and paste it into AVR Studio.
;################################# ;Ptepper Motor Driver/Sequencer ; 2 Phase Stepper Motor ; 5.3V 0.17A ; 31.5 R/1.8 deg ;################################# ;***** Includes .include "8515def.inc" ;***** Global Register Variables .equ Step0 =0b00000101 ; This is the steping sequence CW .equ Step1 =0b00000110 ; You can alter this for diff motors .equ Step2 =0b00001010 ; should obtain this from the specs. .equ Step3 =0b00001001 .equ STable =0x0060 ;Start of step table (uses up 4 bytes) .equ delayCNT=0x12FF ;0AFF ~ 132.8 Hz @4.096MHz -- max ;0BFF ~ 120.8 Hz @4.096Mhz ;0CFF ~ 110.8 Hz @4.096MHz -- smooth ;1FFF ~ 42.88 Hz @4.096MHz ~ 70 RPM .def temp =r17 ;temporary storage register .def temp2 =r16 ;temporary register 2 ;***** Interrupt Vectors or Handles RJMP RESET ;***** CODE ***** RESET: ;***** Initialize Stack ldi temp, HIGH(RAMEND) out SPH, temp ldi temp, LOW(RAMEND) out SPL, temp CLR temp ;***** Initialize Ports clr temp ; Set everything as input (high inp.) out DDRA, temp out DDRB, temp out DDRC, temp out DDRD, temp ldi temp, 0x0F out DDRB, temp ; Set Port B as output (careful with loading) ;***** Initialize Steping Table ; Please obtain this table from the manufacturers specs. ldi XL, low(STable) ; Point X to the begining of the step table ldi XH, high(STable) ldi temp, Step0 st X+, temp ; Now the sequencing is in SRAM ldi temp, Step1 st X+, temp ; Fast and easy to extract. ldi temp, Step2 st X+, temp ldi temp, Step3 st X, temp clr XL clr XH ;***** MAIN CODE ***** ldi R18, 200 ; Make 20 Full Rotations CW loop: rcall CW dec R18 brne loop ldi R18, 200 ; Make 20 Full Rotations CCW loop2: rcall CCW dec R18 brne loop2 done: rjmp done ; Start and End in the exact same spot ;********************* ;***** Delay delay: push temp push temp2 ldi temp, LOW(delayCNT) ; Load how many interations ldi temp2, high(delayCNT) ; the delay rutine should do. keepgoing: dec temp brne keepgoing dec temp2 brne keepgoing pop temp2 pop temp ret ;***** CW ; Spin the motor Clock Wise ; How many deg. depends on how many steps CW: push temp push temp2 push XL push XH ldi XH, high(STable) ldi XL, low(STable) ldi temp2, 20 ; Make a 1/4 turn and exit stepCW: ld temp, X+ out PORTB, temp cpi XL, STable+4 brne not4yet subi XL, 4 not4yet: rcall delay dec temp2 brne stepCW pop XH pop XL pop temp2 pop temp ret ;***** CCW ; Spin the motor Counter Clock Wise ; How many deg. depends on how many steps CCW: push temp push temp2 push XL push XH ldi XH, high(STable+4) ldi XL, low(STable+4) ldi temp2, 20 ; Make a 1/4 turn and exit stepCCW: ld temp, -X out PORTB, temp cpi XL, STable brne not4yet2 subi XL, -4 not4yet2: rcall delay dec temp2 brne stepCCW pop XH pop XL pop temp2 pop temp retTroubleshooting:
If the motor does not spin, and just vibrates, then you have to check your wiring and make sure that pin0 goes to coil 1 pin1 to coil 2 and so on. If the motor does not do anything, put an LED between GND and the microcontroller pins and check to see if they blink, if they do not, check you are looking at the correct port. If the LEDs blink but the motor does nothing, then make sure the transistors are wired properly. Check MPS2222A to find wiring and specs. If nothing works, something has gone terribly wrong and you need to go through the whole thing from beginning to end, and you have to check that the microcontroller is programmed properly. Also check to make sure the clocking is done properly and the XTAL is actually resonating and working properly.
The Code above, was tested and it works, it spinns the motor clock wise and the nit reverses and stops where it started from, this may not be true for motors with a different stepping size.