Autor Tema: Utilizando dos interrupciones...  (Leído 2752 veces)

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

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
Utilizando dos interrupciones...
« en: 20 de Abril de 2005, 19:56:00 »
Hola

Anteriormente había comentado que había hecho un programa en el cual hacía uso de dos interrupciones, una para el control de un motor y otra para la adquisición de datos con ayuda del convertidor. Mi duda es: ¿puede llegarse a dar el caso en que mientras se esté atendiendo una interrupción, se desborde el timer de la otra y se atiendan al mismo tiempo ambas interrupciones? O ¿hasta que se termina una se atiende la otra? Esta es mi duda y quisiera que me ayudaran a despejarla.
¿Acaso será mejor que al entrar en la función de interrupción de adquisición deshabilite la interrupción del motor y al salir la vuelva a habilitar?

El código de mi programa es el siguiente:
Codigo:

#include <16f874A.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#device ADC=10
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  
#byte port_b = 6
#include<lcd.c>

char datohigh, datolow, temp, terminar;
long periodo,freqmot;
long dato, muestras;
int i,j;
long retardo,conteo;

void adquirir()
   {
          dato = read_adc();
      datolow=dato;
      datohigh=make8(dato,1);
      //temp=(dato>>8);
      //datohigh=temp&3;
      putc(datohigh);
      putc(datolow);      
    }

#INT_RTCC
void pulso()
{
   if(--conteo==0)
      {
         output_bit(PIN_B0,!bit_test(port_b,0));
         conteo=retardo;   
      }
   set_rtcc(61);
}

#INT_TIMER1
void adquisicion()
   {
         set_adc_channel( 0 );
      adquirir();
      set_adc_channel( 3 );
      adquirir();
   }

#INT_RDA
void detener()
{
   terminar=getc();
   if (terminar=="s")
      {
         disable_interrupts(GLOBAL);
         disable_interrupts(INT_RTCC);
         disable_interrupts(INT_TIMER1);
         disable_interrupts(INT_RDA);
         output_b(0);
         lcd_putc("f");
         reset_cpu();
      }
}

main()
   {
      char valor, giro, paso;
         int periodohigh, periodolow, muestrashigh, muestraslow, datoalto, datobajo;
         
         //set_tris_b(0x00);
         
         setup_adc_ports( ALL_ANALOG );
         setup_adc( ADC_CLOCK_DIV_32 );
         
         lcd_init();
         
         while(!kbhit()); //Espera la recepcion de un caracter
         valor=getc();
         if (valor=="j")
           {
            putc("8");
         
            //Para el programa de adquisición

            while(!kbhit()); //Espera la recepcion de un caracter
            muestrashigh=getc();
            while(!kbhit()); //Espera la recepcion de un caracter
            muestraslow=getc();
            while(!kbhit()); //Espera la recepcion de un caracter
              periodohigh=getc();
            while(!kbhit()); //Espera la recepcion de un caracter
            periodolow=getc();   

            //Para el control del motor
         
            while(!kbhit()); //Espera la recepcion de un caracter
            datoalto=getc();
            while(!kbhit()); //Espera la recepcion de un caracter
            datobajo=getc();
            while(!kbhit()); //Espera la recepcion de un caracter
              giro=getc();
            while(!kbhit()); //Espera la recepcion de un caracter
              paso=getc();
              
              muestras=(muestrashigh*256) + muestraslow;
            periodo=(periodohigh*256) + periodolow;
            freqmot=(datoalto*256)+datobajo;
            
               
            if (giro=="i")
               {
                  output_high(PIN_C0);
               }
            if (giro=="d")
               {
                  output_low(PIN_C0);
               }
            if (paso=="m")
               {
                  output_high(PIN_C1);
               }
            if (paso=="c")
               {
                  output_low(PIN_C1);
               }
            
            retardo=freqmot;
            conteo=retardo;
            
            lcd_putc("f");
            lcd_gotoxy(1,1);
            printf(lcd_putc,"muestras=%4lu",muestras);
            lcd_gotoxy(1,2);
               printf(lcd_putc,"freq=%4lu",freqmot);
            setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
            set_rtcc(61);
            setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
            set_timer1(60536);    
            enable_interrupts(INT_RDA);
            enable_interrupts(INT_TIMER1);
            enable_interrupts(INT_RTCC);
            enable_interrupts(GLOBAL);
               while(TRUE);
            }
   }


