Created
February 10, 2016 15:05
-
-
Save mstaflex/97fe348dd2b5c36eea48 to your computer and use it in GitHub Desktop.
C program that lets a connected stepper motor swing back and forth through a run-time defined angle with a run-time defined speed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define N_EN PORTB.f2 | |
#define TRIS_N_EN TRISB.f2 | |
#define MS1 PORTB.f1 | |
#define TRIS_MS1 TRISB.f1 | |
#define MS2 PORTB.f0 | |
#define TRIS_MS2 TRISB.f0 | |
#define MS3 PORTA.f5 | |
#define TRIS_MS3 TRISA.f5 | |
#define N_RST PORTA.f4 | |
#define TRIS_N_RST TRISA.f4 | |
#define N_SLP PORTA.f3 | |
#define TRIS_N_SLP TRISA.f3 | |
#define STEP PORTA.f2 | |
#define TRIS_STEP TRISA.f2 | |
#define DIR PORTA.f1 | |
#define TRIS_DIR TRISA.f1 | |
#define SWITCH PORTA.f0 | |
#define TRIS_SWITCH TRISA.f0 | |
#define STEP_DIVISOR 16 | |
#define MAX_SPEED 400 | |
#define MIN_SPEED 50 | |
#define DELAY_STEP 300 | |
unsigned short wait = 0; | |
unsigned short direction = 0; | |
unsigned int delayCounter = 0; | |
unsigned int delayValue = 0; // microsteps not included in this value | |
unsigned int delayCounterMax = 0; | |
unsigned int stepCounter = 0; | |
unsigned int stepStart = 0; | |
unsigned int stepCounterMax = 0; | |
unsigned short subStepCounter = 0; | |
unsigned int speed = 80; // in steps pro second | |
short writeDelayValue = 0; | |
unsigned int clock = 0; | |
short stepIncrement = 1; | |
unsigned short switchLatch = 0; | |
short buttonClickCounter = 0; | |
unsigned int buttonClickDelay = 0; | |
void setMS(short microSteps) { | |
if ((microSteps == 2) || (microSteps == 8) || (microSteps == 16)) | |
MS1 = 1; | |
else | |
MS1 = 0; | |
if ((microSteps == 4) || (microSteps == 8) || (microSteps == 16)) | |
MS2 = 1; | |
else | |
MS2 = 0; | |
if (microSteps == 16) | |
MS3 = 1; | |
else | |
MS3 = 0; | |
} | |
unsigned int calculateDelay(unsigned int velocity) { | |
unsigned long calc = (1000000L / (unsigned long) velocity); | |
return (unsigned int) calc; | |
} | |
void stepping(unsigned int delayTime) { | |
unsigned int t = 0; | |
STEP = 1; | |
Delay_us(2); | |
STEP = 0; | |
for (t=0; t<delayTime; t++) | |
Delay_ms(1); | |
} | |
void main() { | |
ADCON1 = 0x0f; // disable all analog inputs | |
TRIS_SWITCH = 1; | |
TRIS_N_EN = 0; | |
TRIS_MS1 = 0; | |
TRIS_MS2 = 0; | |
TRIS_MS3 = 0; | |
TRIS_N_RST = 0; | |
TRIS_N_SLP = 0; | |
TRIS_STEP = 0; | |
TRIS_DIR = 0; | |
N_EN = 0; | |
setMS(1); | |
N_RST = 1; | |
N_SLP = 1; | |
STEP = 0; | |
DIR = 1; | |
T0CON.PSA = 0; | |
// PreScaler of 000 -> 1/2 => 1us | |
T0CON.T0PS2 = 0; | |
T0CON.T0PS1 = 0; | |
T0CON.T0PS0 = 0; | |
T0CON.T0CS = 0; | |
T0CON.T08BIT = 0; | |
T0CON.TMR0ON = 0; // enabled later | |
T1CON.RD16 = 1; | |
T1CON.TMR1ON = 1; | |
RCON.IPEN = 1; // Int priorities enabled | |
PIE1.TMR1IE = 1; | |
IPR1.TMR1IP = 0; // TMR1 gets low priority | |
INTCON.TMR0IE = 1; | |
INTCON.GIE = 0; // enaled after setup phase | |
INTCON.GIEL = 1; | |
stepCounterMax = EEPROM_Read(0) + (EEPROM_Read(1) << 8); | |
delayValue = EEPROM_Read(2) + (EEPROM_Read(3) << 8); | |
stepStart = EEPROM_Read(4) + (EEPROM_Read(5) << 8); | |
delayCounter = delayValue / STEP_DIVISOR; | |
// Rotation angle setup | |
if (!SWITCH) { | |
stepCounter = 0; | |
setMS(1); | |
while (!SWITCH); | |
while (SWITCH) { | |
stepCounter++; | |
stepping(50); | |
} | |
stepStart = stepCounter; | |
EEPROM_Write(4, stepStart); | |
EEPROM_Write(5, stepStart >> 8); | |
stepCounter = 0; | |
while (!SWITCH); | |
while (SWITCH) { | |
stepCounter++; | |
stepping(50); | |
} | |
while (!SWITCH); | |
stepCounterMax = stepCounter; | |
stepCounter = 0; | |
EEPROM_Write(0, stepCounterMax); | |
EEPROM_Write(1, stepCounterMax >> 8); | |
} | |
// end rotation angle setup | |
// going to zero position | |
N_RST = 0; | |
Delay_ms(1000); | |
N_RST = 1; | |
while (stepCounter++ < stepStart) | |
stepping(40); | |
stepCounter = 0; | |
// end going to zero position | |
setMS(STEP_DIVISOR); | |
INTCON.GIE = 1; | |
T0CON.TMR0ON = 1; | |
while (1) { | |
while (!switchLatch && (buttonClickCounter==0)) { | |
if (SWITCH) break; | |
speed += stepIncrement; | |
if (speed > MAX_SPEED) | |
speed = MIN_SPEED; | |
delay_ms(15); | |
delayValue = calculateDelay(speed); | |
delayCounter = delayValue / STEP_DIVISOR; | |
writeDelayValue = 1; | |
} | |
if (writeDelayValue) { | |
writeDelayValue = 0; | |
EEPROM_Write(2, delayValue); | |
EEPROM_Write(3, delayValue >> 8); | |
} | |
} | |
} | |
void interrupt_low() { | |
TMR1H = 0xF8; | |
TMR1L = 0x2f; | |
clock++; | |
PIR1.TMR1IF = 0; | |
} | |
void interrupt() { | |
unsigned int rms = 0xffff - delayCounter; | |
TMR0H = rms >> 8; | |
TMR0L = rms; | |
STEP = 1; | |
Delay_us(1); | |
STEP = 0; | |
subStepCounter++; | |
if (subStepCounter >= STEP_DIVISOR) { | |
subStepCounter = 0; | |
stepCounter++; | |
} | |
if (stepCounter > stepCounterMax) { | |
DIR = (DIR + 1) & 1; | |
stepCounter = 0; | |
} | |
INTCON.TMR0IF = 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment