Micro Steps

/*
 *  microstepper.c
 *  
 *  Created by Will Gallia on 25/01/2011.
 *
 */

#include <avr/io.h>
#define F_CPU 1000000UL 
#include <util/delay.h>

#define PORT PORTC
#define DDR DDRC

#define DIR PORTC5
#define DIR_DDRPIN DDC5

#define STEP PORTC4
#define STEP_DDRPIN DDC4

#define SLEEP PORTC3
#define SLEEP_DDRPIN DDC3

#define MS1 PORTC2
#define MS1_DDRPIN DDC2

#define MS2 PORTC1
#define MS2_DDRPIN DDC1

void delay_ms(unsigned int n);
void turn(unsigned char dir, unsigned char wait, unsigned int nsteps);
void setStepMode(unsigned char m);

int main(void) {
	
	//set all pins as output
	DDR |= (1<<DIR_DDRPIN);
	DDR |= (1<<STEP_DDRPIN);
	DDR |= (1<<SLEEP_DDRPIN);
	DDR |= (1<<MS1_DDRPIN);
	DDR |= (1<<MS2_DDRPIN);
	
	//the pause between steps
	unsigned int steptime = 8;
	unsigned char nosteps = 200; // one full revolution in full step
	unsigned char mode = 1;
	
	//set sleep to high
	PORT |= (1<<SLEEP);
			
	while (mode < 5) {
		
		setStepMode(mode);
		
		//go one way
		turn(0, steptime, nosteps);
		//and the other way
		turn(1, steptime, nosteps);
		
		steptime /= 2;
		mode++;
		
		if(mode > 4) {
			mode = 1;
			steptime = 8;
			delay_ms(500);
		}
	}
	return 0;
}

void setStepMode(unsigned char m) {
		switch (m) {
			case 1:
				//full step, both to 0
				PORT &= ~(1<<MS1);
				PORT &= ~(1<<MS2);
				break;
			case 2:
				//half step, ms1 = 1, ms2 = 0;
				PORT |= (1<<MS1);
				PORT &= ~(1<<MS2);
				break;
			case 3:
				//quarter step, ms1 = 0,ms2 = 0;
				PORT &= ~(1<<MS1);
				PORT |= (1<<MS2);
				break;
			case 4:
				//eighth step, both to 1
				PORT |= (1<<MS1);
				PORT |= (1<<MS2);
				break;
			default:
				break;
		}
}

void turn(unsigned char dir, unsigned char wait, unsigned int nsteps) {
	//set the direction, 0V
	if(dir) PORT &= ~(1<<DIR);
	else PORT |= (1<<DIR);
	
	int i;
	for (i = 0; i < nsteps; i++) {
		//set low
		PORT &= ~(1<<STEP);
		//set high
		PORT |= (1<<STEP);
		delay_ms(wait);
	}
	delay_ms(100);
	
}

void delay_ms(unsigned int n) {
	while (n) {
		_delay_ms(0.96);
		n--;
	}
}