Gracias por su ayuda


Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Utilizando dos interrupciones...
« Respuesta #1 en: 20 de Abril de 2005, 23:03:00 »
A ver si me acuerdo del ensamblador. No, no es posible ya que cuando se dispara una interrupción el bit GIE (Habilitación Global de Interrupciones) pasa a 0 y no se puede disparar otra. Cuando se sale de ella automáticamente vuelve a 1.

Un saludo

Desconectado j_fernandez

  • PIC12
  • **
  • Mensajes: 89
RE: Utilizando dos interrupciones...
« Respuesta #2 en: 21 de Abril de 2005, 01:52:00 »
EN EL CASO DE QUE SE PRODUZCAN DOS INTERRUPCIONES SIMULTANEAS EL MICRO ATIENDE PRIMERO A LA QUE TU MEDIANTE SOFTWARE LE AS OTORGADO MAYOR PRIORIDAD. sI YA ESTAS EN UNA, MIENTRAS ESTA SE EJECUTA NORMALMENTE SE DESHABILITAN LAS DEMAS HASTA QUE SE ACABA EL PROCESO, LO QUE NO SE ES SI MIENTRAS SE EJECUTA UNA SECUNDARIA Y PIDE UNA DE MAYOR PESO COMO ACTUA EL MICRO.

UN SALUDO

Desconectado j_fernandez

  • PIC12
  • **
  • Mensajes: 89
RE: Utilizando dos interrupciones...
« Respuesta #3 en: 21 de Abril de 2005, 01:54:00 »
POR CIERTO, SE ME HA OLVIDADO ANTES PREGNTAR, SI NO TE SABE MAL, CUANDO AS MENCIONADO LO DE ADQUISICION DE DATOS A QUE TE REFERIAS??  ES QUE YO ESTOY HACIENDO UN PROYECTO SIMILAR.

UN SALUDO DE NUEVO

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
RE: Utilizando dos interrupciones...
« Respuesta #4 en: 21 de Abril de 2005, 12:59:00 »
Hola

Pues muchas gracias por los tips, pues lo de adquirir datos es que leo el convertidor, pero como es de 10 bits, parto el  dato y los envío por el puerto serie, en una pasada hago lo mismo para dos canales, es decir, grafico un dato de cada canal y cuando se vuelve a dar la interrupción lo vuelvo a hacer y así sucesivamente. Yo tenía pensado en que al ser de mayor prioridad la interrupción para generar la señal cuadrada pues que cuando se entrara a esta función yo deshabilitaba por software le interrupción del timer1 y al salir la volvía a habilitar pero bueno, con lo que me dicen creo que no es necesario. De todos modos se aceptan sugerencias para mejorarlo y hacerlo más eficiente.
Esto de la adquisición lo hago para presentar en la pantalla de la computadora, con el uso de visual basic, la forma de onda de las señales obtenidas de unos sensores de presión.

Gracias.

Desconectado j_fernandez

  • PIC12
  • **
  • Mensajes: 89
RE: Utilizando dos interrupciones...
« Respuesta #5 en: 22 de Abril de 2005, 01:37:00 »
Hola, lo que estas haciendo de la adquisicion de datos me ha parecido muy interesante ya yo estoy hacendo algo similar, lo que me veo mas pillao a la hora de conectarlo al ordenador ya que no se Visual Basic ni Visual C. Pero mi proyecto tambien consta de adquirir datos y realizar posteriormente una grafica.

Un saludo

Jose

Desconectado gfp

  • PIC18
  • ****
  • Mensajes: 274
RE: Utilizando dos interrupciones...
« Respuesta #6 en: 23 de Abril de 2005, 07:51:00 »
En los PIC de la familia 18 se puede colocar esta directiva : #device  HIGH_INTS=TRUE, esto significa que por ejemplo, si tienes interrupcion por TMR0 y TMR1 y la prioridad la tiene TMR0, cuando se genera una interrupcion por TMR1 y poco tiempo despues por TMR0 entonces el PIC deja de atender al TMR1, atiende interrupcion por TMR0 y nuevamente sigue atendiende a TMR1.

saludos,

gfp Sonrisa

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
RE: Utilizando dos interrupciones...
« Respuesta #7 en: 25 de Abril de 2005, 00:53:00 »
Pues si, estoy realizando un proyecto para adquirir señales de dos sensores de presión y al mismo tiempo envió una señal de reloj a un driver de un motor a pasos. Cualquier cosa que necesiten saber de visual basic estoy a sus órdenes.

Otra cosa, cómo es eso de dar mayor prioridad a una interrupción por software, qué tengo que hacer para hacer eso? Gracias por todos sus consejos.


 

anything