LED can’t stop blinking (AVR-C)

avrccncledstepper motor

So here is the basis of my code, I have an array of different instructions for the prescribed LEDs to follow.

The led will blink for the prescribed number of times in an interrupt before they stop and increment the array value, which will lead to the second set of instructions in the arrays for the led.

Here is my problem, as the program executes the first set of instructions from the array, when ab = 0, it works just fine, however when I execute the second set of instruction, when ab = 1, the led I am trying to infinitely blinks without stopping

I have tried everything to stop the led, from boolean if statements, to disabling interrupts but nothing is working.

In the program there is a variable which I have to reset to zero which is the x_counter (working with just the x-axis to keep it simple), so that the second set of instructions can happen

However I suspect that it is the reason why it continue to loop on forever.

Any ideas on how to fix this problem? Here is my code:

 /////EDITED///Again////////////////

                /*
         * avr_cnc.c
         *
         * Created: 2015-04-01 6:13:58 AM
         *  Author: Alvi
         */ 


        #include <avr/io.h>    
        #include <stdio.h>
        #include <util/delay.h> 
        #include <avr/interrupt.h>  
        //axis bools

        //////////////////
        // x-axis
        #define stp_x_led PB0
        #define dir_x_led PB1  

        ////////////// 
        // y-axis
        #define stp_y_led PD6
        #define dir_y_led PD7 

        ////////////  
        // z-zxis  
        #define stp_z_led PD4 
        #define dir_z_led PD5

        // PORTB 
        #define led_portx PORTB
        //////////// 
        /// PORTD
        #define led_portyz PORTD 
        ///////////  
        // PORTC 
        //#define led_portz PORTC 
        // DDR////////
        #define led_x_ddr DDRB  
        #define led_y_ddr DDRD 
        #define led_z_ddr DDRD
        #define F_CPU 16000000UL 

        int axis[] = {1,1};
        int direction[] = {1,0};
        int steps[] = {20,20}; 
        int entries = sizeof(axis)/sizeof(int) - 1; 
        int ab = 0; 
        int vay = 1; 

        static volatile int x_counter = 0; 
        static volatile int x_boolean = 1; 
        static volatile int y_counter = 0; 
        static volatile int y_boolean = 1;
        static volatile int z_counter = 0; 
        static volatile int z_boolean = 1;  
        ////////////////// 

        int direction_ab; 
        int steps_ab;  



        int main(void)
        {  

            ////// DDR setups /////////////////////////////////////////////////
            led_x_ddr |= ((1 << stp_x_led) | (1 << dir_x_led));   
            led_y_ddr |= ((1 << stp_y_led) | (1 << dir_y_led)); 
            led_z_ddr |= ((1 << stp_z_led) | (1 << dir_z_led));
            /////////////////////////////////////////////////////////// 


            TCCR1B |= (1 << WGM12);  // configuring timer 1 for ctc mode
            OCR1A = 4678;
            TIMSK1 |= (1 << OCIE1A); // enable ctc interrupt

            TCCR1B |= ((1 << CS12) | (1<< CS10)); //Start at 1024 prescaler 

            sei(); //Enable global interrupts

             //Sets ctc compare value to 1hz at 1mhz AVR clock, with prescaler of 64
            while(1)  
            {    


            }          

        } //end of main loop


        ISR(TIMER1_COMPA_vect)
        {   
            ///////Define which stepper, direction and how many steps in this code
            stepper_protocol(axis[ab],steps[ab],direction[ab]);  

            ////////////////////////////////////////////////////////////////////
        }

         stepper_protocol(enable,steps_ab,direction_ab){ 

            // checks if user enabled x-axis 

            if (ab < entries){
            if (enable == 1){
                //direction
                if (direction_ab == 1){ 
                    led_portx |= (1 << dir_x_led); 
                } 
                else if (direction_ab == 0){ 
                    led_portx &= ~ (1 << dir_x_led); 
                } 
                ///////////////////////////////
                //stepper logic 

                led_portx ^= (1 << stp_x_led);
                   if (x_counter >= steps_ab){ 

                        led_portx = (0 << stp_x_led);   
                        led_portx = (0 << dir_x_led);
                        x_boolean = 0;  
                        ab++; 
                        x_counter = 0;  
                    }     
                    if (x_boolean == 1){
                        x_counter ++;
                    }

            //////////////////////////////
            }   


            // checks if user enabled y-axis 
            else if (enable == 2){
                //directjion
                if (direction_ab == 1){ 
                    led_portyz |= (1 << dir_y_led); 
                } 
                else if (direction_ab == 0){ 
                    led_portyz &= ~ (1 << dir_y_led); 
                }  
                ///////////////////////////////
                //stepper logic
                led_portyz ^= (1 << stp_y_led);
                    if (y_counter >= steps_ab){ 
                        led_portyz &= ~ (1 << stp_y_led);  
                        y_boolean = 0;  
                        //vay = 1; 
                        ab ++;
                    }      
                if (y_boolean == 1){
                y_counter ++;
                }   
                //////////////////////////////
            } 

             // checks if user enabled z-axis 
            else if (enable == 3){
                //direction
                if (direction_ab == 1){ 
                    led_portyz |= (1 << dir_z_led); 
                } 
                else if (direction_ab == 0){ 
                    led_portyz &= ~ (1 << dir_z_led); 
                } 
                ///////////////////////////////
                //stepper logic
                led_portyz ^= (1 << stp_z_led);
                    if (z_counter >= steps_ab){ 
                        led_portyz &= ~ (1 << stp_z_led);  
                        z_boolean = 0; 
                        //vay = 1; 
                        ab ++;
                    }      
                if (z_boolean == 1){
                z_counter ++;
                }    

                //////////////////////////////
            }  
        } 
    }        

Best Answer

some of the more obvious problems with the code.

'ab' is not being incremented during the ISR,

so the interrupt continues forever
should turn OFF the timer & associated interrupt when 'ab' exceeds/equals 'entries'
(not every interrupt, just the timer interrupt)

fails to clear the timer interrupt pending flag at the end of the ISR, resulting in:

 the ISR will immediately re-execute, 
 rather than waiting for the timer to produce another interrupt event.

Is the interrupt rate slow enough to allow time for the CNC (or whatever) device to complete the step before the next interrupt occurs?