Autor Tema: Pregunta sobre interrupciones  (Leído 3827 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Rodricity

  • PIC10
  • *
  • Mensajes: 43
Pregunta sobre interrupciones
« en: 29 de Noviembre de 2007, 14:35:17 »
 Queria basicamente saber si estoy dentro de una funcion, y se podre una interrupcion, poder saltar de la
funcion inicial a una funcion que maneje las interrupciones?

 Es decir, estoy haciendo x, y se produce una interrupcion, x ejemplo un pulso en RA4 (creo que produce
una interrupcion) por lo tanto deje pendiente a "x", haga lo que tenga que hacer cuando se produce la
interrupcion y vuelva al proceso de "x"

 eso, creo haber estadi viendo unos ejemplos, era algo asi:

interrupt void interr()
{
if(flag de interrupcion)              //o un switch en su defecto para saber "que" interrumpio.
   {
   manejo de interrupcion...
   }
}

Desconectado c4_esp_VR

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
    • www.muchotrasto.com
Re: Pregunta sobre interrupciones
« Respuesta #1 en: 29 de Noviembre de 2007, 14:48:13 »
Una rutina de interrupción lo que hace es ejecutarse cuando ocurre un evento que eleve el flag de interrupción, guardando previamente la dirección donde se encontraba en la función principal.

Una vez procesada la rutina de interrupción, el programa vuelve a su función principal donde lo dejó ya que como hemos dicho guardó la dirección donde lo había dejado.

No sé si esto resuelve tu duda.

Un saludote.

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Pregunta sobre interrupciones
« Respuesta #2 en: 29 de Noviembre de 2007, 14:50:04 »
Lo que hace cualquier sistema cuando se produce una interrupción es básicamente lo que quires hacer.

cuando se produce una IT, esta queda señalizada, de modo que una vez ejecutada la instrucción actual, lo primero que hace la unidad de control del procesador es un pooling a las interrupciones para ver si alguna está activa (pooling = encuestar las banderas de IT), si esto es así y dependiendo de cuantas IT, si hay prioridades y otros factores, la unidad de control, guarda en la pila la instrucción que debe ejecutarse a continuación y.... SALTA a la subrutina de interrupción que debe atender a la interrupción (valga la redundancia).

Una vez que se termina de atender la interrupción (para ello hay una instrucción especial, por ejemplo "RETI") la unidad de control saca de la pila el contador de programs y comienza a ajecutar la instrucción que le seguía al lugar donde te quedaste anteriormente. Y así es el proceso.

Donde está el problema, que cuando saltas a una subrrutina de IT, debes guadrar el contexto de la tarea que estabas ejecutando, y justao antes de retornar de ella, debes reestablecer el contexto Esto puede ser batante complejo y depende del procesador y otros factores, para ello los lenguajes de alto nivel suelen resolver el problema de manejar eficiente.

Veamos tu código:
interrupt void inter() es la declaración de una función para que esta se ejecute ante una IT, es decir aquí saltará tu PIC cuando se produzca una IT, como los PIC suelen tener un solo vector de IT para todas solo puede haber una subrrutina de atención de IT.

Luego haces un pooling de IT (para saber cual está activa), para ello tienes
if(flag de IT)
y si es así, puedes lógicamente llamar funciones y demás, el compilador debe generar código para que esto pueda hecerse, pero no debe haber problemas, excepto si llamas a funciones que no son reentrantes como printf, (estudia este concepto para que lo entiendas).

Al fina del interrupt void interr() el compilador mete código para reestablecer el contexto y vuelvas a X sin mucho problema.

Saludos
reinier

Desconectado Rodricity

  • PIC10
  • *
  • Mensajes: 43
Re: Pregunta sobre interrupciones
« Respuesta #3 en: 29 de Noviembre de 2007, 14:53:29 »
 Eso era lo que queria saber, gracias reiniertl

 A ver si de ahí subo el proyecto para que le echeis un ojo...

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Pregunta sobre interrupciones
« Respuesta #4 en: 30 de Noviembre de 2007, 02:13:26 »
Solo un breve comentario sobre:

Citar
Luego haces un pooling de IT (para saber cual está activa), para ello tienes
if(flag de IT)

En CCS no es necesario preguntarle cual está activa (como sí ocurre en ensamblador), solo hace falta activar las interrupciones que se desea que se disparen en el main, con los Enables correspondientes, y luego añadir fuera del main las directivas del preprocesador de las interrupciones deseadas seguidas por las funciones de atención a la interrupción.

Cuando ocurra una interrupción el programa irá a buscar la directiva del preprocesador correspondiente y ejecutará la función asociada.

Un saludo

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
Re: Pregunta sobre interrupciones
« Respuesta #5 en: 30 de Noviembre de 2007, 06:30:55 »
En algunas interrupciones debes hacer un reset al flag asociado a dicha interrupción ya que no se hace por hardware.


Suerte!!! ;)
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: Pregunta sobre interrupciones
« Respuesta #6 en: 21 de Marzo de 2008, 16:38:19 »
aprovecho este post para mi pregunta que no se que pasa , se que cuando me den la respuesta me voy a dar decabezazos,pero en fin aqui pongo mi programa:


