El LED no puede dejar de parpadear (AVR-C)

0

Así que aquí está la base de mi código, tengo una serie de instrucciones diferentes para que sigan los LED prescritos.

El led parpadeará el número de veces prescrito en una interrupción antes de detenerse e incrementará el valor de la matriz, lo que llevará al segundo conjunto de instrucciones en las matrices para el led.

Aquí está mi problema, ya que el programa ejecuta el primer conjunto de instrucciones de la matriz, cuando ab = 0 funciona bien, sin embargo, cuando ejecuto el segundo conjunto de instrucciones, cuando ab = 1 , el led soy tratando de parpadear infinitamente sin parar

He intentado todo para detener el led, desde las declaraciones boolean if , hasta deshabilitar las interrupciones pero nada funciona.

En el programa hay una variable que tengo que restablecer a cero, que es el x_counter (que trabaja solo con el eje x para hacerlo simple), para que pueda suceder el segundo conjunto de instrucciones

Sin embargo, sospecho que es la razón por la que continúa funcionando para siempre.

¿Alguna idea sobre cómo solucionar este problema? Aquí está mi código:

 /////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 ++;
                }    

                //////////////////////////////
            }  
        } 
    }        
    
pregunta Redrachet2

1 respuesta

1

algunos de los problemas más obvios con el código.

'ab' no se está incrementando durante el 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)

no puede borrar el indicador de interrupción del temporizador al final del ISR, lo que resulta en:

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

¿Es la velocidad de interrupción lo suficientemente lenta como para dar tiempo al CNC (o lo que sea)? ¿Dispositivo para completar el paso antes de que ocurra la siguiente interrupción?

    
respondido por el user3629249

Lea otras preguntas en las etiquetas