Archivo

Posts Tagged ‘IRQ’

Cronometro(con interrupciones)

30 diciembre, 2007 Deja un comentario

Cronometro con interrupciones

[spoiler]

/*Descripcion: Cronometro*/

#include 
#include 
#include 

#define BaseTmr 0x0040

//Posicion del cronometro fijo
#define posx 30
#define posy 10
#define MAX 100   //Cantidad maxima de registros a guardar

//***************************************************************************
typedef struct state{
       unsigned int reg;
       unsigned int lsb;
       unsigned int msb;
       unsigned long int cuenta;
       unsigned long int tiempo;
}estado;

typedef struct T{
       char mili;
       char seg;
       char min;
}tiempo;

struct control{
   char mseg;   //Cada vez que mseg pasa a 1, es porque transcurrio 1mseg
   char pausa;  //pausa=0 ==> el cronometro corre; =1 ==> detenido
   char guardar;//Cuando guardar=1, se debe imprimir el tiempo en un costado
   char salir;  //Cuando salir=1 ==> fin del programa
}flag;

//***************************************************************************
//Interrupcion
void interrupt far (*OldTmr) (void);
void interrupt far (*OldKey) (void);
void interrupt far IsrTmr (void);
void interrupt far IsrKey (void);

//***************************************************************************
//Prototipo de Funciones
estado InitHw(estado original);
void RestoreHw(estado original);
tiempo IncTime(tiempo t);
void Mostrar(tiempo t, char columna, char fila, char color);
void Guardar(tiempo datos[MAX],unsigned int cantidad);

//Variables Globales
unsigned long int tmr=0;
char onetime=0;

//**************************************************************************
void main (void){
   //Declaracion de variables locales
   estado original;
   tiempo t;
   tiempo datos[MAX];
   char renglon=0;
   unsigned int contador=0;

   //Inicializacion de las variables
   t.mili=0;t.seg=0;t.min=0;
   flag.mseg=0;
   flag.pausa=0;
   flag.guardar=0;
   flag.salir=0;

   for (contador=0;contador   contador=0;

   //Incializa el Hardware y devuelve una estructura con el estado
   //original del timer
   original=InitHw(original);

   //Loop Principal
   clrscr();
   do{
      //Transcurre 1 mseg
      if (flag.mseg) {
         if (!flag.pausa){
            t=IncTime(t);   //Actualiza la estructura de Tiempo
            Mostrar(t,posx,posy,5);     //Imprime el tiempo en pantalla
         }
         flag.mseg=0;
      }

      //Se presiono guardar
      if (flag.guardar){
            if (renglon<25){
               renglon++;
               }else{
               clrscr();
               renglon=0;
            }
            Mostrar(t,0,renglon,10);
            if (contador
               datos[contador]=t;
               contador++;
            }
            flag.guardar=0;
      }
   }while(!flag.salir);

       RestoreHw(original);

      Guardar(datos,contador);

}

//***************************************************************************
estado InitHw(estado original){
   disable();

   //Guardar la configuracion original del Timer
   original.reg=inportb(BaseTmr+3);
   outportb(BaseTmr+3,0xD8); //Reedback: 1 1 0 1 1 0 0 0
   original.lsb=inportb(BaseTmr);
   original.msb=inportb(BaseTmr);
   original.cuenta=(unsigned long int)original.lsb+256*(unsigned long int)original.msb;

   //Configurar el Timer para que interrumpa cada 1 mseg(0x04A9)
   outportb(BaseTmr+3,0x34); //Reg: 0 0 1 1 0 1 0 0 (timer0, lsb y msb, modo 2, sin bcd)
   outportb(BaseTmr,0xA9); //LSB
   outportb(BaseTmr,0x04); //MSB

   //Tanto la interrupcion del teclado como la del timer ya se encuentran
   //habilitadas desde el PIC.

   //Vector de Interrupcion
   OldTmr=getvect(0x08);
   OldKey=getvect(0x09);
   setvect(0x08,IsrTmr);
   setvect(0x09,IsrKey);

   enable();
   return (original);
}
//***************************************************************************
void RestoreHw(estado original){
   disable();

   //Restaurar el Timer
   outportb(BaseTmr+3,original.reg);
   outportb(BaseTmr,original.lsb);
   outportb(BaseTmr,original.msb);

   //Restaurar el vector de interrupciones
   setvect(0x08,OldTmr);
   setvect(0x09,OldKey);
   enable();
}
//***************************************************************************
void interrupt far IsrTmr(void){
   if (!flag.mseg) flag.mseg=1; //Por si la interrupcion llega antes de que se limpie el reg
   tmr++;
   if (tmr==55) {
      tmr=0;
      OldTmr(); //Interrupcion Original del Timer
   }
   outportb(0x20,0x20); //EOI
}

//**************************************************************************
void interrupt far IsrKey(void){
   char tecla;

   if (onetime==0){
      if (kbhit()){
         tecla=getch();
         tecla=toupper(tecla);
         if (tecla=='S') flag.salir=1;
         if (tecla=='P') flag.pausa=~flag.pausa;
         if (tecla=='G') flag.guardar=1;
         onetime=1;
      }
      }else{
      onetime=0;
   }
   OldKey();   //Isr Original
}

//***************************************************************************
void Mostrar(tiempo t, char columna, char fila, char color){
   //Declaraciones de variables locales a Mostrar
   char far *video=(char far*)0xB8000000l;
   char cadena[20];
   char CadMili[5];
   char CadSeg[5];
   char CadMin[5];
   char i;

   //Convertir la estructura t en un string
   itoa(t.mili,CadMili,10);
   itoa(t.seg,CadSeg,10);
   itoa(t.min,CadMin,10);

   strcpy(cadena,"Tiempo: ");
   strcat(cadena,CadMin);
   strcat(cadena,":");

   if (t.seg<10) strcat(cadena,"0");
   strcat(cadena,CadSeg);
   strcat(cadena,".");
   if (t.mili<10) strcat(cadena,"0");
   strcat(cadena,CadMili);

   //Imprimir la cadena
   video=video+(columna*2)+80*(fila*2);
   for (i=0;cadena[i];i++){
      *video=cadena[i];
      video++;
      *video=color;
      video++;
   }
}

//***************************************************************************
tiempo IncTime(tiempo t){
   if (t.mili<100){
      t.mili++;
      }else{
      t.mili=0;
      if(t.seg<60){
         t.seg++;
         }else{
         t.seg=0;
         if (t.min<60){
            t.min++;
            }else{
            t.min=0;
         }
      }
   }
   return (t);
}
//***************************************************************************
void Guardar(tiempo datos[MAX],unsigned int cantidad){
   FILE *file;
   unsigned int i;
   char resultado;

   clrscr();
   file=fopen("reg.txt","w");
   if (file==NULL) {
      printf("Error al guardar el archivo");
      exit();
   }

   for (i=0;i
      printf("%d",i);
      fprintf(file,"Tiempo: %d:%d.%d\n",datos[i].min,datos[i].seg,datos[i].mili);
   }

   fprintf(file,"Fin del Registro");
   fclose(file);
   getch();

}

[/spoiler]
Download: cron.c