#FUSES HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
#use fixed_io(a_outputs=PIN_A0)
#define led PIN_A0
char dato;
int1 flag;

#int_EXT
interrupcion_isr(){
flag=1;

}

#int_rda
secuencia(){

dato=0x00;
  if(kbhit()){
 
    dato=getc();
   
     
  }
}
enter(){
printf("%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X",0x1E,0x00,0x1C,0xD1,0x00,0x07,0x00,0x01,0x00,0x03,0x00,0x01,0x60,0x00,0x72,0xD7);
     
}
void main()
{
enable_interrupts(global);
   enable_interrupts(int_rda);
   enable_interrupts(int_ext);

   ext_int_edge(H_TO_L); 

   // TODO: USER CODE!!
   set_tris_a(0xFF);
   
   output_bit(led,0);
   while(1){
   if (flag==1){
   flag=0;
   enter();
   delay_ms(1);
   llamar();
       
   }
    if(dato!=0x00){            // Si es distinto de \0 ...
        output_bit(led,1);
     
    }
   
   }
}
lo que supone que quiero que haga es que cuando detecte que hay caracteres recibiendo,se encienda el led,pero se queda enganchado (prendido), aun y cuando no le estoy enviando caracteres, con la interrupcion externa no hay problema,funciona muy bien,de hecho no creo tener ningun conflitcto entre las dos,que podria ser?,P.D. ya he intentado con else en el if de dato!=0x00, :(
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Pregunta sobre interrupciones
« Respuesta #7 en: 22 de Marzo de 2008, 03:43:09 »
Cuando por interrupción recibes un dato haces dato=0x00; pero luego haces dato=getc(); con lo que dato no va a ser nunca 0 y el LED se quedará siempre encendido:

    if(dato!=0x00){            // Si es distinto de \0 ...
        output_bit(led,1);

Un saludo

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: Pregunta sobre interrupciones
« Respuesta #8 en: 22 de Marzo de 2008, 13:13:52 »
ok ,entendido,gracias maestros, jejeje, entendido, volvere a hacer el programa, gracias
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: Pregunta sobre interrupciones
« Respuesta #9 en: 28 de Marzo de 2008, 03:36:17 »
aqui siguiendo dando lata,jejeje
bueno una pregunta con lo de las interrupciones rb4-7,aqui pego mi programa:

#int_rb
interrup_isr_b(){
byte change;
 output_high(PIN_C0);
change=last_b^portb;
last_b=portb;
if (bit_test(change,4 )&& !bit_test(last_b,4)){

flag_rb4=1;
}
if (bit_test(change,5 )&& !bit_test(last_b,5)){

flag_rb5=1;
}
if (bit_test(change,6 )&& !bit_test(last_b,6)){

flag_rb6=1;
}
if (bit_test(change,7 )&& !bit_test(last_b,7)){

flag_rb7=1;
}

}
void main(){

enable_interrupts(int_rb);
   enable_interrupts(global);   // Habilito Interrupciones
   enable_interrupts(int_RTCC); // habilitacion de interupcion externa
   set_tris_b(0xFF);
set_tris_a(0x00);
do {
 
     if (flag_rb4==1){
     flag_rb4=0;
     output_high(pin_a0);
     printf("rb4"); 
     
     }else{
     output_low(pin_a0);
     }
     if (flag_rb5==1){
     flag_rb5=0;
     output_high(pin_a1);
         
     printf("rb5"); 
     }else{
     output_low(pin_a1);
     }
     if (flag_rb6==1){
     flag_rb6=0;
     output_high(pin_a2);
         
     printf("rb6"); 
     }else{
     output_low(pin_a2);
     }
     if (flag_rb7==1){
     flag_rb7=0;
     output_high(pin_a3);
         
     printf("rb7"); 
     }else{
     output_low(pin_a3);
     }

     
   } while (TRUE);
}
   
cuando lo pruebo en la virtual terminal me sale los printf correctamente cada vez que realizo la interrupciones,pero nada con los leds de pruebba del puerto A,alguien  me podria ayudar a decirme por que?
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Pregunta sobre interrupciones
« Respuesta #10 en: 28 de Marzo de 2008, 03:49:44 »
Que raro. El puerto a lo tienes bien configurado como salida con el set_tris correspondiente y luego si te hace el printf necesariamente antes te tiene que hacer el output_high.

Pón el programa completo y te lo pruebo.

Un saludo

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: Pregunta sobre interrupciones
« Respuesta #11 en: 28 de Marzo de 2008, 03:56:49 »

#FUSES HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)

#use rs232(baud=9600,xmit=PIN_c6,rcv=PIN_c7)
#use standard_io(a)
#use standard_io(c)
#include <input.c>

#rom 0x2100={9,7,6,0x1E,0x3F}
#byte portb=6

int contRTCC=0x00;
int flag=0;
int1 enter;
int1 up;
int1 down;
int1 flag_rb4;
int1 flag_rb5;
int1 flag_rb6;
int1 flag_rb7;

int val=0;
char caracter;
char caracter1;
char dato;
int last_b;


////////////////////////
#int_rb
interrup_isr_b(){
byte change;
 output_high(PIN_C0);
change=last_b^portb;
last_b=portb;
if (bit_test(change,4 )&& !bit_test(last_b,4)){

flag_rb4=1;
}else{
flag_rb4=0;
}
if (bit_test(change,5 )&& !bit_test(last_b,5)){

flag_rb5=1;
}else{
flag_rb5=0;
}
if (bit_test(change,6 )&& !bit_test(last_b,6)){

flag_rb6=1;
}else{
flag_rb6=0;
}
if (bit_test(change,7 )&& !bit_test(last_b,7)){

flag_rb7=1;
}else{
flag_rb7=0;
}

}



void main() {

 

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
    enable_interrupts(int_rb);
   enable_interrupts(global);   // Habilito Interrupciones
   enable_interrupts(int_RTCC); //
   set_tris_b(0xFF);
   set_tris_a(0x00);
   set_tris_c(0xFE);
   printf("probando el programa Scientist");

   do {
   
     
     
     if (flag_rb4==1){
     flag_rb4=0;
     output_high(pin_a0);
     printf("rb4"); 
     
     }else{
     output_low(pin_a0);
     }
     if (flag_rb5==1){
     flag_rb5=0;
     output_high(pin_a1);
         
     printf("rb5"); 
     }else{
     output_low(pin_a1);
     }
     if (flag_rb6==1){
     flag_rb6=0;
     output_high(pin_a2);
         
     printf("rb6"); 
     }else{
     output_low(pin_a2);
     }
     if (flag_rb7==1){
     flag_rb7=0;
     output_high(pin_a3);
         
     printf("rb7"); 
     }else{
     output_low(pin_a3);
     }

     
   } while (TRUE);
   
}
por favor no hacer caso de la rom,solo experimentaba las funciones,aqui esta el programa amigo pocher,ahora que aprendo interrupciones se me complica bastante,jejeje
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Pregunta sobre interrupciones
« Respuesta #12 en: 28 de Marzo de 2008, 04:00:12 »
Vale ya no es necesario, creo que lo tengo.

La primera vez que haces flag_rb4==1 sí que activas output_high(pin_a0); pero como como también haces flag_rb4==0 en la siguiente vuelta del while te va a hacer el else con lo que va a apagar a pin_a0 y lo vas a ver siempre apagado.

Un saludo

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: Pregunta sobre interrupciones
« Respuesta #13 en: 28 de Marzo de 2008, 04:09:50 »
ok,lo checo y posteo mis resultados, quitare los flags =0 de el ciclo while
gracias pocher
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: Pregunta sobre interrupciones
« Respuesta #14 en: 28 de Marzo de 2008, 04:30:37 »
pues no se que es amigo pocher,hice lo que me dijiste,primero quite los flags_rbx=0; de el ciclo while,y al correrlo,pues me hacian en el printf una especie de ciclo infinito  hasta que activaba otra y salia esa printf, los leds si prendian pero parecian muy erraticos, despues cambie de lugar hasta lo ultimo de las operaciones if del ciclo while, ya por ultimo quite el else de la funcion de la interrupcion,no se que es :(
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....


 

anything