// Author: Andrew Wilson // Date: 6/28/2006 // Description: This program will control a stepper motor driver circuit. // it will monitor two inputs: analog potentiometer, and digital rpm sensor // the program will ramp the speed output of the motor depending on the // position of the potentiomenter. the rpm sensor will be used to ensure the // correct speed is maintained. #include <18F2520.h> #include "stepper_driver.h" #fuses HS, NOWDT, NOLVP #use delay(clock=CLOCKRATE) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PC) int16 timer1 = 0; int16 timer_step = 0; int16 timer_step_set = 0; int16 timer_debug_set = 0; int16 timer_debug = 0; void checkTimer() { timer1 = get_timer1(); set_timer1(0x0009); //start counting from zero (plus overhead) if(timer_step > timer1) timer_step -= timer1; else timer_step = 0x00; if(timer_debug > timer1) timer_debug -= timer1; else timer_debug = 0x00; } int main() { int16 v_reading; //the pic18f2550 has a 10-bit A-to-D converter //that will give us 255 possible steps (should be 1024, but wasn't working) int16 loop; setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); printf("Stepper Motor Interface v1, brought to you by:\n\r"); printf("Andrew Wilson\n\r"); printf("reconnsworld.com\n\r"); //this sets up PIN A0 as an analog-in pin. //it is OR'd with VSS_VDD which forces the pic to use // ground and VDD as reference voltages setup_adc_ports(AN0_TO_AN1 || VSS_VDD); //this (i think) sets the ADC to clock via the internal //instruction clock setup_adc(ADC_CLOCK_INTERNAL); set_adc_channel(1); //we will only be using this channel //no need to set it again. // Initialize stepper timing here timer_step_set = (int16)140; timer_debug_set = 5000; //.001/(1.0*CLOCKRATE/(1.0*CLOCKSCALER*PRESCALER)); // Initialize stepper motor pins here //----------------------------------- output_low(STEPPER_DIR); output_high(STEPPER_ENA); loop = 0; while(1) { if(timer_debug == 0) { output_toggle(PIN_A0); timer_debug = timer_debug_set; } //This works out to be 20mS -- don't have to scan that much if(loop == 100000) { loop = 0; v_reading = read_adc(); if(v_reading == 0) timer_step_set = MIN_INCS; else timer_step_set = (int16)((MAX_INCS-MIN_INCS)*( ((1.0)*v_reading) / (float)MAX_READING ) + MIN_INCS); //printf("%lu, %lu\n\r", v_reading, timer_step_set); //only use this for debug } if(timer_step == 0) { output_toggle(STEPPER_STP); timer_step = timer_step_set; } checkTimer(); loop++; } return 1; }