Cómo usar interrupciones en micro C

4

Estoy haciendo un robot que puede seguir líneas, evitar obstáculos y seguir flechas. Escribí el código para seguir la línea y la flecha, pero no sé cómo implementar interrupciones con más de dos niveles de prioridad. ¿Puede alguien decirme cómo usar interrupciones para más de dos niveles de prioridad?

Código fuente -

unsigned short current_duty, old_duty, current_duty1, old_duty1;

void InitMain() {
  ANSEL  = 0;                         // Configure AN pins as digital
  ANSELH = 0;
  C1ON_bit = 0;                       // Disable comparators
  C2ON_bit = 0;

  PORTA = 255;
  TRISA = 255;                        // configure PORTA pins as input
  PORTB = 0;                          // set PORTB to 0
  TRISB = 0;                          // designate PORTB pins as output
  PORTC = 0;                          // set PORTC to 0
  TRISC = 0;                          // designate PORTC pins as output
  PORTD = 0;                          // set PORTC to 0
  TRISD = 0;                          // designate PORTC pins as output
  PWM1_Init(5000);                    // Initialize PWM1 module at 5KHz
  PWM2_Init(5000);                    // Initialize PWM2 module at 5KHz
}

void main() {
  InitMain();
  current_duty  = 255;                 // initial value for current_duty
  current_duty1 = 255;                 // initial value for current_duty1

  PWM1_Start();                        // start PWM1
  PWM2_Start();                        // start PWM2
  PWM1_Set_Duty(current_duty);         // Set current duty for PWM1
  PWM2_Set_Duty(current_duty1);        // Set current duty for PWM2

  while (1) {                          // endless loop

  PORTD.F4=1;
  PORTD.F5=0;
  PORTD.F6=1;
  PORTD.F7=0;

    if (PORTB.F1==1) {                 // turn L  moter L pwm1
      PWM1_Set_Duty(50);
      PWM2_Set_Duty(175);
      delay_ms(500);
      PWM1_Set_Duty(150);
      PWM2_Set_Duty(150);
     }

     if (PORTB.F3==1) {                    // turn R  moter L pwm1
      PWM1_Set_Duty(175);
      PWM2_Set_Duty(50);
      delay_ms(500);
      PWM1_Set_Duty(150);
      PWM2_Set_Duty(150);
     }

     if (PORTB.F2==1 &&  PORTB.F3==1) {                    // turn R  moter L pwm1
      PWM1_Set_Duty(175);
      PWM2_Set_Duty(25);
      delay_ms(500);
      PWM1_Set_Duty(150);
      PWM2_Set_Duty(150);
     }

     if (PORTB.F2==1 &&  PORTB.F1==1) {                    // turn R  moter L pwm1
      PWM1_Set_Duty(25);
      PWM2_Set_Duty(175);
      delay_ms(500);
      PWM1_Set_Duty(150);
      PWM2_Set_Duty(150);
     }
  }
}  
    
pregunta Thulana Vimukthi

1 respuesta

3

Esta puede ser una respuesta algo obvia, pero como no hay otras respuestas y el dispositivo es PIC16, creo que la única forma de obtener niveles es usar un bloque de instrucciones if o equivalentes.

Por ejemplo, algo como esto:

interrupt()
{
  if(A)
    {
      handle(A);
    }
  if(B)
    {
     handle(B);
    }
}

Básicamente, dentro de la función de interrupción, que en mikroC tiene que ser void interupt(void) para las interrupciones de nivel normal y alto y void interrupt_low (void) para las interrupciones de bajo nivel en 18F o se debe declarar usando la palabra clave iv , se colocará una lista ifs que comprueba cada una Interrumpir la bandera en el orden que desee. Dentro de si coloca el controlador que maneja la interrupción y borra la bandera y luego vaya a la bandera de red. Desafortunadamente, eso significa que no hay una manera fácil de implementar múltiples niveles de interrupciones.

Un "truco" podría ser verificar los indicadores de interrupción que desea tener una prioridad más alta dentro de un bloque if de una interrupción de prioridad más baja antes de las piezas que requieren mucho tiempo. Sin embargo, esto conduce a rutinas de servicio de interrupción largas y complicadas.

Por ejemplo

interrupt()
{
  if(A)
    {
      handle(A);
    }
  if(B)//B takes a long time and several steps
    {
     init(B);
     if(A)
     {
       handle(A);
     }

     handle(B);//This takes long time
    }
}

Otra forma sería mover el procesamiento de interrupción del ISR al bucle principal, si puede. Cree algunas variables globales (declaradas fuera de cualquier función) y utilícelas como indicadores que se establecerán en el ISR y luego se procesarán dentro del bucle principal. En caso de que tenga algunas interrupciones muy críticas que no puedan esperar a que el bucle principal venga y las procese, podría hacer el enfoque híbrido. Coloque las rutinas de manejo para las interrupciones más importantes en el ISR y para el resto de las interrupciones use indicadores que se procesarán en el bucle principal. Incluso puede agregar algunos "niveles" de interrupciones más marcando los indicadores establecidos por el ISR para las interrupciones más importantes varias veces en el bucle principal y para las interrupciones menos importantes solo al principio o al final del ciclo.

Por ejemplo

char a,b,c;

interrupt()
{
   if(A)
        {
          handle(A);
        }
      if(B)
        {
         b=1;
         clear_B_interrupt_Flag;
        }
    }

main()
{

  while (1)
  {

   if(b)
    {
      handle(B);
      b=0;
    }
  }
}

Aquí es el enlace para el La documentación de mikroElektronika para interrupciones.

    
respondido por el AndrejaKo

Lea otras preguntas en las etiquetas