/******************************************************************** * FileName: Stepper_Motor_using_interrupts.c * Processor: PIC18F4520 * Compiler: MPLAB C18 v.3.36 * * This file uses the timer 0 to set an interrupt event. When the * interrupt occurs, it changes the RC0:RC4 state. You can modify * code within the high priority interrupt to change how often the * interrupt occurs. * * H-Bridge connections for driving a stepper motor. * RC0 = L293 Enable line * RC1 = Phase A control line * RC2 = Phase A control line * RC3 = Phase B control line * RC4 = Phase B control line * * Author Date Comment * David Fisher 9/25/07 Created * David Fisher 12/18/09 Moved enable line to RB0 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /** Processor Header Files *****************************************/ #include #include /** Define Constants Here ******************************************/ #define STEP1 0b00010100 #define STEP2 0b00010010 #define STEP3 0b00001010 #define STEP4 0b00001100 #define ENABLE_PIN 0b00000001 /** Local Function Prototypes **************************************/ void low_isr(void); void high_isr(void); // ============================================================ // Configuration Bits // ============================================================ #pragma config OSC = INTIO67 // Use the internal oscillator #pragma config WDT = OFF #pragma config LVP = OFF #pragma config BOREN = OFF #pragma config XINST = OFF /** Declare Interrupt Vector Sections ****************************/ #pragma code high_vector=0x08 void interrupt_at_high_vector(void) { _asm goto high_isr _endasm } #pragma code low_vector=0x18 void interrupt_at_low_vector(void) { _asm goto low_isr _endasm } /** Global Variables *********************************************/ char recentState = STEP1; /***************************************************************** * Function: void main(void) ******************************************************************/ #pragma code void main(void) { // Run the clock at 500 kHz (I could've picked about anything) OSCCONbits.IRCF2 = 0; OSCCONbits.IRCF1 = 1; OSCCONbits.IRCF0 = 1; // Setup the timer with a 1:4 prescaler with 16 bits resolution // Therefore the timer0 freq is 500 kHz / 4 / 4 = 31.25 kHz OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_4 ); // Should take a little over 2 seconds to overflow the counter from TMR0 = 0 // If you write in a different starting value for TMR0 it'll overflow sooner WriteTimer0(65530); // Start the timer at a some high value to get to the ISR the first time asap // Enable Global interrupts INTCONbits.GIE = 1; // Enable High priority interrupt // Setup the digital IO pins ADCON1 = 0x0F; // Make sure they are digital not analog TRISC = 0xE0; // Make the RC4:RC0 outputs PORTC = 0x00; // Clear the bits to start with while (1) { // A blank while loop, think of all the things you could do here! // When you use an interrupt the main loop is free for something else } } /***************************************************************** * Function: void high_isr(void) * Overview: This interrupt changes the state of the RC4:RC0 pins when * the timer zero overflows (0xFFFF -> 0x0000) and triggers * this interrupt code to run ******************************************************************/ #pragma interrupt high_isr void high_isr(void) { // Check whether it was the timer interrupt that got us here // (better be, since that's the only interrupt right now) if(INTCONbits.TMR0IF) { INTCONbits.TMR0IF = 0; // Clear interrupt flag for timer 0 switch (recentState) { case STEP1: recentState = STEP2; break; case STEP2: recentState = STEP3; break; case STEP3: recentState = STEP4; break; case STEP4: recentState = STEP1; break; default: recentState = STEP1; break; } PORTC = recentState | ENABLE_PIN; // The Timer0 frequency is 31.25 kHz // Pick where to start the time to determine how fast it overflows // Every overflow, the stepper motor will take a single step //WriteTimer0(3036); // 1 step every 2 seconds //WriteTimer0(18661); // 1 step every 1.5 seconds //WriteTimer0(34286); // 1 step every 1 seconds WriteTimer0(49911); // 1 step every 0.5 seconds //WriteTimer0(57723); // 1 step every 0.25 seconds //WriteTimer0(62411); // 1 step every 0.1 seconds //WriteTimer0(63973); // 20 step every second //WriteTimer0(64911); // 50 step every second //WriteTimer0(65224); // 100 step every second //WriteTimer0(65380); // 200 step every second } } /****************************************************************** * Function: void low_isr(void) * Input: * Output: * Overview: ********************************************************************/ #pragma interruptlow low_isr void low_isr(void) { // no low isr }