I heard about PIC-Step and I decided to try my hand at designing my own stepper controller. At the minute I am just working on the step sequence etc... and an algorithm that will allow me to compute 1, 1/2, 1/4, 1/8 etc step modes without the need for a large step table, I just thought I would share my progress so far. If anyone has any input I'd be more than happy to listen to it.
Also, I was considering using TIP-121 NPN Darlington transistors with a max Ic of 6A as my motors run at around 3A each @ 12v so there would be loads or leeway there...
All code is written for a 16F684 and is written in Hi-Tech C Lite.
StepperController.c
Code:
/*
// LEGAL JIBBER JABBER ----------------------------------------------------------------
PICNC FIRMWARE - PIC STEPPER MOTOR CONTROLLER
Copyright (C) 2007 STEVEN MOUGHAN <STEVEN@THEOBSOLETE.COM>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// WIRING CONNECTIONS ----------------------------------------------------------------
OUTPUTS
RA0 A1
RA1 B1
RA2 A2
RA3 B2
RA4 ERROR STATE (E-STOP)
RA5 OPERATIONAL (LIVE)
INPUTS
RC0 STEP MODE, 0 == FULL, 1 == HALF
RC1 ENABLE
RC2 DIRECTION (1 == FORWARDS)
RC3 STEP
RC4 RESET
RC5 E-STOP
*/
#include <pic.h> //STANDARD PIC HEADER FOR DEFINITIONS
#include "stepfunctions.h" //CUSTOM FUNCTIONS FOR STEPPER CONTROL
// CUSTOM DEFINITIONS -----------------------------------------------------------------
#define _STEP_DELAY 1
#define _MODE RC1
#define _ENABLE RC1
#define _DIRECTION RC2
#define _STEP RC3
#define _RESET RC4
#define _ESTOP RC5
#define _A1 RA0
#define _B1 RA1
#define _A2 RA2
#define _B2 RA3
#define _ERROR RA4
#define _OPERATIONAL RA5
// 1 2 3 4 5 6 7 8
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS & IESODIS & FCMDIS);
// 1: INTERNAL OSC
// 2: DISABLE WATCH DOG TIMER
// 3: 70mS TIME UP DELAY
// 4: DISABLE MCLR
// 5: DISABLE CODE PROTECTION
// 6: BROWN OUT DETECT DISABLED
// 7: INTERNAL EXTERNAL SWITCHOVER MODE DISABLED
// 8: FAIL-SAFE CLOCK
// VARIABLE DECLERATIONS --------------------------------------------------------------
// FUNCTIONS --------------------------------------------------------------------------
void step_forwards(void) {
if(!_MODE) {
fullstep_forwards();
} else {
halfstep_forwards();
}
delayMS(_STEP_DELAY);
}
void step_backwards(void) {
if(!_MODE) {
fullstep_backwards();
} else {
halfstep_backwards();
}
delayMS(_STEP_DELAY);
}
void idle(void) { //THIS WILL STOP THE PIC
_ERROR = 1; //SET ERROR LED
//_OPERATIONAL = 0; //CLEAR OPERATIONAL LED
while(1 == 1) { //IN CASE OF EMERGENCY
if(_RESET) { //CHECK FOR RESET
_ERROR = 0; //CLEAR ERROR LED
//_OPERATIONAL = 1; //SET OPERATIONAL LED
return; //RETURN TO MAIN
} //END IF
} //END WHILE
} //END IDLE
void main(void) {
CMCON0 = 7; //TURN OFF COMPARATORS
ANSEL = 0; //TURN OFF ADC
PORTA = 0x01; //INITIALISE PORTA TO 0x01
PORTC = 0x00; //INITIALISE PORTC TO 0x00
TRISA = 0b000000; //MAKE PORTA OUTPUT
TRISC = 0b111111; //MAKE PORTC INPUT
//_OPERATIONAL = 1; //SET OPERATIONAL LED
while(1 == 1) { //MAIN PROGRAM LOOP
if(RC5 == 1) { //IS ESTOP ACTIVATED
idle(); //IDLE UNTIL RESET
}
if(_STEP && _ENABLE) {
if(!_DIRECTION) {
step_backwards();
} else {
step_forwards();
}
}
} //END INFINATE LOOP
} //END MAIN stepfunctions.h
Code:
/*
// LEGAL JIBBER JABBER ----------------------------------------------------------------
PICNC FIRMWARE - PIC STEPPER MOTOR CONTROLLER
Copyright (C) 2007 STEVEN MOUGHAN <STEVEN@THEOBSOLETE.COM>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
int x,i,j; //VARIABLES FOR TIMERS
void delayMS(int time) { //CREATE A DELAY LASTING 'TIME' NUMBER OF mS
for(x=0;x<=time;x++) { //THIS LOOP SHOULD TAKE A TOTAL OF 1uS
for(i=0;i<=1;i++); //AND THESE LOOPS CONTROL IT
for(j=0;j<=60;j++);
} //END PERMUTATIONS LOOP
} //END DELAYMS - THIS IS FOR INTERNAL OSC AT 8MHz, IT PROVIDES 1.002mS DELAY PER LOOP
void fullstep_forwards(void) {
switch(PORTA) { // 2121
case(8):
PORTA = 0b0001;
break;
default:
PORTA = PORTA * 2;
break;
}
}
void halfstep_forwards(void) {
switch(PORTA) {
case(9):
PORTA = 0b0001;
break;
default:
PORTA++;
break;
}
}
void fullstep_backwards(void) {
switch(PORTA) {
case(1):
PORTA = 0b1000;
break;
default:
PORTA = PORTA / 2;
break;
}
}
void halfstep_backwards(void) {
switch(PORTA) {
case(1):
PORTA = 0b1001;
break;
default:
PORTA--;
break;
}
}