UNIVERSIDAD AUTONOMA METROPOLITANA- .- Unidad Iztapalapa C'6IT. n PROYECTO DE INGENIERIA I y II '' OSCILOSCOPIODIGITAL x T.\CESAR/GOMEZ GAYTAN Junio De 1994. 3 T. CESAR GOMEZ GAYTAN INGENIERIA ELECTRONICA EN COMPUTACION MATRICULA: 86329879 1 INTRODUCCION Un microprocesador es un dispositivo que puede ser usado para realizar una gran variedad defunciones. Es decir,es un controladorprogramable.Todoslosmicroprocesadores realizan tres tareasbbicas: - Transferencia de datos. - Operaciones aritméticas y lógicas. - Toma de decisiones. Unmicroprocesadorcontrolalasoperacionesde la memoria y alosdispositivosde entraddsalida. Las interconexiones entre microprocesadory estos dispositivos se hacen por y el bus de control. medio del bus de datos, el bus de direcciones Las conexiones delbusdedireccionessonusadasparaproporcionarlasdireccionesde memoria o una dirección de entraddsalida ala memoria. El bus de datos es usado para llevar información entre el microprocesador y la memoria, o entre el microprocesador y los dispositivos de entraddsalida. El busdecontrol es usado para controlar tanto elsistemadememoriacomoel entraddsalida. Consiste de cuatro señales: RD (lectura), WR (escritura), MREQ (petici6n de memoria) y IOREQ (petición de entrawsalida). Las señales de RD y WR son usadas para que los datos sean leídos o escritos en memoria. La señal MREQ califica a las señales RD o WR como lecturas de memoria o escritura a memoria, y las señal IOREQ las califica como lecturas o escrituras de entraddsalida. El sistema de memoria en una computadora realiza dos importantes tareas: l . Almacenar las instrucciones del programa. 2. Almacenar los datos usados por el programa. En muchos sistemas el programa es almacenado en una memoria ROM (Memoria de sólo RAM (Memoria deacceso aleatorio). lectura) y los datos son almacenados en una memoria Los dispositivos de entradalsalida en una computadora logran la interacción del microprocesador con el mundo exterior. El microprocesador se comunica a los humanos y /o a otras maquinas a travesde los dispositivosde entrawsalida, loscualessedefinen como dispositivos que aceptan una señal eldctrica para procesamiento o la generan 2 Los dispositivos de entraddsalida en una computadora logran la interacción del microprocesador con el mundo exterior. El microprocesador se comunica a los humanos y /o a otras mhquinasatravbsdelosdispositivosdeentraddsalida, loscualessedefinen como dispositivos que aceptanuna s e u elbctrica para procesamientoo la generan JUSTIFICACION La idea bbica para el disefio y desarrollo de este proyecto surgió dela observación de los grandesproblemasquesetienencuandosehacenmedicionesdeseflalesanalógicascon dispositivos tambibn analógicos. Se vio la necesidad de poder almacenar las formas de las seiIales que se miden yasea en memoriao en archivos para que pudieranser analizadas con mayor detalle. Es por ello que se desarrolló un sistema que toma muestras de una seÍíal analógica cualquiera y las transmite hacia el puertoseriede una computadora,dondese grulca en pantalla la forma de onda de dicha sefial analógica. Todo esto selleva a cabo con lo que hemos llamado Osciloscopio Digital trabajando en tiempo real.Lo que significa que la muestra tomada es inmediatamente transmitida, por lo que la fiecuencia de operación del sistema depende en gran parte del convertidor analógico-digital y del microcontrolador que se estbn usando. KIT BASADO EN EL MICROCONTROLADOR 8031 El microcontrolador 8031esunode los miembros de la familia MCS-51 de INTEL, y es toda una micro computadora fabricada en una sola pieza desilicio. Esta familia se creópara usarse en aplicaciones de tiemporeal, control industrialy para perif6ricos de computadora. Todosestosmicrocontroladorespuedenserexpandidoshasta 64 Kbytes enmemoriade programa y hasta 64 Kbytes de memoria de datos, usando circuitos integrados de memoria externos. Independientemente de la memoria externa todos ellos tienen: 128 bytes de memoria interna asignada para los SFR (Registros de Función Interna) aunque sólose puedanusar 21 de ellos. INTEL ha reservado losrestantes para futuras expansiones. 0 Cuatropuertosprogramablesde VO; sinembargoalgunosdeellosseusan manejo de la memoria externa. 3 para el O Dos TimedContadores de 16 bits cada uno. 0 Unpuertoserial. O Circuitería interna parael oscilador del reloj. 0 0 Cuatro bancos de registro (con 8 registros cada unode ellos), los cuales se localizan en la memoria de datos interna. Cinco lineas deinterrupción(dosdefuentesexternas dos niveles de prioridad. y tres de fuentes internas con Organizaci6n De Memoria La familia del 8031 tiene dos tipos de memoria: l. La memoria de programa. 2. La memoria de datos. La memoria de programa puede ser hasta 64 Kbytes. Donde los primeros 4 Kbytes pueden residir dentro de microcontroladoro pueden estar los64 Kbytes externamente. Dentro de la memoria de datos se distinguen dos tipos: Una es la memoria externa, la cual puede crecer hasta 64 Kbytes y la otra es la memoria interna la cualconstade 128 bytes;estos 128 bytespuedenseraccesadosdirectae indirectamente. Los 128 bytes de memoria de datos internaestán divididos entres áreas: a. Los bancosderegistro 0-3: de la dirección OOh a la 1Fh (32 bytes).Cadaban co empleado contiene 8 registros (0-7). b. Posee una área direccionablep o r bit, de la direcci6n 20h a la 2Fh para un total de 16 bytes. Cada uno de los 18 bits de esta área pueden ser direccionados correctamente (00-7Fh). c. Tiene una área multiusos que va de los bytes 30h de datos delusuario o cualquier otro uso. 4 ""- - al 7Fh y puede usarse como área Software El juego deinstruccionesdeestosmicrocontroladoressepuededividiren: 55% de instrucciones de un byte, 36% de instrucciones de dos bytes, yel 9% de tres bytes. Existe una gran diferencia entre la memoria de datos internay la externa. Las direcciones de datos internas se refieren a aquellas que esth dentro de chip y que se pueden accesar de varias formas; mientras que l a s direcciones externas están localizadas fuera de chip, en los 64 Kbytes de memoria de datos externa y s610 puede ser accesada con las instrucciones MOVX. La interface programable (PPI)8255 La interface programable de perifdricos (PPI)8255 es uno de los circuitos de soporte m& útiles y flexibles del 8055. Contiene tres puertos paralelos programables de entradalsalida de ocho bits,cada uno con características propias. El sentido y la funci6n de l a s líneas de todos los puertos se programan durantela operaci6n 8 bits que envía el normal del dispositivo mediante una palabra de control de microprocesador al PPI. Internamente el 8255 dispone de cuatro registros, tres de los cuales se dedican a almacenar la informaci6n que entrao sale por los puertos A, B y C.El cuarto se denomina registro de control, y como su nombre lo indica,sededicaarealizarlasfuncionesdecontrol. Programando este registro se configuran los puertos y se define el hcionamiento general de los dispositivos. Velocidad de respuesta Respecto a la velocidadderespuesta, el OsciloscopioDigitaltendrii un rendimiento un ciertointervalo de satisfactorio s610 paraseñalesqueseencuentrendentrode frecuencias. Según el teorema de Nyquits, la frecuencia de muestreo debe ser al menos el doble de la frecuencia mhxima de la señal muestreada. La fkcuencia de muestreo de este sistema e s a determinada por la velocidad de respuesta o procesamiento de información de la PC.Esto se explica de la siguiente manera: Aunque la señal es muestreada por el convertidor analógico-digital, Cste entrega los bytes muestreados al Kit 8031 y estea su vez los entrega a la PC. Sin embargode los tres 5 dispositivos antes mencionadosla PC es elmas lento, ya que el tiempo transcurrido entre la lecturadelpuertoserie y la graficacióndeldatoleídoesconsiderablementegrande si tomamos en cuenta la velocidad de muestreo de convertidor y la velocidad de transmisión o del microcontrolador. Así que todos los bytes que se muestrean en este tiempo se pierden sonignoradospor la PC.Estoexplicaclaramenteporqué la velocidaddemuestreo "es impuesta" porla PC. En un principio se consideró que las muestras se tomaran en base a interrupciones hechas al Kit 803 l. Es decir, el convertidor da a su salida un byte el cual queda "enganchado", luego manda una señal de interrupción al Kit 803 1, quien a su vez ejecuta una rutina de servicio para tomar el byte y mandarloal puerto serial de la PC. Mientras tanto el convertidor ya no envía nada. Luego, la PC gráfka el byte leído de su puerto serial y envía una sefial de fin proceso al Kit 8031. El Kit 8031 manda entonces una señal al convertidor indichdole que ya puede enviar otro byte,repitihdose lo anterior enun ciclo. Esta descripción de funcionamiento es mucho m& confiable en cuanto a que se evita la perdidadeinformación. Sin embargoalaumentarseñalesdehandshaking(señalesde control), la frecuencia de muestreo disminuyey por lo tanto el alcance del equipo tambidn. Por tal motivo se evitaron todas esta formalidades. Amplitud de las seilales muestreadas El convertidoranalógico-digital referencia de las muestras son: e s a configuradode tal maneraquelos voltajes de - voltaje mínimo igual a O Volts (tierra). - voltaje mhximo igual a5 Volts. Por lo tanto sólo pueden graficarse señales cuya amplitud est6 entre O y 5 Volts. Programacih de Baud Rate La programación del Baud Rate (velocidad de transmisih) es un punto en el que se debe poner especial atención.En teoría se puede programar una gama de baud rates que puedeir dando un valor al registro t h l del desde 150 hasta 36000 baudios;ést0selogra microcontrolador 803 1 en base ala fórmula: thl = 256 - ((2*fiec. de osc.) / (386*baud rate)) 6 pero, al calcular el error de aproximación respecto a baud rate requerido, nos damos cuenta de que este valor esmuy grande. Es decir, al despejar dela fórmula anterior el baud ratecon el thl programado, vemos que estos difieren mucho. Por ejemplo, para un oscilador de 12 MHz y un baud rate de 9600, de acuerdo con la fórmula se tiene un thl de 249.5 el cual se redondea a250. Paracomprobar la certezadelcálculo,despejamosel baud rate de la fórmula, y sustituyendo el thl=250, obtenemos un baud rate real de 10416.6. Este error (8% diferente) nopermiteque la PCleaconsincroníalosbytesquelleganalpuertoserialypor consiguiente el programa se abortará. Se sugiere entonces que, para tener un baud rate muy cercano al requerido cambiarel cristal de cuarzo enel circuito osciladorpor otro que permitauna buena aproximación. Diagramas Los diagramas etiquetados como 1 y 2 muestran el diseño de los circuitos utilizados en la construcción del Osciloscopio Digital. La primera parte (diagrama1) muestra el sistema mínimo del KIT microcontrolador 803 1 y consta de lo siguiente: 1 . Microcontrolador 803 1 (el "cerebro" del sistema). 2. Memoria EPROM. Contiene el programa monitor del sistema. 3. Memoria RAM de 64 Kbytes. Donde se almacenan los programas ejecutables. 4. Display de 8 dígitos. Utilizado para visualizar direcciones de memoria, datos contenidos en la misma, etc. 5. Teclado. Compuesto de 24 teclas. 6. Mapeo de 2 Kbytes. 7. Bus de datos de8 bits. 8. Bus de direcciones de 15 bits. La segunda parte (diagrama 2) muestra la conexión del sistema conel PPI y el convertidor sus puertos de 8 bits actúa analógico-digital. El PPI se programó de tal modo que uno de I I . s 1 2 9 m 4 i I m " I I X BUS DE: COMTROL J DIR 1 8 0 0 ” I F F F ~ ”1 R E X T/CEXT I a IMT a DEL Bo31 T+t I t PROYECTOTERHINCY I Y 11 comoentrada. El convertidoranalógico-digitalse hizo trabajara una velocidadde aproximadamente 600 KHz, entregando 600 muestras de 8 bits por segundo. Cada vez que el convertidoranalógico-digitalentrega una muestraalmicrocontrolador 803 1, le envía un pequeÍí0 pulso a unade sus interrupciones para indicarle el envío. Sin embargodebidoaqueestepulsoesdemasiadocortoelmicrocontroladornoalcanzaa reconocerlo. Es por ello que se usó el circuito 7412 1 para ampliar el tamaño del pulso y que Cste pudiera ser reconocido fácilmente por el microcontrolador. Programacidn del KIT 8031 A continuación se lista el programa desarrollado en lenguaje ensamblador que programa al Kit 803 l . Este programa se carga enla memoria RAM del Kit. MOV A,#90H PALABRA DE CONTROL PARA EL 8255, CON LOS PUERTOS: A, DE ENTRADA; B Y C, DE SALIDA. MOV DPTR,#1803HDIRECCION DEL 8255, CONAO=A1=1,CON LA CUAL ESTA LISTO PARA LEER UNA PALBRA DE CONTROL. MOVX @DPTR,A ESCRIBE LAPALABRA DE CONTROL AL 8255. CLR P1.0 INICILAIZA EL PUERTO, PARA INDICAR EL INICIO DE CONVERSION. MOV DPTR,#1800HDIRECCION DEL 8255, CONAO=Al=O,CON LA CUAL ESTA LISTO PARA SER ACCESADO. INICIO: SUBRUTMA INICIO. SETB P1 .O INDICA AL CONVERTIDOR A/DQUE S E PREPARE PARA UN INICIO DE CONVERSION "START". CLR INICIO DE CONVERSION PARA P1.0 SETB P1.2 INHABILITA MOV R1 ,#O 1H EL ADC0800. LA COMUNICACION HASTA BIT SEAPUESTO EN CERO. QUE ESTE ESPERA: SUBRUTINA ESPERA. JB SENSA EL FIN DE CONVERSION A TRAVES DE ESTE PUERT0,Y AL DETECTARLO CAPTURA EL DATO DIGITAL. SJMP P1.1 ,CAPTURA ESPERA ESPERA HASTA DETECTAR EL FIN DE CONVERSION. CAPTURA: SUBRUTINA CAPTURA. MOVX A,@DPTR LEE LA PALABRA DE EL PUERTO 8255, DADA POR EL CONVERTIDOR A/D Y LA PONE EN EL ACC A. LCALL TRANSM SE LLAMA LA RUTINA DE TRANSMISIONY SE TRANSMITE EL DATO LEIDO DE EL 8255. SJMP INICIO PERMANECE CONVIRTIENDO Y TRANSMITIENDO HASTA QUE SE INTERUMPA LA EJECUCION DEL PROGRAMA. TRANSM: SUBRUTINA TRANSM. R2,#08H MOV NUMERO DE BITSA TRANSMITIR, DADA LA PROGRAMACION DEL PUERTO SERIE DE LA PC. CLR P1.2 BIT DE INICIO PARA LA COMUNICACION SERIE NORMA RS-232. LCALL RETARDO GENERA UN RETARDO PROPORCIONAL AL PERIODO DE TRANSMISION((1/9600) SEG PARA ESTE CASO). DJNZR1,DATOS SU FUNCION ES SOLO PARA COMPENSAR LA VELOCIDAD DE TRANSMISION DE EL BIT DE INICIO. DATOS: SUBRUTINA DATOS. RRC A ROTA HACIA EL ACUMULADOR EL BIT MAS SIGNIFICATIVO. MOV P1.2,C MUEVE AL CARRY(MSB),AL PUERTO P1.2, DONDE ES TRANSMITIDO HACIA EL PUERTO SERIE DE LA PC. LCALL RETARDO GENERA UN RETARDO PROPORCIONAL AL PERIODO DE TRANSMISION ((1/9600) SEG PARA ESTE CASO). 9 DJNZ R2,DATOS REVISA QUE SE HAYAN TRANSMITIDO LOS OCHO BITS DE INFORMACION. SETB P1.2 BIT DE PARO DE LA TRANSMISION DE LA PALABRA DE OCHO BITS. LCALL RETARDO GENERA UN RETARDO PROPORCIONAL AL PERIODO DE TRANSMISION((1/9600) SEG PARA ESTE CASO). RET RETORNO DE LA SUBRUTINA. RETARDO: SUBRUTINA RETARDO. MOV R3,#OEH VALOR PARA EL CUALSE ALCANZA EL RETARDO DE (1 /9600) SEG. NOFUNC: SUBRUTINA NOFUNC. NOP CICLO DE RETARDO. NOP CICLO DE RETARDO. DJNZ R3,NOFUNC AQUI SE SUSPENDE MOMENTANEAMENTE LA OPERACION DEL PROGRAMA CON CICLOS DE NO OPERACION. RET END Software de PC Se desarrolló un programa en el lenguaje de programación C que se encarga de graficar y mostrar en pantalla los datos que llegan a1 puerto serial de la PC. Este programa se divide básicamente en tres partes principales: - Inicialización grhflca. - Lectura de puerto serial. - Graficacih de la sefial. La inicialización grhfica tiene la función de dar de alta los archivos grhfícos y ver por las especificaciones particulares del monitor.Es decir, identifica eltipo de monitor mediante el número de pixeles del mismo. La lectura del puerto serial se hace tratando a éste como un archivo. Se abre el puerto serie declarándolo como un nombre con carácter de archivo quedando listo para hacer lectura de los datos. La graficación de la señal se lleva a cabode la siguiente manera: Debido a que los bytes son de8 bits, se tienen valores entreO y 255, donde el cero indicala amplitud minima dela sefial muestreada, que en nuestrocaso será O volts, y 255 la amplitud mhima que serh de 5 volts. Después se considera que el pixel superior (pixeles verticales) equivale al byte 255 y que el pixel inferiorcorresponde al byteO. Una vez encendido un pixel, el programa hace que el punto de referencia sobre X (pixeles horizontales) se desplace una delta X, donde se grdlcará otro pixel. De esta forma se hace un barrido horizontal hasta llenar la pantalla con la señal recuperada. Una vez que se llena la pantalla con la gráfica, se borrará y se repetirá el proceso desde el extremo izquierdo del monitor. 11 " " .. .. ... " _ I " // PROGRAMA UTILIZADO PARA GRAFICAR DATOS LEIDOS DEL PUERTO I/ SERIAL. #include <stdio.h> #include <conio.h> #include <alloc.h> #include <math.h> #include <graphics.h> #include <dos.h> #define NoPuntos5 12 #define SI 1 #defmeNO O #define ESC 27 typedef short Bool; enum Dominios { TMPO, FREC 1; enum Opciones { REAL, MAGN, POTN 1; void MenuPrin (Bool *apesd, Bool *apslr); void LeerSec (float **apentr, float **apenti, int *apnmax, Bool esdir); Bool Transfim (Bool esdir, float entr[], float entin, float **apslr, float **apsli, int nmax); void OpcSal (float tmprn, float tmpi[], float ficro, float fici[], int nmax); void LeerArch (float **apentr, float **apenti, int *apnmax); m h ,char nmvr); void Leerpuerto (float **apentr, float **apenti, int *apnmax, charn void BorrLin (intnumlin); void Leercmpj (float entro, float enti[], int n, char car); void DespMenu (void); void Indicar (int posx, int sel); Bool Calcular (float **apsup, float **apinf, float secr[], float secin, int nmax, int opc); void Graficar (float ssup[], float sinfn, int nmax, int opc); 12 void Listar (float ssup[], float S*], int nmax, int opc); void Salvar (float seer[], float secin, int nmax); Bool Aprob (void); Bool ModoGraf (void); void MinMax (float sec[], int nmax, float *apmin, float *apmax); // m6dulo principal main 0 { int nmax; Bool esdir, salir, exito; float *entre, *entim, *salre, * d m ; textmode (BW80); MenuPrin (&esdir, &salir); while (!salir) { LeerSec (&entre, &entim, &nmax, esdir); i f (nmax){ // Si entrada nula no exito = T r a n s h (esdir, entre, entim, &salre,&salim, nmax); i f (exito) { // Si salida nula no i f (esdir) OpcSal (entre, entim, salre, salim, nmax); else OpcSal (salre, salim, entre, entim, nmax); I I I I free (salre); free (salim); free (entre); free (entim); MenuPrin (&esdir, &salir); closegrapho; void MenuPrin (Bool *apesd, Bool *apslr) { char car; clrscro; printf("Mndique la opcion a seguir: .. h"); printf("h transformada [Dlirecta"); printf("h transformada [Ilnversa"); printqt1\n [Slalirhh"); 13 while ( (car=getchO)!='d' &$ car!='? && car!='s'); *apesd = (car='&) ? SI : NO ; *apslr = (cF's') ? SI : NO ; 1 void LeerSec (float **apentr, float **apenti, int *apnmax, Boo1 es&) { char car; char nmfn,nmvr, *so; nmfn= esdir? 'g' : 'G' ; nmvr = esdir?'k' : 'n' ; = es&r ? "T" : "fo" ; clrscr(); , mfn,nmvr, so); printf("\n\nleer %c(%c%s) desde: .. h"n printf("h [Dlisco''); printf("h [Pluerto seriehh"); while ( (car=getcho)!='d' && car!='p'); if (car=='&) LeerArch (apentr, apenti, apnmax); else { InicializaModoGrafko(); nmfn, nmvr); Leerpuerto (apentr, apenti, apnmax, 1 void LeerArch (float **apentr, float **apenti, int *apnmax) { char nmarch[80]; FILE *arch; int nmax; int posy; float *entr, *enti; size-t m,ni; Boo1 reint; // Rutina de Apertura de Archivo. posy = whereyo; gotoxy (1,posy); BorrLin (5); printf ("Entre el nombre del archivo : .. 'I); (nmarch); gets // nombre archivo Entra el del arch = fopen (nmarch,"rb"); i f (!arch) { printf (%No fue posible abrir el archivo %s\n",nmarch); printf ("hIntentar de nuevo ? (s/n) .. "); reint = Aprobo; 1 } while ( !arch && reint ); // Fin rutinaaperturaarchivo if (!arch) { *apnmax = O; return; // Si fiacaso en la apertura // Indica entrada nula // Y regresa 1 // Lectura del Tamaño de los Arreglos y Asignacion de Memoria. fiead (&nmax, sizeof(int), 1/*elemento*/, arch); // Lee nmax entr = calloc (nmax/*puntos*/, sizeof(float) ); enti = calloc (nmax/*puntos*/, sizeof(float) ); // Asigna memoria i f (!entr 11 !enti) { // Si memoria insuficiente printf ("Wemoria insuficiente. Lectura de disco no realizada.\n"); printf ( Y n Pulse 'ESC' para salir .. "); while ( getch() != ESC ); *apnmax = O; // Indica entrada nula // Liberamemoriasiasignada i f (entr) fiee (entr); i f (enti) fiee (enti); fclose (arch); return; // Y regresa 1 // Transferencia de los Datos del Disco a los Arreglos. do { datos delectura //deRutina nr = fiead (entr, sizeof(float),nmax /*puntos*/, arch); ni = fiead (enti, sizeof(float), nmax /*puntos*/, arch); i f (nr!=nmax 11 ni!=nmax) { // Si error de lectura 15 posy = whereyo; printf ("Wrror durante la 1ectura.h"); printf ("hDesea intentar de nuevo ? (s/n) reint = Aprobo; /I Si reintentar i f (reint) { N Restaura pantalla gotoxy (1 ,posy); BorrLin (5); fseek(arch,(long)sizeof(int), SEEK-SET); 1 Nlectura Finde si error 11 nr!=nmax) && reint ); fclose (arch); 1 1 N Fin lectura Narchivo Cierra el i f (nr"llmax && ni==nmax){ *apnmax = nmax; *apentr = entr; *apenti = enti; else { (entr); free free (enti); *apnmax = O; N Restauraarchivo reintentar I! Fin si 1 } while ( (nr!=nmax .. "); N Si lectura exitosa /I Indica entrada nula no /I Y asigna los arreglos // Si lectura fallida I/ Liberar memoria N E indicar entrada nula fallida lectura I/ Fin si void BorrLin (int numlin) { int i; for (i=O; i<numlin, i t t ) delhe(); 1 DibujaEjesO { int MaxX = getmaxxo; int MaxY = getmaxyo; 16 ." - setcolor( getmaxcolor()); rectangle( O, O, MaxX, MaxY); line(30,MaxY-53,MaxX-3O,MaxY-53); line(3O,MaxY-52,MaxX-3O,MaxY-52); line(MaxX-35,MaxY-58,MaxX-3O,MaxY-53); line(MaxX-35,MaxY-48,MaxX-3O,MaxY-53); line(MaxX-35,MaxY-58,MaxX-3O,MaxY-53); line(MaxX-35,MaxY-48,MaxX-3O,MaxY-53); line(30,50,30,MaxY-53); line(3 1,50,3 1 ,MaxY-53); line(25,55,30,50); line(26,55,3 1,50); line(35,55,30,50); line(36,55,3 1,50); settextstyle@EFAULT FONT, HOU-DIR, 1); outtextxy( MaxX/2-14*8,16,"Gráficaci6n en Tiempo Real"); outtextxy( MaxX/2-4*8, MaxY-18,"Tiempo"); outtextxy( 30,MaxY-48,"0"); outtextxy( 130,MaxY-48," 10"); outtextxy( 230,MaxY-48,"20"); outtextxy( 330,MaxY-48,"30"); outtextxy( 430,MaxY-48,"40"); outtextxy( 530,MaxY-48,"50"); outtextxy( MaxX-40,MaxY-43,"mseg"); settextstyle(DEFAULT-FONT, VERT-DIR, 1); outtextxy( 20, MaxY/2- 4*8, "Amplitud"); void Leerpuerto (float**ape&, float **apenti, int *apnmax, char n d h , char nmvr) { int nmax=NoPuntos; float *entr, *enti; int posy,cntrl; char cad[30]; struct text-info info; int altura, ancho, altvnt; int n, naux, fin; unsigned data=(OxO3 I Ox00 I Ox00 I OxEO); int Xi=32,Yi=5O,X~getmaxxO-38,Y~getmaxyO-54,i,puntoY,color; int car; float DivisoF1,Amplitud= 1 ; 17 " 1_1 // Leer Numero de Puntos y Asignar Memoria. entr = calloc (nmax/*puntos*/, sizeof(float) ); enti = calloc (nmax/*puntos*/, sizeof(float)); // Asigna memoria if (!entr 11 !enti) { // Si memoria insuficiente printf ("Wemoria insuficiente para alojar la secuencia.\n"); Desea intentar de nuevo? (s/n) .. "); printf ( l b 1 } while ( (!entr 11 !enti) && Aprob() ); if ( !entr 11 !enti ) { *apnmax = O; if(entr)free(entr); if (enti) free (enti); return; // Si memoriainsuficiente // Indica entrada nula // Liberamemoria si asignada // Y regresa 1 // Ciclo de Lectura de Datos del Puertoy Eco en Pantalla naux = O; n = O; bioscom(O,data,O); DibujaEjeso; setviewport(Xi,Yi,Xf,Yf,l); ~u~~oY=(Y~+NoPu~~os-~OO)/~; do // Graficarh mientras no se presionealguna tecla { moveto(0,puntoY); for (i = O; i <= (int) (NoPuntos -l)*Divisor; i++) do { car=OxFF & bioscom(2,0,0); entr[i] = car; enti[i] =O; puntoy = (Yf+NoPuntos-300)/2 Amplitud*car; lineto(i/Divisor,puntoY); } while(iMNoPuntos); clearviewport(); }while (!kbhit()); restorecrtmode(); - *apnmax = NoPuntos; // Indica entradano nula 18 *apentr = entr; *apenti = enti; // Y asigna arreglos void Leercmpj (float entr[],float entia, int n, char car) { int Po=, posy; char cad[80], *pos, *cd2; posx = wherexo; posy = whereyo; // Leer la Cadena. pos = cad; do { if (car==O) getcho; else if (car==8) { if (poecad) { putchar (8); putchar putchar (8); pos"; // Si tecla no ASCII, leer codigo // Si BACKSPACE, borrar anterior I); 1 1 else if ( (unsignedchar)car>3 1 ) { putchar (car); *(pos++) = car; 1 // Si es imprimible } while ( (car=getchO)!=13 ); // Mientrasno RETURN *pos = '\O'; // Termina la cadena // Separar la Cadena en sus Partes Real e Imaginaria. pos = cad; while ( *pos!='\O' && *pos!=',' && *pos!=' ' ) Pos++; cd2 = pos; while ( *cd2!='\0' && (*cd2=',' 11 *cd2=' ') ) cd2++; *pos = '\O'; entr[n] = atof (cad); enti[n] = atof (cd2); 19 gotoxy (POS& posy); clreolo; cprintf ("%10.4g %10.4gjhw, entr[n], enti[n] ); Bool Transfim (Bool esdir, float entro, float enti[], float **apslr, float **apsli, int nmax) { float *salr, *sali; char sgn; float coef, coefg, cosa, sena; int numitrs, iter, numgpos, grupo, ptsgpo2; int n, nini, nfold, dn; float *aper, *apei, *apsr, *apsi; float gr, gi, hr, hi; int num, factor, opuesto; clrscr(); // Asignacion de Memoria para las Secuencias Resultado salr = calloc (nmax/*puntos*/, sizeof(float) ); sali = calloc (nmax/*puntos*/, sizeof(float) ); // Asignamemoria i f (!salr 11 !sali) { // Si memoria insuficiente printf ("Memoria insuficiente. Calculono realizad0.W'); printf ("hPulse 'ESC' para salir .. "); while ( getch() != ESC ); i f (salr) free(salr); // Liberamemoriasiasignada i f (sali) free (sali); return (NO); // E indica no exito 1 // Copia de las secuencias de entrada. // Calculo de la Transformada Rapida de Fourier. sgn = esdir ? -1 : 1; // Signodelexponente / nmax; // Coeficiente delexponente coef = sgn * 2 * "PI 20 numitrs = (int) ( log((doub1e)nmax) / log(2.0) ); // Iteraciones for (iter==O; iter<numitrs; iter++) { numgpos = (int)pow(2.0,(float)iter); /* Grupos: 2"iter ptsgpo2 = (nmax/numgpos) / 2; // Puntos por grupo / 2 coefg = coef * numgpos; // Coeficiente paraestaiter. for (grupo=O; grupo<numgpos; grupo++){ nini = grupo * ptsgp02 * 2 ; // Inicio del grupo en turno nfold = nini + ptsgp02 ; // La mitaddel grupo en turno for (n=nini,dn==O; n<nfold; n++,dn++){ gr = salr[n]; hr = salr[n+ptsgpo2]; gi = sali[n]; hi = sali[n+ptsgpo2]; salr[n] = gr + hr; sali[n] = gi + hi; cosa = cos (coefg*dn); sena = sin (coefg*dn); salr[n+ptsgpo2] = cosa*@-hr) - sena*(gi-hi); sali[n+ptsgpo2] = sena*@-hr) + cosa*(gi-hi); 1 1 1 // Ordena los Resultados de la Transformacion. for (n=l ;n<nmax; n++) { num = n; opuesto = O; factor = nmax; while (factor>l) { factor I= 2; opuesto += (1 & num) * factor; num >>= 1; 1 i f (opuesto>n) { gr = salr[n]; salr[n] sali[n] gi = sali[n]; = salr[opuesto]; salr[opuesto] = sali[opuesto]; sali[opuesto] 1 1 i f (!esdir) for (n=O,apsFsalr,apsi=sali; n<nmax; n++,apsr++,apsi++) { *apsr /= nmax; *apsi I= n m a x ; 1 *apslr = salr; // Asigna arreglos 21 = gr; = gi; *apsli = sali; return (SI); N Indica exito 1 void OpcSal (float tmpr[], float tmpi[], float frcru, float frci[], int nmax) { Boo1 haydom, hayopc, slvdot, slvdof,salir, exito; int dom, opc; char car; float *secr, *seci; float *ssup, *sinf; const const const const posx= 6; posy= 21; xdom= 4; xopc= 27; // Posicion de inicio de mensajes N Posicion horizontalde los menus N de dominio y mostrar haydom = NO; hayopc = NO; slvdot = NO; slvdof = NO; salir = NO; do DespMenuO; if (haydom) Indicar (xdom, dom); opc); if (hayopc) Indicar (xopc, gotoxy oposx,PosY); printf("1ndique su seleccion: .. "); car = getcho; dellineo; gotoxy (Po~x,PosY); if (car-='t' I( car-='f) { dom = (car-='t') ? T W O : FREC ; secr = (car=='t') ? tmpr : ficr ; seci = (car-=lt') ? tmpi : frci ; haydom = SI; 1 else if (car=='r' 11 car=='m' 11 car=='p') { opc = (car=='r') ? REAL : (car=='m') ? MAGN : POTN ; hayopc = SI; 1 else if (car=='g' 11 c p ' l ' ) { 22 i f (!haydom 11 !hayopc) { i f (!haydom) printf ("No ha elegido dominio. PulseESC .. "); else printf ("No ha indicado que mostrar. PulseESC .. "); while ( getch() != ESC ); I else { exito = Calcular (&ssup, &sinf, secr, seci, nmax, opc); i f (exito) { i f (car=='g') Graficar (ssup, sinf, nmax, opc); else Listar (ssup, si&, nmax, opc); // No liberar las secuencias si i f (opc!=REAL) { //fueron nocalculadas free (ssup); free (sinf); I // Fin si opc no es REAL I exito // Fin si I // Fin si haydom y hayopc I //esFin car si 'g' o '1' else i f (car=='a') { i f (!slvdot) { printf (%Desea salvar secuencia de tiempo en disco ? (s/n) .."); i f (Aprob()) Salvar (tmpr, tmpi,nmax); I i f (!slvdof) { printf (%Desea salvar secuencia de frecuencia en disco ? (s/n) .."); i f (Aprob()) Salvar (ficr, fici, nmax); I I salir = SI; else if (cF's') { i f (!haydom) { printf ("No ha elegido dominio. PulseESC .. "); while ( getch() != ESC ); I else { Salvar (secr, seci, nmax); slvdot = slvdot 11 (dom=TMPO); slvdof = slvdof 11 (dom=FREC); I I 23 } while (!salir); void DespMenu (void) { clrscr(); gotoxy (895); MODO"); printf("DOMINI0 MOSTRAR gotoxy (698); printfr [TI iempo [R]imaginaria eal e [GI raficar"); gotoxy (6,l O); printf("[F] recuencia [M] agnitud fase y b]istar"); gotoxy (29,12); printf("[P] otencia"); gotoxy (14,16); [A] bandonar"); printf("[S] alvar secuencia 1 void Indicar(int posx, int sel) { int opc; char car; const int maxopc = 3; const int yini = 8; for (opc=O; opc<maxopc; opc++) { gotoxy (posx, yini+ 2*0pc); car = (opc=sel) ? : ; putch (car); I*' 1 Boo1 Calcular (float **apsup, float **apinf, float secru, float seci[], int nmax, int opc) { float *sup, *sinf, val; int n; 24 " i f (opc-REAL) ssup = secr; sinf = seci; /I Si REAL,hay no que calcular { 1 else { N Si MAGN o POTN, inicia N Asignacion de Memoria para las Secuencias. ssup = calloc ( nmax/*elementos*/, sizeof(float) ); sinf = calloc ( nmax/*elementos*/, sizeof(float) ); i f (!ssup 11 !sinf) { /I Si intento fallido printf ("No hay memoria suficiente.ESC para continuar .. "); while ( getcho != ESC ); i f (ssup) free (ssup); /I Libera memoria asignada si i f (sinf) free (sinf); return (NO); N Y regresa 1 N Realizacion del Calculo de las Secuencias. for (n=O; n<nmax; n++) { val = secr[n]*secr[n] + seci[n]*seci[n]; ssup[n] = (opc=MAGN) ? sqrt(val) : val ; val = secr[n] ? atan2 (seci[n], secr[n]) : seci[n] ? M-PI-2 : O ; s i a n ] = (opc-MAGN) ? val : 0.0 ; 1 1 *apsup = ssup; *apinf = SS, return (SI); 1 (si else N Fin no REAL) /I Asigna secuencias exito N Indica void Graficar (float ssupn, floatsinfn, int nmax, int opc) { Boo1 exito; float vmin, vmax,escx, escy, *sec; int sup[2], -21, izq, der, vist; int m=, m a y , alt, x, y, yo; char *let[2], cad[80]; int n; 25 exito = ModoGrafO; if (!exito) return; // Prepara las Cabeceras y Asigna los Limites de las Vistas. maxx = getmaxxo + 1 ; maxy = getmaxyo + 1 ; izq=3*maxx/20; der = 19 * maxx / 20; sup[O] = maxy / 10; inflo] = 17 * maxy / 20; sup[l] = maxy / 10; infIl] = 17 * maxy / 20; let[O] = (opc=FtEAL) ? "Parte Real" : (opc=MAGN) ? "Magnitud" : "Potencia" let[l] = (opc=FtEAL) ? "Parte Imag" : (opc=MAGN) ? "Fase" : ""; // Prepara Cada Vista y Grafica la Secuencia Correspondiente. for (vist==O,sec=ssup;vista; vist++,sec=sinf) { MinMax (sec, nmax, &vmin, &vmax); // Obtiene vmin y vmax settextjustify ( LEFT-TEXT, BOTTOM-TEXT ); outtextxy ( O,sup[vist]-5,let[vist]); // Cabecera settextjustify ( RIGHT-TEXT, TOP-TEXT ); sprintf (cad,"%.3g", vmax*5/255); cad); // Valor y maximo outtextxy ( izq-5,sup[vist], ~printf(cad,"%d", 1); outtextxy ( der,infIvist]+5, cad); // Valor x maximo settextjustify ( RIGHT-TEXT, BOTTOM-TEXT ); sprintf (cad,"%.3g", vmin*5/255); // Valor y minimo outtextxy ( izq-5,infIvist], cad); settextjustify ( LEFT-TEXT, TOP-TEXT ); outtextxy ( izq,inflvist]+5, "O" ); // Valor x minimo escx = (float)(der-izq) / (nmax-1); // Calculaescalas alt = infIvist1-sup[vist]; escy = (vmax==vmin) ? (float) alt : alt / (vmax-vmin); 26 yo = (int) ( escy * (vmax-0.0) ); yo = (yo<O) ? o : (yo>&) ? alt : yo ; yo = yo + sup[vist]; der,yo ); line ( izq,yo, N Calculaorigen (y=O) /I Dibuja eje horizontal for (n=O; n<nmax; n++) { N Grafica y = sup[vist] + (int) ( escy * (vmax-sec[n]) ); x = izq + (int) ( escx * n ); line ( X,YO, X,Y 1; 1 settextjustie ( CENTER-TEXT, BOTTOM-TEXT ); outtextxy ( maxx/2,maxy, "<ENTER> para continuar while ( getch() != 13 ); cleardevice(); ..It); 1 restorecrtmode(); 1 void Listar (float ssup[], floatsfl], int nmax, int opc) { char *letsup, *letinf, car; int n, nini; int maxcol, maxlin, lin, colini; struct text-info info; Boo1 salir; int ancho, anchsec, anchn; int ptsporpant; letsup = (opc-REAL)? "Parte Real": (opc-MAGN)? letinf= (opc=REAL)?"ParteImag": (opc-MAGN)? gettextinfo (&info); maxcol = info.screenwidth, maxlin = info.screenheight; anchsec = 16; anchn = 10; ancho = anchn + 2*anchsec + 4; colini = (maxcol-ancho)/2 + 1; /I El ancho es 46 clrscr(); window ( colini,1, (colini+ancho-l),maxlin ); ptsporpant = (maxlin-5) I 2; 27 "__"L 'I 'I Magnitud Fase 'I: It: Potencia It; It.9 salir = NO; n = O; cprintf ("I %4u 1%13g1%13g I", n++,ssup[n],sinf[n3 ); lin = 5; while ( n<nmax && lin < (maxlin-3) ) { cprintf (Ir+ -------_-_ +"-+_-_-----__-_---;Iq); cprintf("I %4u 1%13gI%13g I", n++, ssup[n], sifln] ); lin += 2; ____________ 1 cprintf (If+ +"); . . . . . . . . . . . . . . . . . . . . . . gotoxy (1 ,maxlin); cprintf [Sliguiente,[Alnterior,[R]egresar"); while ( (car=getch())!='s' && car!='a' && car!='r' ); if (car='a') n = nini ? nini-ptsporpant : nini ; salir = (car=Y) ? SI :NO ; ('I 1 mientras // Fin textmode (BW80); <nmax y no salir // Restaura pantalla void Salvar (floatsecru, float seci[], intnmax) { char march[30]; FILE *arch; Boo1 reint; size-t nr, ni; comt posx = 6; comt posy = 21; // Posicion de inicio de mensajes // Rutina de Apertura de Archivo. 28 .-.- l . . do { gotoxy (posx,Posy); BorrLin (5); printf ("Entreel nombre del archivo: .. "); (nmarch); gets //nombre Entra archivo eldel arch = fopen (nmarch, "wb"); if (!arch) { printf ("\n No fue posible abrir el archivo %s.",nmarch); Intentar de nuevo ? (s/n) .. "); printf (Yn reint = Aprob(); 1 } while ( !arch && reint ); // Finrutinaaperturaarchivo (!arch) if { // Si fraoaso en la apertura gotoxy (Posx,PosY); BorrLin (5); printf("Secuencia no salvada. ESC para continuar while ( getch() != ESC ); return; // Y regresa ..I*); 1 // Escritura del Tamaiio del Arreglo y los Datos. fwrite (&nmax, sizeoqint), 1 /*elemento*/, arch); // Escribe nmax do { datos escritura de //de Rutina nr = fwrite (secr, sizeof(float),nmax /*puntos*/, arch); ni = fwrite (seci, sizeoqfloat),wax /*puntos*/, arch); if (nr!=nmax 11 ni!=nmax){ // Si error de escritura gotoxy (Posx, Posy); BorrLin (5); printf ("Error durantela escritura."); Desea intentar de nuevo ? (s/n) .. "); printf (Yn reint = AprobO; (reint)if // Si reintentar // Restauraarchivo fseek(arch,(long)sizeof(int), SEEK-SET); 1 // Fin si error de escritura } while ( (nr!=nmax 11 nr!=nmax) && reint ); 29 // Fin escritura fclose (arch); /Iarchivo Cierra el if (nr!=nmax 11 ni!=nmax){ /I Sierrordeescritura gotoxy @osx,PosY); error N Indica BorrLin (5); printf("Secuencia no salvada. ESC para continuar .."); while ( getcho != ESC ); return; N Y regresa 1 1 Bool Aprob (void) { char car; Bool resp; while ( (car=getchO)!='s' && car!='n' ); resp = (cF's') ? SI :NO ; return (resp); 1 Bool ModoGraf (void) { int disp, errgrd, static int modo; modo = getgraphmode(); errgraf = graphresult(); N Si graficos no iniciados if (errgraf= grNoInitGraph) { disp = DETECT; initgraph (&disp,&modo,"BGI"); /I Inicializar errgraf = graphresult(); 1 (errgraf if != grOk) { Nhay Si error printf (%I Error: %s\n", grapherrormsg (errgraf)); printf Pulse ESC para regresar.."); while ( getcho != ESC ); return (NO); ('I 1 else { setgraphmode (modo); return (SI); error /I Si no 30 void MinMax (floatsecn, int nmax, float *apmin, float *apmax) { float min, max; int n; min = sec[O]; max = sec[O]; for (n=l ;n<nmax; n++) { if (sec[n] < min) min = sec[n]; if (sec[n] > max) max= sec[n]; 1 *apmin = min; *apmax = max; 1 InicializaModoGrafico() // Start graphics mode and draw labels { int rowpos; int g-driver, g-mode, g-error; detectgraph(&g-driver,&g-mode); initgraph(&g-driver,&g-mode,""); g-error = graphresulto; if(g-erro60) { 1 printf("Error de inicializacibn del modo gráfico %s.\n", grapherrormsg(g-error)); exit( 1); 1 31 CONCLUSIONES En general un sistemadigitaldeadquisicióndedatoscomoelquesedesarrollóenel presente proyecto tiene un amplia gama de aplicaciones tanto en la industria como en la investigación. Específicamente la aplicación que se la dio a este sistema de adquisición de datos fuela de un Osciloscopio Digitalusando una PC. Este Osciloscopio digitalsoporta seííales continuas y nocontinuasenetiempo,desdeunasimpleondasenoidalhastasefialesdeaudio, mientras estas se encuentren en los límites especificados en las consideraciones t6cnicas ya descritas. En esteproyectosedemostróque un sistemadigitales m&vershtilque un sistema analógico, tanto en el disefio como en sus aplicaciones, dando resultados más óptimos. Un ejemplo de ello es el hecho deque, una vez capturada en la computadora, esta se puede procesarsegúnserequiera,desde guardar la informaciónen un disco,hastarealizar un procesamiento de la sefial en un programa de procesamiento de señalesles digitales. Sin embargo, con el desarrollo de este proyecto, se pudo comprender las limitaciones de los equipos digitales incluyendo velocidad de respuesta, capacidad de almacenamiento en memoria, límite de distancias en transmisiones seriales, etc. El propósito de este proyecto eraoperarcon una frecuenciamáxima de 10,000 H z , lo cual fueimposible dada las velocidadesalcanzadasdurante la transmisiónenelpuertoseriede la PC, donde la velocidad de transmisión m e a es de 9600 bauds. Por lo que en teoría, según el teorema de muestreo, la frecuencia mas alta muestreable es de (9600/2) Hz, lo cual equivale a una frecuencia de 4800 hz. Además se observó que este sistema es muy lento para fines de tiempo real, dado el tiempo de procesamiento de la sefial dentro de la memoria de la PC. 32 BIBLIOGWIA DE APOYO - DAVIOMARC Digital Systems Ed. Wiley, 1983. - BREY,BARRY B. The 2-80 microprocessor Ed. Prentice Hall, 1988. - BOYCE,JEFFERSON C. Digital Computers Fundamentals Ed. Prentice Hall, 1977. - FAST AND LS TTL MANUAL Motorola, 1990. - MEMORYDATA MANUAL Intel, 1990. - PHERlPERALS MANUAL Intel, 1990. 33