//================================================================== //= Este programa realiza adquisiciones de muestras utilizando = //= la tarjeta DAS1600 con el m‚todo de definici¢n de la velo- = //= cidad de muestreo por medio de los contadores de la tarjeta = //= y las interrupciones. El programa no pretende ser el id¢neo = //= sino tan s¢lo servir como demostraci¢n elemental de como re- = //= solver la pr ctica correspondiente. = //= (Algunas funciones se han inclu¡do como documentaci¢n aunque = //= no sean utilizadas en el programa). = //= Para cualquier duda/aclaraci¢n contactar con el autor en = //= luis.zorzano@die.unirioja.es = //================================================================== #include #include #include #include typedef unsigned char Byte ; typedef unsigned int Word ; typedef Byte Canales; typedef Word Datos; typedef Word Abscisas; typedef Word Ordenadas; typedef Datos *TablasDatos; Abscisas x, y; Canales Canal, CanalConvertido, PrimerCanal, UltimoCanal; Datos Dato; Ordenadas Tabla[16][640]; int Columna[16]; TablasDatos TablaDatos; int ContadorMuestras; Byte Muestras8 [5000]; Word Muestras12 [5000]; Byte Registro0, Registro1; int pantalla [16][640]; Byte FinConversion; void interrupt (*VectorViejo)(); void interrupt RecogeMuestras(); Byte clk () { Byte Estado; Estado = inportb (0x300+0x407) & 0x01; return (Estado); } Byte bme () { Byte Estado; Estado = inportb (0x300+0x407) & 0x40; return (Estado); } Byte me () { Byte Estado; Estado = inportb (0x300+0x407) & 0x20; return (Estado); } Byte cd () { Byte Estado; Estado = inportb (0x300+0x407) & 0x10; return (Estado); } Byte ws () { Byte Estado; Estado = inportb (0x300+0x407) & 0x02; return (Estado); } void EstadoDAS1600 (void) { if (clk() == 1) printf ("La frecuencia del reloj es 10 MHz\n"); if (clk() == 0) printf ("La frecuencia del reloj es 1 MHz\n"); if (bme() == 0) printf ("Burst Mode Disabled\n"); if (bme() != 0) printf ("Burst Mode Enabled \n"); if (me() == 0) printf ("DAS1600 Mode Disabled \n"); if (me() != 0) printf ("DAS1600 Mode Enabled \n"); if (cd() == 0) printf ("Conversions disabled \n"); if (cd() != 0) printf ("Conversions allowed \n"); if (ws() == 0) printf ("No wait state \n"); if (ws() != 0) printf ("Wait State Enabled \n"); } void SeleccionaModoBurst(Byte NumeroCanales) { Byte Dato; outportb (0x704, 0x00); outportb (0x705, 0x40); outportb (0x706, 0x40); Dato = NumeroCanales << 4; outportb (0x30A, Dato); } void SeleccionaFrecuenciaMuestreo (float f) { const TimerX_Ctl = 0x30F; const Timer0_Dat = 0x30C; const Timer1_Dat = 0x30D; const Timer2_Dat = 0x30E; Byte x; Word ContadorH, ContadorL, WordH, WordL; Byte ContadorHH, ContadorHL, ContadorLH, ContadorLL; unsigned long int T, N, Contador; unsigned long int Periodo; float fclk; if (f<=0) f=1; if (((inportb (0x300+0x407) & 0x01))==1) fclk = 1e7; else fclk = 1e6; N = (unsigned long int) fclk/f; if (N<=10) { WordH = 2; WordL = 5; }; if ((N>10)&&(N<65535)) { WordH = 2; WordL = (Word) (N/2); }; if (N>65535) { WordH = 10000; WordL = (Word) (N/10000); }; ContadorHH = (Byte)(WordH >> 8); ContadorHL = (Byte)(WordH & 0x00FF); ContadorLH = (Byte)(WordL >> 8); ContadorLL = (Byte)(WordL & 0x00FF); /* ################################################################## Los contadores han de tener (ambos) un bajo valor para velocidades altas de muestreo. ­ No almacenar el per¡odo en los contadores ! T = CTR2*CTR1 us T <> CTR2*65536 + CTR1 us Tener la precauci¢n de no precargar los contadores con 1, puesto que al decrementar se bloquean con 0, puesto que al decrementar se precargan a 0xFFFF. Puesto que las velocidades de muestreo suelen ser m£ltiplos de 10 conviene cargar CTR1 con un m£ltiplo de 10 ################################################################## */ outportb (TimerX_Ctl, 0x74); //01 11 010 0} {Timer1, Secuencial, Continuo, Binario} outportb (Timer1_Dat, ContadorLL); outportb (Timer1_Dat, ContadorLH); outportb (TimerX_Ctl, 0xB4); //10 11 010 0} {Timer2,Secuencial, Continuo, Binario} outportb (Timer2_Dat, ContadorHL); outportb (Timer2_Dat, ContadorHH); outportb (0x30a, 0x20); outportb (0x308,0); } Word LecturaContador1 (void) { Word Timer0_Dat = 0x300+12; Word Timer1_Dat = 0x300+13; Word Timer2_Dat = 0x300+14; Word TimerX_Ctl = 0x300+15; Word Cuenta; Byte CuentaH, CuentaL; outportb (TimerX_Ctl, 0x74); /* 0%01110100); */ /* BCD */ /* Modo 2 */ /* Lectura Bytes L-H */ /* Contador 1 */ outportb (TimerX_Ctl, 0x44); /* 0%01000100); */ /* BCD */ /* Modo 2 */ /* Capturar contadores */ /* Contador 1 */ CuentaL = inportb (Timer1_Dat); CuentaH = inportb (Timer1_Dat); Cuenta = (Word) CuentaH; Cuenta = (CuentaH << 8) | CuentaL; return(Cuenta); } Word LecturaContador2 (void) { Word Timer0_Dat = 0x300+12; Word Timer1_Dat = 0x300+13; Word Timer2_Dat = 0x300+14; Word TimerX_Ctl = 0x300+15; Word Cuenta; Byte CuentaH, CuentaL; outportb (TimerX_Ctl, 0xB4); /* 0%10110100); */ /* BCD */ /* Modo 2 */ /* Lectura Bytes L-H */ /* Contador 2 */ outportb (TimerX_Ctl, 0x84); /* 0%10000100); */ /* BCD */ /* Modo 2 */ /* Capturar contadores */ /* Contador 1 */ CuentaL = inportb (Timer2_Dat); CuentaH = inportb (Timer2_Dat); Cuenta = (Word) CuentaH; Cuenta = (CuentaH << 8) | CuentaL; return(Cuenta); } void SeleccionaIRQ (Byte NumeroIRQ) { Byte Dato; Dato = (0x80) | (NumeroIRQ << 4) | 3; outportb (0x309, Dato); } void SeleccionaRelojInterno () { Byte dato; dato = 0x03 | ((UltimoCanal-PrimerCanal+1)<<4); outportb(0x30a, dato); } void HabilitaInterrupcionesPC (Byte NumeroIRQ) { Byte dato, mascara; mascara = ~(0x01 << NumeroIRQ); dato = inportb (0x21); dato = dato & mascara; outportb(0x21, dato); } void InHabilitaInterrupcionesPC (Byte NumeroIRQ) { Byte dato, mascara; mascara = (0x01 << NumeroIRQ); dato = inportb (0x21); dato = dato | mascara; outportb(0x21, dato); } void InHabilitaInterrupcionesTarjeta () { outportb (0x309, inportb (0x309) & 0x7F); } void HabilitaInterrupcionesTarjeta () { outportb (0x309, inportb (0x309) | 0x80); } void SeleccionaGanancias () { outportb (0x30B, 0x01); } void SeleccionaCanales (Canales PrimerCanal, Canales UltimoCanal) { Byte dato; dato = (UltimoCanal << 4) | PrimerCanal; outportb(0x302, dato); } void SeleccionaCanal (Canales Canal) { Byte dato; dato = (Canal << 4) | Canal; outportb(0x302, dato); } void CambiaVectorInterrupciones (Byte NumeroIRQ) { VectorViejo = getvect (NumeroIRQ+8); setvect (NumeroIRQ+8, RecogeMuestras); } void RecuperaVectorInterrupciones (Byte NumeroIRQ) { setvect (NumeroIRQ+8, VectorViejo); } void EsperaFinalConversion () { do{} while ((inportb(0x308) & 0x80) != 0); } void interrupt RecogeMuestras() { Registro0 = inportb (0x300); Registro1 = inportb (0x301); Canal = Registro0 & 0x0F; Muestras8 [ContadorMuestras] = (Byte) Registro1; Muestras12 [ContadorMuestras] = (Word) (Registro1 << 4) | (Registro0 >> 4); Tabla [Canal][x] = (Byte) Registro1; Columna[Canal] = Registro1; outportb (0x308, 0); x = (x+1) % 640; if (Canal == UltimoCanal) ContadorMuestras = ContadorMuestras + 1; outportb (0x20, 0x20); outportb (0xA0, 0x20); } int inicializa_graficos(void) { /* request auto detection */ int gdriver = DETECT, gmode, errorcode; /* initialize graphics mode */ initgraph(&gdriver, &gmode, "c:\\tc\\bgi"); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) /* an error occurred */ { printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); /* return with error code */ } return 0; } int cierra_graficos (void) { closegraph (); return 0; } int dibuja_columna (int x, int ordenadas[16]) { int c; for (c=PrimerCanal; c<=UltimoCanal; c++) putpixel (x, pantalla[c][x], BLACK); for (c=PrimerCanal; c<=UltimoCanal; c++) putpixel (x, ordenadas[c], c+1); for (c=PrimerCanal; c<=UltimoCanal; c++) pantalla[c][x] = ordenadas[c]; return 0; } void EsperaInterrupciones (int NumeroMuestras) { Word y; Canales Canal; ContadorMuestras = 0; x = 0; y = x; do { while (x==y); y = x; dibuja_columna (x, Columna); } while ((ContadorMuestras < NumeroMuestras) & !kbhit()); } void main () { clrscr(); EstadoDAS1600(); PrimerCanal = 1; UltimoCanal = 1; Canal = PrimerCanal; x = 0; ContadorMuestras = 0; InHabilitaInterrupcionesTarjeta (); outportb (0x308, 0); SeleccionaCanal (Canal); SeleccionaGanancias (); SeleccionaFrecuenciaMuestreo (1000); CambiaVectorInterrupciones(5); SeleccionaRelojInterno (); HabilitaInterrupcionesPC(5); HabilitaInterrupcionesTarjeta(); SeleccionaIRQ (5); EstadoDAS1600(); getch(); inicializa_graficos (); while (!kbhit() && ContadorMuestras<5000) EsperaInterrupciones(640) ; InHabilitaInterrupcionesTarjeta (); InHabilitaInterrupcionesPC (5); RecuperaVectorInterrupciones(5); cierra_graficos (); }