Está en la página 1de 84

Proyecto Final

Osciloscopio de Almacenamiento Digital para PC

Robert Prez 7mo KA Ao 2004 I.T.S Montevideo - Uruguay

Proyecto Final DSO para PC

Robert Prez

Indice:
Introduccin 3

Teora:
Diferencias entre DSOs y Osciloscopios Anlogos Teora de Muestreo Frecuencias o seales Alias Que es un ADC ? Muestreo y retencin Arquitectura de Conversores ADC: Conversores Flash Conversores Half-Flash Conversores SAR Conversores Integradores Conversores Pipeline Conversores Delta-Sigma Oversampling Noise Shaping Cuadro de comparacin de Arquitecturas Circuitos de trigger 4 5 8 9 10 11 11 12 12 13 14 15 17 17 18 19

Diseo
Caractersticas y descripcin del equipo: Diagrama General Placa de captura Placa de control Descripcin del Software del Microcontrolador PIC Placa de entrada Diagrama del gabinete Descripcin del Software de la PC Filtrado digital Anlisis de Costos Conclusin Apndice A Porqu en C ? Apndice B Listado del Software de la PC Apndice C Listado del software del PIC Referencias 20 20 22 27 43 46 47 51 53 55 57 58 77 84

Pgina 2 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Introduccin:
El proyecto que planteo es un Osciloscopio de Almacenamiento Digital para PC. Consiste en un equipo capaz de tomar muestras de una seal analgica, guardarlas en un buffer interno y luego trasmitirlas a la PC para su posterior anlisis. Est compuesto por un hardware externo conectado a la PC mediante el puerto paralelo, que a travs de un software (que tambin es parte del proyecto) me permite construir la seal adquirida en la PC. Actualmente el equipo es capaz de tomar 40MSPS (Millones de muestras por segundo) con una resolucin de 8 Bits. Lo que me permite tericamente adquirir seales menores a 20MHz. Lo que me motiv a hacer este proyecto fue intentar traer una herramienta imprescindible hoy en da a mas tcnicos e ingenieros de Uruguay, buscando formas para reducir los costos pero a su vez implementar prestaciones que no se encuentran en los Osciloscopios analgicos. Al usar la PC para almacenar y reproducir las seales adquiridas, los costos se reducen dado que no hay que usar un TRC (y circuitos asociados) y adems me permite realizar varias funciones que solo se encuentran en los Osciloscopios digitales (filtrado digital, almacenamiento de seales, etc.) Vale aclarar que este proyecto no es un producto final terminado, sino que es el comienzo de un estudio y posible desarrollo de estos equipos, aunque bastante avanzado en algunas etapas hay otras a las que se le ha dedicado poco tiempo debido a la complejidad de todo el equipo en su conjunto (Hardware y Software) El informe empieza primero con las diferencias y similitudes entre este tipo de equipo y las versiones analgicas, luego sigue una introduccin a la adquisicin de seales para despus empezar a explicar el funcionamiento del equipo.

Pgina 3 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Teora: Diferencias entre DSOs y Osciloscopios Anlogos


Para ver las diferencias entre estos dos equipos debemos fijarnos en los diagramas en bloques que se muestran mas abajo.
Amplificador / Atenuador Vertical

T.R.C.

Generacin de Trigger

Generacin de Barrido Horizontal

Fig. 1 Diagrama simplificado de un Osciloscopio analgico. En un Osciloscopio Analgico la seal entra a la etapa de amplificacin / atenuacin (segn lo que corresponda hacerle a la seal, se selecciona desde los controles del Osciloscopio) donde es acondicionada para provocar la deflexin vertical del haz en el T.R.C (Tubo de Rayos Catdicos) y adems se usa para generar el trigger (disparo) sincronizando as el barrido de las seales siguientes y dando la sensacin de que la seal est inmvil (si esta es peridica). La etapa de trigger alimenta la etapa de generacin de barrido horizontal, que es un generador de seal en forma de rampa que vara su perodo segn se ajuste el control de base de tiempo del Osciloscopio. Veamos ahora el esquema de un DSO.
Clock de captura Sistema digital de visualizacin Amplificador / Atenuador Vertical

ADC T.R.C.

Generacin de Trigger

Buffer para muestras

Microprocesador o controlador

Fig. 2 Diagrama en bloques bsico de un DSO. A simple vista el diagrama en bloques del Osciloscopio Digital de Almacenamiento (DSO) tiene mas componentes que el analgico. Podemos ver que difiere en varios aspectos:

Pgina 4 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

El corazn del sistema es el ADC (Conversor Analgico/Digital) que convierte la seal analgica en un flujo de nmeros que representan la seal analgica (si el ADC es de 8Bits los nmeros van del 0-255 y si es de 12Bits van del 0-4096), estos se almacenan en el buffer (Memoria SRAM o FIFO) temporalmente para despus mostrarlos en la pantalla. El Microprocesador o Microcontrolador sincroniza el funcionamiento de las diferentes etapas. Primero habilita el ADC para que empiece a convertir (si es necesario espera una seal del circuito de trigger ) y almacena las muestras en la memoria. Luego detiene el ADC y lee la memoria para enviar las muestras adquiridas a la etapa de visualizacin. El Clock de captura fija la frecuencia a la que se adquieren muestras, que se puede variar para no llenar la memoria con muestras redundantes (es innecesario capturar una seal de 100Hz a 40MSPS, aunque si se desea es posible.) La etapa de visualizacin digital consiste en un DAC (Conversor Digital / Analgico) que convierte las muestras adquiridas en una seal analgica para alimentar el TRC o LCD segn corresponda, adems de generar las seales de barrido para el caso del TRC. La complejidad que agrega este tipo de equipos se compensa con la posibilidad que ofrecen de almacenar las seales adquiridas para su posterior anlisis, o poder recorrer una seal adquirida de punta a punta (ampliarla o reducirla segn se necesite), medir tiempos entre eventos por medio de cursores, etc.

Teora de Muestreo
Si tomamos muestras de una seal analgica podemos llegar a pensar que estamos perdiendo la informacin correspondiente a los puntos de la seal en los que no tomamos muestras, esto no es as si tenemos en cuenta el Teorema de Muestreo que explicamos a continuacin. El teorema de muestreo dice: Una seal limitada en banda f(t) de valor real sin componentes espectrales por encima de una frecuencia de B Hertz, se determina en forma nica por medio de sus muestras equidistantes en intervalos no mayores a 1/(2B) segundos. Este enunciado se puede demostrar por medio de la propiedad de modulacin de la Transformada de Fourier. Tenemos una seal limitada en banda f(t) (o sea que no tiene componentes de frecuencia por encima de B Hertz), a la que se le toman muestras a intervalos de tiempo regulares usando la funcin peridica pulso cuadrado donde cada pulso tiene una amplitud unitaria, tiene segundos de ancho y ocurre a intervalos de T segundos. Nombrando a la seal muestreada fs(t) y la funcin pulso cuadrado peridico p(t), podemos escribir:

Pgina 5 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


f ( t) s f ( t) p ( t)

Robert Prez

Pero como p(t) es peridica, podemos representarla por su serie de Fourier

f ( t)

f ( t)
n

Pn

j n c t

Donde c = 2/T . Aplicando la Transformada de Fourier en ambos lados de la ecuacin tenemos


Fourier

(f ( t ) s )

Fourier f ( t )
Pn

Pn e

j n c t

( )s
n

Fourier

(f ( t )

j n c t

Si usamos la propiedad de traslacin en frecuencia de la Transformada de Fourier, tenemos


F ( )s

Pn F ( n c )

Sacando el termino para n=0 fuera de la sumatoria, resulta

F (

)s

P 0 F (

Pn F ( n c )

(con n 0)

De esta forma resulta evidente que la densidad espectral (Transformada de Fourier) de la seal f(t)s es, salvo por la constante multiplicando, igual a la densidad espectral de la seal muestreada f(t) dentro del ancho de banda original. Luego se repite a si misma en forma peridica cada c radianes/seg, quedando cada repeticin multiplicada (o modulada) por los coeficientes de la serie de Fourier de la seal de muestreo. Notar tambin que la densidad espectral de la seal original se puede recuperar usando un filtro pasa bajos a la frecuencia c/2 (en la figura aparece como o/2). Vemoslo representado en las figuras de abajo para entenderlo mejor.

Pgina 6 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 3. En la figura 3.a vemos la seal f(t) limitada en banda, a la derecha tenemos su equivalente en el dominio de la frecuencia, donde podemos ver que efectivamente no tiene componentes por encima de |B| Hertz (o W radianes/seg).En la figura 3.c tenemos la seal de muestreo que tiene forma de tren de pulsos peridicos, separados T segundos, con amplitud unitaria y con una duracin del pulso alto de segundos. A la derecha tenemos la representacin de la densidad espectral para esta funcin, tiene una envolvente de la forma (sen (x))/(x) con cada componente separada o rad/seg En la figura 3.e, tenemos la funcin f(t)s que es el resultado de multiplicar las dos seales anteriores en el dominio del tiempo, y a la derecha tenemos su representacin en el dominio de la frecuencia, en ella podemos apreciar que aparecen varias copias del espectro de la

Pgina 7 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

seal original modulados por la envolvente de la densidad espectral de la seal de muestreo y desplazada hacia ambos lados a una frecuencia angular de c radianes/seg Tambin vemos que una copia del espectro se encuentra en = 0 que es el espectro de la seal original que podemos recuperarlo con un filtro pasa bajos a la frecuencia de c/2. Esto es lo mismo que explicamos mas arriba con los resultados de las cuentas. Veamos ahora que pasa si variamos la frecuencia de la seal de muestreo. Recordar que c = 2/T , por lo tanto T= 2/c Si T disminuye c aumenta y las copias del espectro de la seal original se separan cada vez mas lejos evitando as que se superpongan e interfieran unos con otros. Por otro lado si T aumenta c disminuye y las copias se juntan cada vez mas hasta que llegamos al punto critico donde W=c/2 en este punto si seguimos disminuyendo la frecuencia de muestreo, los espectros vecinos se traslapan entre s provocando distorsin. Teniendo en cuenta que 2W=c=2/T , y sabiendo que W=2B tenemos que 2(2B)= 2/T o 2B=1/T entonces B=Fs/2 siendo Fs=1/T y es la frecuencia de muestreo. Este es el punto en el que los espectros se traslapan entre si, pero nosotros queremos evitar eso, as que B<Fs/2 (esto tambin se conoce como Frecuencia de Nyquist.) siendo B el ancho de banda en Hertz de la seal que queremos muestrear o la maxima componente de frecuencia de la seal a adquirir. La pregunta que queda ahora es, que pasa si no hacemos esto ?, es decir, si muestreamos por debajo de esta frecuencia mnima, dijimos que aparece una distorsin, pero de que forma ? Aparecen las seales o frecuencias alias.....

Frecuencias o seales alias:


Las frecuencias o seales Alias aparecen por no cumplir con el Teorema del Muestreo. Las copias de los espectros de la seal original se traslapan entre si y aparecen seales con frecuencias que estn relacionadas con la suma y diferencia de las componentes en de la seal muestreada y la frecuencia de muestreo. Para asegurarnos de que complimos con el Teorema del Muestreo colocamos un filtro pasa bajos en la entrada del conversor ADC a la frecuencia de FS/2 para evitar que toda componente mayor a esta frecuencia llegue al conversor. Prcticamente esto es imposible, por lo que se usan filtros de mas de un orden para obtener una respuesta lo ms brusca posible, pero sin afectar demasiado la fase o la distorsin de la seal de entrada. Tericamente al cambiar la frecuencia de muestreo deberamos tambin cambiar la frecuencia de corte de este filtro. Por razones que explicaremos cuando hablemos de la etapa de entrada del equipo este DSO no tiene un filtro pasa bajos a la entrada, lo que tiene el inconveniente de permitir el pasaje Pgina 8 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

de frecuencias mayores a la de Nyquist, provocando as la generacin de alias en las seales. Que es un ADC ?: Las diferentes formas que tiene un ADC para convertir la seal analgica en digital varan de un integrado a otro. Esta depende de la arquitectura del conversor, algunos tienen como ventaja la velocidad de conversin, mientras que otros tienen la ventaja de una mayor resolucin (nro de Bits).

Figura 4 Describiremos brevemente un conversor genrico a modo de ejemplo y luego los ms usados: Este tipo de conversor que vemos en la Figura 4 es un conversor simple e intuitivo (aunque es muy parecido a la arquitectura de ADC Integrador como veremos mas adelante) pero sirve para explicar el funcionamiento bsico de un conversor ADC. Consiste en un conversor DAC que es alimentado por un contador. Cuando damos la orden para empezar la conversin (ponemos el pin de Reset en 1) el contador comienza a incrementarse en uno a la frecuencia fijada por el reloj de 1Mhz. Dado que el contador alimenta el conversor DAC, a la salida del mismo vemos una tensin analgica en forma de rampa (o escalera ascendente). Cuando esta tensin supera la seal de entrada el comparador deshabilita el Clock por medio de la compuerta AND y el valor digital correspondiente a la seal analgica se encuentra en el contador y sale al exterior por medio del Buffer 74245. Este tipo de ADC si bien sirve para explicar el funcionamiento bsico de un conversor no es tan eficiente como parece. Por ejemplo si la tensin analgica es muy alta, el DAC demorara mas tiempo en llegar a una tensin comparable ya que empieza en 0 y se va incrementando con el tiempo a medida que el contador se incrementa. A su vez el tiempo Pgina 9 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

de conversin no es constante sino que depende de la tensin de entrada. Estas cosas son las que se tratan de corregir con otras arquitecturas como veremos a continuacin, pero antes veremos otro componente de los conversores ADC que a veces se encuentra integrado en el mismo IC o fuera del mismo como otro circuito aparte, el circuito de Muestreo y Retencin.

Figura 5 Normalmente es necesario tomar la tensin de entrada a la hora de convertirla y mantenerla hasta que se termine de convertir. Para esto se crearon los circuitos de muestreo/retencin (Sample & Hold , o S&H). Como vemos en la imagen de arriba, un circuito de S&H se compone principalmente de un switch y un elemento almacenador como un capacitor. Lo que hacemos es cargar el capacitor a la tensin instantnea de entrada y luego abrir el switch. De esta forma el capacitor mantiene la tensin instantnea de la seal hasta que lo hagamos de nuevo para la prxima muestra. Lo que hace este circuito es mantener la tensin constante mientras estemos convirtiendo la muestra a digital, dado que si vara la tensin el conversor puede determinar un valor errneo para el equivalente analgico. Pgina 10 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

En la figura tambin vemos que hay dos amplificadores operacionales, en realidad esto es para mostrar que estamos aislando la seal de entrada del elemento almacenador, y tambin hacia la salida tenemos un operacional para proporcional una impedancia de carga alta, de esta forma el condensador demora mas en descargarse. Actualmente en circuitos integrados se usan MOSFETs como switches y se usa la capacidad que hay entre puerta y surtidor para almacenar el valor instantneo durante un corto tiempo.

Arquitecturas de Conversores ADC:


Veamos ahora las distintas arquitecturas que hay disponibles de conversores ADC Conversores FLASH Los conversores Flash usan una cadena de comparadores junto con divisores resistivos para obtener el equivalente digital de la seal aplicada a la entrada. Las tensiones de comparacin estn 1LSB separadas entre s, 1LSB es el valor de tensin correspondiente al

Figura 6 mnimo cambio en el valor digital, si tenemos 256 valores posibles (conversor de 8Bits) 1LSB es Vref/256. De acuerdo al nivel de la tensin de entrada los comparadores generan un 1 o un 0 de acuerdo si es mayor o menor a su tensin de referencia. Luego la lgica combinacional tiene que cambiar la codificacin ya que tomando solamente la salida de los comparadores obtenemos un cdigo de termmetro que se debe convertir a binario o a lo que sea necesario (se le dice cdigo termmetro porque es parecido a como sube el mercurio en un termmetro con la temperatura.)

Pgina 11 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Tienen la desventaja de requerir 2n 1 comparadores (seran 255 para un conversor de 8Bits) junto con sus resistencias (2n) , lo que los hacen econmicamente inviables para resoluciones mayores a 8 o como mximo 10Bits. La ventaja es que son los ms rpidos de todos ya que tienen el menor tiempo de retardo. Conversores Half Flash Estos conversores usan tambin comparadores, pero la diferencia con los Flash es que convierten en dos etapas. Primero obtienen la mitad superior de los Bits (los mas significativos), luego alimentan este valor a un DAC y por medio de un circuito restador obtiene la diferencia con la seal a medir. Luego alimentan esta diferencia a un ADC para obtener los Bits menos significativos (incluso es posible usar el mismo ADC que la vez anterior si usamos un circuito de S&H extra.) La ventaja de estos conversores es que solo usan 2x(2n/2 1) comparadores (o solo 2n/2 1) si usan el mismo ADC para ambos casos, por lo tanto si usamos 8Bits, tenemos 15 comparadores en vez de 255. Se podran considerar como un conversor Pipeline de dos etapas (ver mas adelante), aunque tambin se puede llegar a usar el mismo ADC Flash para convertir las dos veces, disminuyendo as la cantidad de comparadores en el chip. La desventaja que tienen es que en comparacin con los FLASH son mas lentos ya que hay mas tiempos de propagacin agregados por las dos etapas, el restador, etc. Conversores SAR Los conversores SAR (Succesive Aproximation Register o Registro de Aproximaciones sucesivas), se llaman de esta forma porque contienen un registro de este tipo. Estos conversores usan un algoritmo de bsqueda binaria para converger en la seal de

Figura 7 entrada. Bsicamente usan una tcnica que nosotros usamos normalmente aunque sin darnos cuenta. Por ej., cuando buscamos una pagina en un libro no empezamos a contar desde la primer pagina una por una hasta llegar a la pagina deseada. Si no que vamos hasta la mitad del libro (mas o menos a la mitad), y si la pagina estaba antes volvemos un poco para atrs o si estaba despus vamos mas hacia delante, y as hasta encontrar la pagina deseada ,estos conversores hacen algo similar. Como vemos en la figura la seal de entrada pasa por un circuito de retencin y alimenta la entrada no inversora de un comparador.

Pgina 12 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

La lgica SAR, carga en el registro un valor digital correspondiente a Vref/2, o sea 100....000 en binario. Con ese valor en la salida del DAC hay una tensin que es igual a Vref/2, la salida del comparador indica cual tensin es mayor. Si la salida del DAC es mayor, en el registro se cambia ese 1 por un 0 y se sigue con el siguiente bit, y si la tensin de entrada es la mayor se deja el primer uno y luego se pone el siguiente bit en 1 para seguir con el proceso. Luego de N decisiones de este tipo tenemos el valor digital de la tensin de entrada en el registro SAR de N Bits. Estos conversores tienen como tope unos pocos MSPS y con resoluciones no mayores a 14 o 16 Bits. La velocidad de estos conversores est limitada por el tiempo de establecimiento del DAC, el del comparador y los tiempos de propagacin de la lgica empleada, aunque su ventaja es la baja disipacin de potencia y su capacidad para ser integrado en poco espacio, lo que permite integrarlo con otros componentes (Microcontroladores por ejemplo).

Figura 8 En la Figura 8 vemos como un conversor ADC SAR de 4Bits va convirtiendo una muestra a digital, vemos como la salida del DAC se va aproximando (converge) a la seal analgica a convertir a medida que transcurren los ciclos de reloj. ADC Integradores: Estos conversores se basan en un integrador y un comparador analgico. Como vemos en la Figura 9 (abajo), integramos la tensin de entrada hasta que el comparador detecte que la salida del integrador es mayor que la tensin de referencia. Medimos el tiempo que esto demora en suceder (quizs con un contador) y este valor es proporcional a la tensin de entrada (Tint Vin). Si bien es fcil de implementar, el inconveniente que tiene este sistema es que la precisin del integrador depende de los componentes R y C. Si estos varan con la temperatura, frecuencia, tensin o cualquier otro parmetro (y seguramente lo harn) tendremos una conversin que no es precisa. Para eliminar este problema se usan dos ciclos de integracin (conversores de doble pendiente) como vemos en la Figura 10. Primero integramos contra una tensin de referencia interna y luego de-integramos con la seal de entrada. De esta forma en los dos ciclos eliminamos los inconvenientes de los componentes, ya que Pgina 13 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

cualquier error introducido por la precisin de los componentes se cancela en la etapa de de-integracion. En este caso el tiempo de de-integracion es proporcional a la tensin de entrada y tambin al tiempo de integracin, cancelndose as entonces la imprecisin de los componentes.

Figura 9

Figura 10

Conversores Pipeline (Tubera) Esta es la arquitectura mas nueva en cuanto a conversores ADC, implementan un tipo de

Figura 11 tubera con lo que se consigue ir convirtiendo varias muestras a la misma vez (de manera similar a como los microprocesadores actuales ejecutan mas de una instruccin por ciclo de reloj). De esta manera la cantidad de Muestras/Seg aumenta considerablemente cuanto ms larga sea la tubera y mayor es la frecuencia de reloj. La figura muestra un ADC de 12Bits formador por una tubera de 5 etapas, la ultima siendo un conversor tipo Flash de 4 Bits como los que describimos anteriormente.

Pgina 14 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Empezando desde la izquierda, la seal analgica es muestreada y retenida por el circuito de muestreo y retencin (S&H), luego la primer etapa obtiene una aproximacin de la seal de entrada por medio de un conversor Flash de 3 Bits, la salida de este conversor es llevada a un DAC tambin de 3 Bits que convierte de nuevo ese valor a analgico y se resta de la seal de entrada, obtenindose as un residuo que es amplificado por 4 y luego pasa a la siguiente etapa. Ese residuo amplificado por 4 se convierte de nuevo a digital con 3 Bits de resolucin y sigue el mismo proceso que en la etapa anterior. Al final los ltimos 4 Bits se obtienen del conversor ADC Flash de mas a la derecha. La ventaja que tiene esta arquitectura en tubera es que una vez que la 1er etapa aproxima la seal con 3 Bits y pasa el resultado a la siguiente, puede empezar a convertir otra muestra debido al circuito de S&H que tiene incorporado cada bloque. De esta forma se alcanza un mayor flujo de muestras (throughput) en el conversor.

Figura 12 Como vemos en la Figura 12 estos conversores sufren de un fenmeno que se llama Latencia (Latency), el cual hace que el tiempo que demora una muestra en atravesar toda la tubera (o sea en convertirla a digital) sea de N x Tclk, donde N es el numero de etapas de la tubera y Tclk es el periodo del reloj del conversor. As que idealmente si tenemos una muestra, en realidad esta corresponde a un tiempo N x Tclk antes del actual, o sea no es tiempo real, aunque esto se compensa con la ventaja de la tubera de procesar varias muestras a la vez (N muestras a la vez ). Delta Sigma ADCs. Este tipo de conversores tambin es muy popular, usa componentes analgicos simples aunque luego usa filtros digitales y diezmadores digitales que son relativamente complicados. Viendo la Figura 13, la parte analgica consiste en un punto de suma (un restador analgico), un integrador, un ADC de 1 Bit (comparador) y cerrando el lazo de realimentacin negativa un DAC de 1 Bit.

Pgina 15 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 13 La teora de funcionamiento es relativamente simple. Supongamos que la seal de entrada es constante, a la salida del integrador tendramos una rampa (ascendente si la entrada es positiva o descendente si es negativa), la rampa se aplica al ADC de 1 bit (que simplemente es un comparador analgico), este decide si la seal se encuentra por encima o debajo de 0 Volts y genera un 1 o un 0 de acuerdo a esto. Este flujo de unos y ceros se aplica al DAC de 1 Bit transforma un 1 en +Vref y un 0 en Vref, por lo tanto debido al lazo de realimentacin negativa, cuando el circuito se estabiliza tenemos que en el punto de suma (B), el valor medio de la salida del DAC es igual al valor medio de la seal de entrada, y su representacin digital se obtiene del flujo de bits que alimenta el DAC. Este flujo antes de sacarlo hacia el exterior se pasa por un filtro pasa bajos digital que elimina toda componente de frecuencia por encima de la banda que nos interesa. Hay una tcnica muy popular que se llama sobre-muestreo (Oversampling) que consiste en muestrear por encima de la frecuencia de Nyquist (normalmente 64 o ms veces) para reducir el ruido de cuantificacin (ruido producido por el error entre el valor digital y el analgico). Veamos las figuras de abajo... Veremos tambin un circuito que se llama diezmador que realiza un downsampling, lo que hace es dejar pasar una muestra de cada K muestras.

Pgina 16 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 14 Lo que muestran estas figuras es como logramos reducir el ruido usando distintas tcnicas. En la parte superior izquierda tenemos un conversor ADC que no es Delta-Sigma, que corre a una frecuencia de muestreo fs , y vemos que el ruido de cuantificacin (que para una seal senoidal vale q/sqrt(12), siendo q el intervalo de cuantificacin (LSB)) es continuo hasta fs/2 (justamente la banda que nos interesa). Abajo vemos que pasa si usamos la tcnica de Oversampling con el mismo ADC, es decir muestreamos a K.fs , siendo K un nro. entero, luego pasamos las muestras por un filtro digital pasa bajos y luego por un diezmador entre K. A la salida del diezmador tenemos las muestras de la seal como si hubisemos realizado un muestreo a fs Muestras/Seg. A la derecha de esta figura vemos como quedara repartido el ruido de cuantificacin en el dominio de la frecuencia. Tenemos que el ruido de cuantificacin se esparci desde 0 a K.fs/2, pero como nos interesa la banda desde 0 a fs/2 usamos un filtro pasa bajos para eliminar todo por encima a fs/2, eliminando as tambin gran parte del ruido (que en realidad qued reducido en un factor de K). Cuanto ms aumenta la frecuencia de muestreo, mas se reduce el ruido y aumenta el ENOB (Effective Number Of Bits) que depende de la relacin seal ruido que se obtenga en el conversor, al disminuir el ruido, aumenta la SNR y aumenta el ENOB. En la ultima parte de la figura anterior, tenemos un ADC tipo Delta-Sigma con Oversampling, filtro digital y diezmador. El conversor Delta-Sigma proporciona una caracterstica que se conoce como Noise Shaping (modelado de ruido, o darle forma al Pgina 17 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

ruido) , ya que debido a su respuesta en frecuencia (principalmente al integrador), el ruido queda en su mayor parte acumulado cerca de K.fs/2, reduciendo aun mas el ruido luego de aplicar el filtro pasa bajos entre 0 y fs/2. Cuadro de comparacin entre arquitecturas. Como siempre la arquitectura ms conveniente depende de la aplicacin. Si se requiere un conversor rpido, no va a ser de bajo costo. Veamos un par de grficas que nos muestra la relacin entre costos, complejidad, resolucin y velocidad.

Figura 15 Tenemos 3 grficas que muestran las caractersticas de cada arquitectura para que podamos compararlas. En la de arriba a la izquierda vemos la grfica de resolucin/tiempo de conversin, en este caso vemos que si deseamos mantener la velocidad a medida que aumentamos la resolucin lo mejor es un conversor Flash, luego le siguen los SAR y de Tubera, Sigma-Delta y por ultimo los integradores que aumentan en forma casi exponencial el tiempo de conversin para una cantidad dada de Bits de resolucin. Arriba a la derecha vemos la grfica de resolucin/igualdad de componentes (o calibrado de componentes). En esta caracterstica se destacan los conversores integradores, ya que no los afecta la diferencia entre componentes si son de doble pendiente. Las dems arquitecturas dependen de que sus componentes sean iguales (comparadores, divisores resistivos, etc.) Al final tenemos la grfica de resolucin/tamao del IC (o complejidad en cuanto a cantidad de componentes). Ac los que requieren mas espacio en el IC a medida que aumentamos la resolucin son sin duda los conversores Flash, dado que se duplica la Pgina 18 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

cantidad de comparadores (y componentes asociados) cada vez que agregamos un bit de resolucin (por lo tanto son tambin los mas caros). Luego tenemos los SAR, Delta-Sigma, ADCs de Tubera y los que requieren menos espacio en el IC para una resolucin dada son los Integradores. Como siempre, no hay una arquitectura que lo tenga todo (buena resolucin, velocidad y que sea de bajo precio), siempre tenemos que buscar lo que mas se ajusta a nuestras necesidades. Por ejemplo para un voltmetro digital que tenemos que tomar 100 muestras/seg nos alcanza con un ADC integrador. Para Audio se usan mucho los Delta-Sigma porque se obtienen resoluciones bastante buenas y bajo ruido debido al Noise-Shaping. Para equipos de adquisicin de datos (DSOs, imagen, etc.) se usan ADCs Pipeline o ADCs Flash ya que normalmente se requieren altas velocidades de conversin.

Circuitos de Trigger:
Para que necesitamos un circuito de trigger ? Necesitamos un circuito de trigger para disparar la adquisicin de muestras en un momento determinado. Esto es debido a que si queremos adquirir en forma continua una seal peridica tenemos que encontrar un punto de referencia a partir del cual capturarla. Veamos un ejemplo:

Figura 16 En esta figura tenemos una seal senoidal que es la entrada y un nivel de trigger que son 3.0V. Lo que hacemos es determinar cuando la seal de entrada sobrepasa el nivel de trigger y generar un pulso para empezar a convertir la seal (esto lo hacemos con un comparador). Luego para el prximo ciclo hacemos lo mismo y as indefinidamente. De esta forma logramos que en la pantalla del Osciloscopio veamos la seal inmvil si esta es peridica. Lo anterior corresponde a un trigger de nivel, o sea disparamos la adquisicin de la seal cuando sobrepasa un nivel de tensin fijado por un potenciometro o por ejemplo por un DAC controlado por PC y por un Microcontrolador.

Pgina 19 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Otra forma de trigger que tenemos es un trigger que cuenta la cantidad de pulsos y de acuerdo a esto dispara la conversin de la seal. Por ejemplo en la figura de arriba queremos disparar la conversin luego del 3er pulso del comparador. De esta forma veramos 3 ciclos de la seal senoidal. Todas las variaciones anteriores pueden darse de la forma de flanco ascendente o descendente, lo que tenemos que hacer es usar un detector de flancos (construido con un circuito RC formando un filtro pasa altos) e invertir los pulsos que salen del comparador.

Diseo: Caractersticas y descripcin del equipo propuesto:


Frecuencia maxima de muestreo Ancho de Banda Analgico Impedancia de entrada X1 X10 Rango de entrada: X1 X10 Cantidad de canales Potencia de consumo Peso Dimensiones 1 500mA*9V = 4.5W nominales. 420 gr. 160mm X 105mm X 80mm +/- 512mV +/- 5.12V 10K 110K 40MSPS (Millones de muestras por segundo) Tericamente 475Mhz, sin medir prcticamente

Pgina 20 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Diagrama General:
Microcontrolador

Placa de Control Osc 20MHz

Osc 40MHz Lgica Combinacional Contador 16Bits

Atenuador AC/DC

ADC 40MSPS 8Bits

SRAM 32Kbytes @ 25nS

Controles Placa de Captura

Buffer

LPT de la PC

Placa de Entrada

Figura 17 El equipo est separado en 3 PCBs para simplificar su modificacin en caso de ser necesario, la placa de captura, la placa de control y la placa de entrada Cada etapa cumple una funcin especifica, veamos una descripcin bsica. La seal llega hasta la etapa de entrada, pasando por el atenuador y el separador AC/DC que es controlado por un par de llaves en la Placa de Entrada. Luego esta seal se dirige hacia el ADC que segn la orden del Microcontrolador comienza a convertir a digital la seal en su entrada. Las muestras que salen del ADC con una frecuencia de FS muestras/seg se almacenan en la memoria SRAM en la posicin que seala el contador de 16Bits. Luego cuando la PC lo solicite, el Microcontrolador activa el Buffer de 3 estados para que pasen las muestras almacenadas en la memoria hacia el puerto paralelo de la PC, donde el software las lee y luego las grafica en el monitor. Vamos ahora a una explicacin mas exhaustiva de cada etapa.

Pgina 21 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Placa de captura: Es la que contiene el conversor ADC, la memoria, los contadores y el Buffer de 3 estados para la transmisin por medio del puerto paralelo. El esquemtico completo se encuentra al final del informe, explicaremos el funcionamiento de este circuito: El ADC: En el esquemtico de la placa de captura vemos los componentes mas importantes del equipo (salvo el Microcontrolador). En ella se encuentra el ADC (U1 en el esquemtico), que es un circuito integrado de la empresa Analog Devices denominado AD9283. Es capaz de tomar hasta 100MSPS de 8Bits mximo por lo tanto para nuestra aplicacin a 40MSPS sirve perfectamente. Este conversor es de Arquitectura en Tubera (ya explicamos este tipo de arquitectura), tiene entradas analgicas diferenciales, una entrada de reloj para fijar el reloj de captura, una seal de habilitacin que cuando est deshabilitada pone al conversor en un modo de bajo consumo (aprox 4.2mW), tensin de referencia incluida (aunque se puede usar una externa si se desea), y tensiones de alimentacin analgica y digital por separado por si se quiere reducir el ruido en la fuente de alimentacin para las etapas analgicas. Otra de las ventajas de este integrado es que contiene un circuito de muestreo y retencin integrado, evitando as componentes extras para formar esta etapa. Por otro lado el encapsulado del mismo es SSOP de 20 patillas, teniendo una separacin entre patillas de 0.65mm lo que complica su soldadura sin los equipos adecuados (que lamentablemente no dispona) Este integrado funciona con una fuente de alimentacin de 3.4V nominales, por lo tanto no pude usar la misma alimentacin que para los dems ICs, pero le arm una fuente con esa tensin para alimentarlo con un regulador usado de una placa ya que no dispona actualmente de otro y este funciono a la perfeccin. Primero intent usar un LM371 para generar los 3.4V pero dado que es una tensin tan baja no funcionaba correctamente, por eso lo tuve que sustituir. El uso del ICs es relativamente simple, hay que aplicar la seal analgica a convertir en las entradas analgicas en forma diferencial (o en forma Single Ended si se desea conectando /AIN a masa), asegurarse de que la seal de POWERDOWN est en 0 lgico (es activa a nivel bajo) y aplicar la seal de reloj a la patilla ENCODE. La seal de reloj es una onda cuadrada, preferiblemente con 50% de ciclo de trabajo, a la frecuencia que se desea convertir la seal analgica (p.ej, 50MHz si se desea convertir a 50MSPS). Como el IC tiene 4 ciclos de latencia, la primer muestra va a aparecer 5 ciclos de reloj mas tarde desde que empezamos a convertir, aunque en el software ignoramos las primeras 10 muestras porque normalmente son errneas. La latencia de la que hablamos se debe principalmente a la arquitectura del conversor y depende de cuantas etapas halla en la tubera. (ver la explicacin de la arquitectura en las paginas anteriores.) Hay que tener en cuenta de que al conversor no se le deben aplicar mas de 1,024 Vpp entre las entradas diferenciales analgicas (por mas de que el IC tiene diodos de proteccin que recortan las seales por debajo de GND o por encima de VDD) Hay que tener especial cuidado ya que en la Placa de entrada no se tuvo en cuenta el diseo de limitadores o algn circuito de proteccin. A su vez las seales de POWERDOWN y ENCODE antes de llegar al conversor se pasan por un divisor resisitivo (formado por dos Pgina 22 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

resistencias de 4.7K y 10K respectivamente que atenan X0.68) para adaptar los 5V del Microcontrolador PIC al conversor que corre a 3.4V. En cada placa se proveen capacitores de 47nF cerca de cada IC para disminuir el ruido que generar las transiciones de 1 a 0 o viceversa de los circuitos digitales. Adems en esta placa se provee un condensador de 220uF para filtrar la lnea de 5V y luego uno de 47uF para la de 3.4V Memoria: Las muestras que salen del conversor AD, se dirigen hacia la memoria de 32Kbytes de almacenamiento y hacia el buffer de 3 estados, que en el momento de almacenamiento est bloqueando la salida de datos hacia la PC. Esta memoria es de la empresa Alliance Semiconductor , tiene como ya dije 32Kbytes de capacidad organizados en una matriz de 256 columnas por 128 filas, y tiene como interface con el mundo exterior un bus de direcciones de 15 Bits, un bus de datos bi-direccional y 3 seales de control, nWE (habilitacin de escritura), nOE (habilitacin de lectura) y nCE (habilitacin del chip, para poner mas de uno en cascada.) Lo que ms se precisaba en la memoria, es que fuese de un rpido tiempo de acceso ya que a 40MSPS tenemos solo un ciclo de reloj para almacenar la muestra que se adquiri, o sea solo tenemos 25nS. Esta memoria tiene un tiempo medio de acceso de 15nS. El uso de esta memoria lo dividimos en dos etapas, escritura y lectura. Escritura: Para almacenar las muestras en esta memoria lo que hacemos es colocar el valor de 8 Bits en el bus de datos, la posicin de memoria en la que deseamos que la muestra quede

Figura 18 almacenada en el bus de direcciones, poner a 0 la seal de nWE, a 1 la seal de nOE, y a 0 la de nCE (ver nota). Luego subimos la seal de nWE a 1, y la muestra se almacena en la posicin que especificamos en el bus de direcciones. En la hoja de datos de la memoria se especifican los tiempos necesarios para almacenar. Con el oscilador tuve problemas con esta parte y con los niveles TTL de la compuerta que us, mas adelante lo explico en mas detalle.

Pgina 23 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Lectura: Para leer una muestra el procedimiento es similar. Poner la direccin que deseo leer en el bus de direcciones, poner en 1 la seal nWE, en 0 la seal nOE, y en 0 la seal nCE. Cuando subo la seal nOE a 1, el valor almacenado se transporta al bus de datos, desde donde puedo leerlo para enviarlo a la PC.

Figura 19 Nota: normalmente la lnea nCE estara siempre a cero si usamos una sola memoria, pero en el 1er diseo pens en usar dos memorias de 32K ya que como est hecho el impreso podra ir una soldada encima de la otra y doblar la capacidad de almacenamiento. En el diseo final no lo hice, pero la lnea nCE qued cableada al bit 15 de los contadores como vemos en el esquemtico Cuando el valor de la muestra aparece en el bus de direcciones lo que hago es habilitar el buffer de 3 estados para que deje pasar la informacin hacia la PC (esto lo hago poniendo en 0 la seal n2PC en el buffer 78LS245), de esta forma lo puedo leer desde el puerto paralelo de la PC, ya que la salida del buffer de 3 estados est conectado al bus de datos del puerto paralelo (pin 2 al pin 9). Contadores: Son dos contadores de 8 Bits cada uno de la empresa Philips denominados 74F269, y estn conectados en cascada, o sea que cuando unos se desborde (pase de 1111.1111 a 0000.0000), incremente en 1 el 2do contador (vindose efectivamente como un contador de 16Bits). Estos contadores los uso para direccionar la memoria desde la posicin 0 a la 32768. La salida de los contadores est conectada al bus de direcciones de la memoria y el ultimo bit (el bit 15) est conectado a la seal nCE de la memoria. Tambin tengo conectada la seal nCE de la memoria al pin RA4 del PIC, lo que me ayuda a poner a cero los contadores (para mas detalle ver la rutina del PIC ResetCnt() ) La especificacin que tena para estos contadores era que fueran capaces de operar perfectamente a 40Mhz, si nos fijamos en la hoja de datos del componente vemos que operan normalmente hasta los 115Mhz typ, as que estn bastante sobrados. Para incrementar los contadores usamos una seal de reloj que tiene que estar bien sincronizada con la seal de reloj para adquirir las muestras y leer la memoria (ver la placa Pgina 24 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

de control), esta seal est conectada al pin etiquetado cnt_clk del contador (ver esquemtico Placa de Captura) Buffer 3 Estados. Este componente asla el bus de datos del puerto paralelo de la PC. Solo cuando habilitamos la lnea nOE (Output Enable) del buffer, tenemos conexin entre los dos buses. En el IC, la lnea de direccin (DIR) est conectada a un 1 lgico, lo que determina que la direccin es desde el bus de datos de la memoria al bus de datos del puerto paralelo (en el IC desde el Bus A al Bus B). Este componente no tiene requisito de frecuencia de operacin, ya que opera a frecuencias bajas debido a que el puerto paralelo no soporta grandes tasas de transferencias de datos (con el Pic corriendo a 20MHz solo llegu a unos 200Kbytes/seg) En la figura de abajo mostramos el impreso de esta placa (tambin se encuentra en formato PDF junto con las hojas de datos si se desea ver en mejor calidad). En la parte inferior derecha mostramos las modificaciones que se le tuvieron que hacer luego de encontrar fallas en el impreso (por ejemplo en la fuente del ADC y en la lnea de nCE de la memoria)

Pgina 25 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Veamos el PCB de esta placa junto con las modificaciones que surgieron despus.

Figura 20

Pgina 26 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Placa de control La placa de control como lo dice su nombre es la encargada de generar todas las seales para sincronizar el funcionamiento del equipo. Lo que hace es generar las seales de nWE, nOE para la memoria, incrementar los contadores, iniciar o detener el ADC segn estemos escribiendo o leyendo la memoria, y enviar las muestras a la PC por medio del Buffer 74LS245, etc. El esquemtico se encuentra al final del informe junto con los dems, en el vemos un Microcontrolador PIC16F819, un arreglo de compuertas y el oscilador de 40MHz junto con el XTAL para el oscilador del PIC. Los mas interesante aqu es el arreglo de compuertas (La lgica combinacional que figura en el diagrama en bloques) para generar las seales control. Estas toman el Clock que genera el Osc. de 40 MHZ o el que genera el PIC (2.5MHZ) mas algunas seales de control que genera el PIC (nOE_WE y hsclk_en) que son para lectura o escritura de la memoria. Para explicar esta etapa debemos ver tambin el software que tiene cargado el Microcontrolador. El listado completo se encuentra al final del informe, pero aqu veremos las rutinas por separado segn sea necesario. El software del PIC est escrito en el lenguaje C en vez de lo mas comn que es el ensamblador. Lo atractivo de este lenguaje es que es mas simple de entender que el ensamblador, es mas fcil de escribir o implementar una idea que en ensamblador. Para saber un poco mas de porqu us este lenguaje en vez a lo mas comn que es ensamblador, ver el Apndice A, as ahora nos centramos en el Software. El programa comienza en la funcin main() , esta funcin primero llama a otras funciones para inicializar el Microcontrolador y luego entra en un loop infinito (una secuencia que se repite continuamente) que consiste en almacenar muestras en la RAM y luego transmitirlas a la PC. Expliquemos en que consiste esta funcin. void main() { declaraciones.. instrucciones.. instrucciones.. // esto es un comentario /* esto es otro comentario */ } Aqu arriba vemos como se ve un programa simple, la palabra clave void quiere decir algo as como vaco, y significa que la funcin main no retorna ningn valor a la funcin que la llama (en nuestro caso main nunca retorna) Pgina 27 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Las declaraciones e instrucciones dentro de la funcin estn encerradas entre corchetes, las declaraciones son las variables que vamos a usar en las instrucciones y las instrucciones operan en estas variables o en los registros del procesador. Veamos como luce la funcin main de nuestro programa.
void main() { unsigned char cnt,cnt2;

aqu estamos declarando dos variables sin signo de 1 byte de ancho, cnt y cnt2. O sea en estas variables podemos almacenar un valor de 8 bits.
Inicializar(); // Setear los registros TRIS y deshabilitar interrupciones.

Esta funcin lo que hace es setear cuales pines en el PIC vamos a usar para entrada y cuales para salida, deshabilita las interrupciones porque no las usamos, deshabilita el ADC interno porque no lo usamos y setea los valores iniciales de los registros que vamos a usar, mas adelante veremos el cuerpo de esta funcin en detalle. Luego viene el loop infinito que captura las muestras y despus las enva, en el lenguaje C hay varias formas de construir un loop infinito, yo us la instruccin while, que ejecuta lo que est dentro de los corchetes mientras la condicin sea verdadera (en este caso es 1 que quiere decir TRUE), si la condicin en algn momento se hiciera 0, saldramos del loop pero como est puesto un 1 fijo lo que est dentro de los corchetes se ejecuta continuamente una y otra vez
while(condicin) { instrucciones.... }

el loop de nuestro software luce as


while(1) { loop: if(start_conv == 0) goto loop; if(start_conv == 1) goto loop2; loop3: if(start_conv == 0) goto loop3; powerdown = 0; // Habilitar el ADC

loop2:

Pgina 28 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Lo que hacemos aqu es fijarnos si la variable start_conv (que est definida como un pin en algn puerto del PIC que est conectado al LPT de la PC) est en 1 o 0. Lo que hago es esperar una secuencia por parte de la PC para saber que me est pidiendo que comience a capturar y almacenar muestras. El if(condicin) lo que hace es ejecutar la instruccin que est abajo si la condicin es verdadera (en este caso si el BIT start_conv es igual a 0), que en este caso es saltar hacia atrs (a la etiqueta loop:) para volver a ejecutar de nuevo la misma instruccin if y seguir indefinidamente hasta que start_conv se haga igual a 1. Lo mismo pasa con las instrucciones siguientes (3 bloques parecidos) que lo que hacen es definir la secuencia que debe seguir la PC, primero un 1, luego un 0 y finalmente otro 1. Luego de terminada esta secuencia la instruccin powerdown = 0; pone a cero el pin del PIC asignado a esta variable que en definitiva habilita al ADC para que comience a adquirir muestras.

if(nInit == 1) Adquirir40MSPS(); else Adquirir2_5MSPS(); powerdown = 1; // Mandar el ADC al modo de bajo consumo, tambien pone sus salidas en Hi-Z

Luego siguen las siguientes instrucciones, el comando if(nInit == 1) determina si la PC puso esta seal del LPT a uno o cero y adquiere muestras a 40MSPS o 2.5MSPS segn su valor (si es 1, usa 40MSPS y si es 0, usa 2.5MSPS) Las funciones Adquirir40MSPS(); y Adquirir2_5MSPS(); las veremos mas adelante en mas detalle. La instruccin else, lo que hace es ejecutar la instruccin que est abajo si la condicin del if es falsa, en nuestro caso llama a la funcin para adquirir a 2.5MSPS. Al final de todo deshabitamos el ADC (ponemos powerdown = 1) para que las salidas se pongan en alta impedancia y no daarlas por sobrecarga con la salidas de la memoria (sino quedara el ADC como salida y la memoria como salida conectadas en paralelo, si un pin del ADC tiene un 0 y el otro pin en paralelo de la memoria tiene un 1 se produce una sobrecarga de corriente que puede daar el transistor driver del pin de salida.) La hoja de datos del ADC recomienda que cuando deshabitamos el ADC, mandemos unos ciclos de reloj en la lnea de ENCODE para asegurarnos de que valla al estado de reposo, yo en mi caso mando 20 ciclos (la hoja de datos recomienda por lo menos 15). Antes ponemos la seal read_clk en 1 as en la entrada de la compuerta OR que maneja la seal de ENCODE no queda siempre en 1 (notar que la seal read_clk pasa por una NAND antes que invierte la seal), ver el esquemtico para mas detalles. Luego hacemos un loop 40 veces que hace alternar entre 1 y 0 la lnea de ENCODE (en realidad son 20 ciclos completos)

Pgina 29 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


//

Robert Prez

mandar unos ciclos de ls_encode antes de seguir para asegurar el powerdown. read_clk = 1; cnt = 40; while(cnt != 0) { ls_encode = !ls_encode; cnt--; } ls_encode = 0; read_clk = 0;

En esta parte del programa usamos la variable que habamos definido al principio, cnt, en la que primero almacenamos el nro. 40 y luego vamos decrementando de uno en uno (con la instruccin cnt-- que sera igual a cnt = cnt 1; aunque es mas corta), la instruccin ls_enconde = !ls_encode quiere decir que la variable ls_encode (el ls es por low speed, simplemente para recordar que es la seal generada por el PIC), la invertimos con el operador ! NOT y luego la asignamos a si misma, bsicamente la estamos invirtiendo. Lo que logramos es invertir la seal 40 veces, que en sntesis genera una onda cuadrada de 20 ciclos completos en la lnea de ls_encode que est conectada a la compuerta OR y luego al ADC por medio de la lnea ENCODE. Luego de esto volvemos a dejar las seales que usamos en cero, es decir, ls_encode y read_clk ambas igual a cero.
n2PC = 0; EnviarMuestras(); n2PC = 1; } } return; // pasa todo a la PC. // no sale nada hacia la PC, estoy almacenando...

Lo que hacemos despus es poner la seal n2PC (la n quiere decir que es activa a nivel bajo, el 2 es por to PC y el PC es hacia el puerto LPT de la PC, es una nomenclatura normal en programacin, o por lo menos para m ), esta seal si nos fijamos en el esquemtico vemos que est conectada al buffer 74LS245 que deja o no pasar los bits que vienen de la memoria hacia el LPT de la PC (si est en cero pasa, si est en uno no.) As que dejamos que pasen las muestras hacia la PC, y llamamos a la funcin que se encarga de enviar las muestras por el LPT con el protocolo EPP y luego volvemos a hacer que el buffer de 3 estados bloquee todo hacia la PC. La llave que cierra luego de esa instruccin est cerrando el bloque del loop infinito, as que despus de aqu se vuelve a repetir esta funcin. La palabra clave return quiere decir que llegamos al final de la funcin main() por lo tanto del programa, pero como no salimos nunca del loop infinito esto no pasa. La ultima llave cierra el bloque de la funcin main(). Pgina 30 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Expliquemos ahora las funciones auxiliares que llamamos desde la funcin main(). La primera que venia era Inicializar();
void Inicializar() { /* Setear los Puertos, timers, interrupciones, etc..... */ ADCON1 = 0x06; /* */ TRISA = 0b1111.0010; TRISB = 0b1000.1100; powerdown = 1; ls_encode = 0; n2PC = 1; read_clk = 0; GIE = 0; hsclk_en = 0; } /* El ADC arranca deshabilitado (output en HI-Z). */ /* Reloj del ADC arranca en 0. */ /* No se transmite nada a la PC */ /* deshabilitar interrupciones */ /* todava nada de clocks...*/ PORTA es todo digital I/O, con otros valores podemos definir algunas entradas analogicas para usar el ADC interno

La primera instruccin que vemos asigna el valor 6 al registro del PIC ADCON1 que si nos fijamos en la hoja de datos del mismo quiere decir que usamos el puerto A como entrada/salida digital, otros valores nos permiten usar algunos bits para el conversor ADC integrado en el mismo controlador, cosa que actualmente no queremos. Luego seteamos los registros TRIS A y B del controlador, los valores estn en binario (el nibble alto primero y luego del punto el nibble bajo) los bits que estn en 1 son entradas y los que estn en 0 son salidas. Estos valores estn de acuerdo a las definiciones que estn al principio del programa y de acuerdo al esquemtico, que define que seales estn conectadas a que pines del PIC. Los pines de cada puerto estn representados como bit0 = RA0 o RB0 (depende del registro TRIS, TRISA o TRISB), el bit1 es RA1 o RB1 y as sucesivamente. Mas abajo ponemos en el estado inicial las seales de control, los comentarios explican para que sirve cada instruccin. La funcin que sigue es Adquirir40MSPS(); que es la encargada de tomar las muestras y guardarlas en la memoria en la localidad que corresponda. Mostremos el cuerpo de la funcin:
void Adquirir40MSPS() { ResetCnt(); nOE_WE = 1; hsclk_en = 1;

// escribir... // comienza el oscilador de 40MHZ

Pgina 31 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Lo que hacemos antes que nada es resetear los contadores para empezar desde la posicin 0 (mas adelante veremos esta funcin). Luego decimos que vamos a escribir en la memoria, poniendo la lnea de nOE_WE en 1, de esta forma el hardware se encarga de poner la lnea de nWE = 0 y la de nOE = 1, y cuando aplicamos el Clock, la nica lnea que cambia es la de nWE. Despus habilitamos el Clock de alta velocidad, poniendo la lnea hsclk_en (HighSpeed Clock Enable) en 1, de esta forma

/* while(tc2cnt == 0) ; */ #asm loop: BTFSS PORTA,4 GOTO loop #endasm } hsclk_en = 0; ; tc2cnt

// sin reloj de 40

Luego, lo que est entre /* y */ es un comentario, en realidad es lo que el cdigo de abajo hace. El problema aqu era que el compilador me generaba instrucciones adicionales en ensamblador, que no eran necesarias (esto pasa porque me generaba dos instrucciones para el switcheo de banco, que no se precisaban porque siempre estoy en el mismo banco de memoria, pero como el compilador es una versin gratuita no incluye todas las optimizaciones posibles, entonces tuve que recurrir a generar yo mismo las instrucciones en ensamblador, ver el Apndice A para mayor explicacin). Volviendo al cdigo, lo que hacemos aqu es esperar a que tc2cnt se ponga en 1, eso es lo que hacen las instrucciones en ensamblador:
#asm loop: BTFSS PORTA,4 GOTO loop #endasm ; tc2cnt

Las etiquetas #asm y #endasm indican al compilador que lo que est dentro de ellas no es cdigo en C, sino que nosotros decidimos incluir directamente el cdigo en ensamblador y que nos hacemos responsables de que es correcto. Este cdigo lo que hace es probar el Bit 4 de Puerto A (tc2cnt), si es 1 salta sobre la instruccin GOTO y continuamos con la siguiente instruccin, si era 0 quiere decir que todava no llenamos la memoria y tenemos que seguir as que se ejecuta el GOTO loop, y volvemos a probar el Bit 4 del PORTA con la instruccin BTFSS (Bit Test File Skip if Set) Cuando el tc2cnt se pone en 1 es porque llenamos la memoria y tenemos que detener el ADC, que es lo que hacemos mas abajo poniendo la lnea hsclk_en en 0 y ah es donde retornamos a la funcin desde donde est fue llamada. Pgina 32 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Ahora seguimos con la funcin Adquirir2_5MSPS(), que hace lo mismo que la anterior, lo nico que captura a 2.5MSPS.
void Adquirir2_5MSPS() { unsigned char cnt,cnt2; ResetCnt(); nOE_WE = 1; hsclk_en = 0; // write... // sin reloj de 40

Comenzamos definiendo dos variables sin signo de 1 byte cada una, cnt y cnt2. Nos van a servir como contadores para el loop que vamos a describir mas abajo. Antes de empezar a ejecutar alguna instruccin reseteamos el contador con la funcin ResetCnt(), luego seteamos la seal nOE_WE a 1 para indicar que vamos a escribir en la RAM (igual como lo hicimos en la funcin que captura a 40MSPS), y luego ponemos la seal hsclk_en en cero para deshabilitar el reloj de 40Mhz, ya que vamos a generar el reloj de 2.5Mhz con el PIC.
cnt = 0xFF; cnt2 = 2; read_clk=0; //256*(128/2)*2=32768

a las variables que definimos anteriormente ahora le asignamos valores, a cnt le asignamos 255(0xFF) y a cnt2 el valor 2, para entender porque estos valores debemos ser las instrucciones que estn abajo....
// read_clk = RB5 #asm MOVLW 0b0001.0000 next: XORWF XORWF XORWF XORWF XORWF XORWF XORWF PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F // 128*2 veces para completar 128 ciclos de reloj // dejo todos los pines del PORTB // iguales menos RB5 que lo hago subir y bajar.

128 Instrucciones total.

........................ ........................
XORWF PORTB,F XORWF PORTB,F XORWF PORTB,F

Como vemos por la directiva #asm las que siguen son instrucciones en ensamblador, esto es para lograr la mayor velocidad posible. Lo que hacemos es asignar al registro acumulador (W) el valor en binario 0001.0000, esto es para hacer operaciones XOR con este registro y los valores del Puerto B, de esta forma al asignarle solo 1 al Bit 5 logramos que al hacer XOR entre los dos registros sucesivamente el Bit 5 del Puerto B alterne entre 1 y 0 con cada instruccin. Podra haber hecho (en realidad al principio lo hice) un loop mas corto de la siguiente forma:

Pgina 33 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


Loop: XORWF PORTB,F DECFSZ cnt

Robert Prez

(este cdigo no se encuentra en el programa, es a modo de ejemplo) Este cdigo tambin funciona pero el problema que tiene es la velocidad, dado que las instrucciones de salto en el PIC toman dos ciclos de reloj el mnimo periodo que se puede lograr con el PIC corriendo a 20Mhz es de 1.2uS (3ciclos x 0.2uS x 2). De esta forma solo se puede obtener una onda cuadrada con una frecuencia de 1/1.2uS o sea 833.3Khz. La forma alternativa que encontr fue la que mostramos primero, coloqu 128 instrucciones XORWF PORTB,F seguidas y con los contadores ejecuto este loop de 128 instrucciones unas 2x256 veces. Con esto logro 2x256x128 = 32768 ciclos completos de una onda cuadrada. Ya que solo ejecuto 2x256 saltos para ejecutar las 128 instrucciones XOR, en promedio logro una seal cuadrada con un periodo de 2x0.2uS o sea 400nS. Si hacemos el inverso tenemos que la frecuencia de muestreo que obtenemos son 2.5Mhz con el PIC corriendo a 20Mhz.
DECFSZ cnt2,F GOTO next DECFSZ cnt,F GOTO next #endasm }

Al final de la funcin tenemos las instrucciones que decrementan los contadores y cuando se hacen cero salimos de la funcin. Primero decrementamos el cnt2, si no es cero volvemos arriba a ejecutar las 128 instrucciones XOR de nuevo, si es cero decrementamos el cnt, y cuando cnt vale cero retornamos a la funcin que nos llam. Vamos ahora con la funcin ResetCnt()
void ResetCnt(void) { /* ls_encode = 1; read_clk = 0; while(tc2cnt == 0) read_clk = !read_clk; while(tc2cnt == 1) read_clk = !read_clk; read_clk = 0; ls_encode = 0;

// deshabilito el encode, es solo para // incrementar el contador

*/

Por problemas de velocidad y eficiencia esta funcin fue escrita en su mayora en ensamblador. Las instrucciones en C que estn arriba comentadas son solo para mostrar como funciona el algoritmo. Pgina 34 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Como tenemos dos contadores de 8Bits en cascada, son capaces de contar hasta 64K (65536), pero nuestra memoria es de solo 32K (32768). El 15 Bit (empezamos a contar desde el Bit0) est conectado a la lnea de nCE de la memoria que deshabilita el uso de la memoria si est en 1. Por lo tanto la memoria est operativa solo en el intervalo del contador que va desde 0 hasta 32K Lo que hacemos es incrementar los contadores y hasta que nCE (que en el software se llama tc2cnt) sea 1, eso quiere decir que pasamos el intervalo de 0 a 32K, luego hacemos lo mismo pero esperamos que se haga 0 de nuevo, o sea que salimos del intervalo de 32K a 64K y estamos en cero. Luego nos salteamos las primeras 10 posiciones por un problema que tenia antes porque quedaban huecos al principio de la memoria con posiciones sin llenar. Esta fue una solucin simple que le encontr. Expliquemos ahora como est implementado esto en software. Expliquemos solo el equivalente en ensamblador para no tener que verlo dos veces.
unsigned char cnt;

Primero definimos la variable sin signo y de 1 byte de ancho cnt que la vamos a usar al final de la funcin.
#asm BCF BCF BSF BCF m001 BTFSC 0x05,tc2cnt GOTO m002 0x03,RP0 0x03,RP1 0x06,ls_encode 0x06,read_clk

Primero empezamos dicindole al compilador que vamos a escribir instrucciones en ensamblador con la directiva #asm, luego siguen dos instrucciones para especificar que vamos a trabajar en el banco 0 de memoria (ver manual del Microcontrolador para mas informacin), luego ponemos en 1 la lnea ls_encode para solo poder incrementar los contadores pero no mandarle ciclos al ADC por la lnea de ENCODE, fijando esta lnea en 1 la otra entrada de la compuerta OR no cambia el estado de la salida. Adems ponemos la seal read_clk en 0 como estado inicial. Luego nos quedamos en un loop esperando a que la seal tc2cnt se ponga en 0 por lo que explicamos antes mientras no se haga 0 tenemos que generar una onda cuadrada en la lnea de read_clk para incrementar el contador. Esto lo hacemos de forma similar a la funcin de muestreo, hacemos un XOR entre el Puerto B y un valor cargado en el acumulador (W), en este caso el valor es 16 ya que la lnea read_clk est conectada al Bit 5.
MOVLW .16 XORWF PORTB,1 GOTO m001

Eso es lo que hace este grupo de 3 instrucciones, asigna el valor 16 al acumulador, luego hace el XOR entre el acumulador y el Registro PORTB y salta al inicio del loop.
m002 BTFSS 0x05,tc2cnt GOTO m003

Pgina 35 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


MOVLW .16 XORWF PORTB,1 GOTO m002

Robert Prez

Luego tenemos este otro grupo de instrucciones que hace algo similar aunque espera a que la lnea tc2cnt est en 1, el funcionamiento del cdigo es igual al de arriba.
m003 BCF BCF #endasm 0x06,ls_encode 0x06,read_clk

Antes de terminar ponemos las lneas ls_encode y read_clk en cero para su posterior uso. La directiva #endasm indica el final de las instrucciones en ensamblador, ahora nos salteamos las primeras 10 posiciones de memoria en el loop que sigue abajo. Iniciamos el contador a 10 y mientras no sea igual a cero aplicamos un ciclo de reloj al contador para incrementarlo y luego salimos de la funcin al llegar al final.
cnt = 10; // me salteo las primeras 10 muestras

while(cnt != 0) { read_clk = !read_clk; read_clk = !read_clk; cnt--; }

La funcin que sigue ahora es epptx() que transmite un byte por el puerto paralelo de la PC con el protocolo EPP (Extended Parallel Port) que est disponible en PCs desde 486 en adelante. Antes veremos una introduccin a este protocolo. El puerto paralelo a partir de la PC PS/2 de IBM viene con mejoras (LPT de ahora en mas). Normalmente el LPT solo se usaba para enviar informacin al exterior (impresoras, etc..), pero desde el PS/2 de IBM se le agreg la caracterstica de recibir informacin transformndolo en un puerto bi-direccional. Esta caracterstica se controla con el Bit 5 del puerto de control BASE + 2 siendo la direccin base 0x378 o 0x278 en hexadecimal segn el puerto que sea (LPT1 = 0x378 y LPT2 = 0x278 normalmente), entonces BASE+2 es 0x378+2 o 0x278+2 segn corresponda. Luego se le fueron agregando caractersticas como por ejemplo que el protocolo lo controle el hardware del puerto en vez del software de la PC para hacer las comunicaciones mas rpidas y eficientes. Uno de estos protocolos es el que usamos ac para transmitir las muestras de 8 Bits que estn en la memoria. Abajo tenemos una figura en la que mostramos como implementar este protocolo.

Pgina 36 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 21 El ciclo de lectura es el siguiente: 1) El programa de la PC lee el registro de datos. (Base+4) 2) DATA STROBE se activa si WAIT est a nivel bajo. 3) La PC espera el reconocimiento por la lnea WAIT al cambiar a nivel alto. 4) El Dato se lee de los pins del puerto paralelo (D0-D7). 5) DATA STOBE se desactiva. 6) El ciclo de lectura de datos finaliza.

Figura 22 En nuestro caso no usamos la lnea de WRITE, simplemente como el bus de datos est conectado a travs del buffer de 3 estados (74LS245), habilitamos la lnea de n2PC que es la seal que habilita al buffer de 3 estados para que pase el byte que est almacenado en la memoria. Ahora mostramos el ciclo de lectura. Lo nico que vara es la que la lnea de WRITE ahora est en 1 como es activa a nivel bajo est indicando un ciclo de lectura, pero como nosotros no la usamos no cambia nada con respecto al ciclo de escritura..

Pgina 37 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Tericamente con este protocolo se pueden lograr velocidades de transmisin de hasta 2Mbytes/seg, pero con el PIC corriendo a 20Mhz lo mximo que logr fueron unos 200Kbytes/seg. Adems ahora los puertos paralelos tienen una memoria FIFO de 16 niveles que hace de buffer para almacenar los valores recibidos y aumentar la velocidad de lectura o escritura. Mas adelante cuando veamos el software que est del lado de la PC veremos como tenemos que hacer para usar este protocolo a la hora de recibir informacin en la PC. Expliquemos ahora en que consiste la funcin epptx() que hace uso de este protocolo para el envo de los bytes hacia el LPT
/* Transmite un byte al LPT de la PC con el protocolo EPP void epptx() { /* wait = 0; while(datastb == 1) ; wait = 1; while(datastb == 0) ; */ */

Por el mismo propsito que hablamos antes esta funcin est codificada en ensamblador Lo que est entre los delimitadores /* y */ es el equivalente en C del cdigo que implementa el protocolo EPP (es un comentario, el compilador no genera cdigo para este texto, solo est para que el programador pueda hacer anotaciones en medio del programa). Primero ponemos la lnea wait en cero y esperamos a que la PC nos responda poniendo datastb (DATA_STROBE) en cero. Se supone que antes ya tenemos el 74LS245 habilitado para que pase el byte que est en la memoria hacia el LPT. Por lo tanto cuando la PC nos responde, nosotros seguimos con el protocolo poniendo la lnea wait a 1 y luego esperamos a que datastb suba a 1 como respuesta de la PC. Cuando esto sucede ya la PC ley el byte y podemos salir de la funcin.
#asm BCF PORTA,wait NOP m001: BTFSC PORTB,datastb GOTO m001 BSF PORTA,wait NOP m002: BTFSS PORTB,datastb GOTO m002 #endasm }

La ultima funcin que queda EnviarMuestras(), es la encargada de controlar el envo de muestras a la PC, y hace uso de la funcin que describimos anteriormente. Pgina 38 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


void EnviarMuestras() { ResetCnt(); nOE_WE = 0; // lectura

Robert Prez

Primero reseteamos el contador con la funcin ResetCnt() y luego ponemos la lnea nOE_WE en cero indicando que estamos a punto de leer la memoria en la posicin que indica el contador.
while(tc2cnt == 0) { read_clk = !read_clk; read_clk = !read_clk; epptx(); } }

Luego entramos en un loop que incrementa el contador adems de generar los ciclos en la lnea de nOE para la memoria (lo explicaremos mas adelante) y despus enviamos esa muestra hacia la PC por el puerto LPT, pero no salimos del loop hasta que no lleguemos a las 32K muestras indicado por la lnea tc2cnt. Luego de ver el software que est cargado en el PIC podemos pasar a ver el hardware en s. Para ver el esquemtico completo, ver al final del informe donde se muestran. Aqu solo vamos a ver partes especificas del mismo. 5 1 4 2

Figura 23 La placa de control consiste en un arreglo de compuertas (lgica combinacional), el Microcontrolador PIC y los cristales para obtener las seales de reloj. Quiz lo mas importante en la placa de control es la lgica combinacional que genera todas las seales para controlar el ADC, la memoria y los contadores. En la primer compuerta AND que tenemos mas hacia la izq. llega la seal de CLK (40MHZ) desde el oscilador y una lnea (PORTB.0) desde el PIC, esta ultima se usa para inhabilitar el CLK de 40MHZ cuando se va a leer la memoria o cuando se va a adquirir a una frecuencia de Pgina 39 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

muestreo generada por el PIC (en nuestro caso a 2.5MSPS). La salida de esta compuerta AND se dirige hacia una de las entradas de la compuerta OR que est casi en el centro de la imagen. La otra entrada de esta compuerta OR es otra lnea del PIC (PORTB.4) que es CLK generado por el PIC. Cabe destacar que para el correcto funcionamiento cuando voy a usar el CLK de 40MHZ debo poner el otro CLK del PIC en 0 y viceversa (estas son las lneas etiquetadas como 2 y 3 en la imagen). La salida de esta compuerta es una onda cuadrada de 40MHZ o de 2.5MHZ seleccionable desde el PIC, ahora necesitamos una forma de generar las seales de nWE, nOE, ENCODE, y cnt_clk a partir de este reloj. Parte de este trabajo lo hacen las compuertas NAND que siguen. Las 3 superiores forman un de-multiplexor, lo que hace es tomar la seal de reloj y mandarla a una de las dos salidas posibles (U7 o U12) que a travs de las compuertas OR (U8 y U11) alimentan la memoria con las seales nWE para la escritura y nOE para la lectura. Las dos compuertas OR al final fueron necesarias para mantener la sincronizacin entre los tiempos de todas las seales, dado que de alguna forma tena que controlar la seal de ENCODE en forma independiente a la seal de cnt_clk tuve que hacerla pasar por una compuerta para controlarla con el PIC. Dado que las compuertas de la serie 74FXX tienen un tiempo de propagacin medio del orden de 5nS, y que el periodo de la seal de CLK de 40MHZ es de 25nS y que la seal de lectura o de escritura en la memoria tiene que tener un pulso bajo de por lo menos 15nS las seales de control deben estar muy sincronizadas, debido a esto us otras compuertas para mantener un tiempo de propagacin en todas las seales de control constante. La compuerta AND abajo del todo tiene una de sus entradas conectadas a una seal que iba a servir de trigger pero dado que el tiempo no dio para terminar esta etapa qued en espera. Por lo tanto esta entrada est conectada a +V habilitando siempre la seal de reloj.

Figura 24 La siguiente Figura 24 muestra el oscilador de 40Mhz que genera el reloj que fija la frecuencia de muestreo, y el cristal de 20Mhz es el que est conectado al PIC y fija el ciclo de instruccin (200nS). Los capacitores de desacople de 30pF c/u forman junto con el cristal y un inversor dentro del PIC un oscilador a la frecuencia del cristal (para mas detalles ver la hoja de datos del PIC). El oscilador de 40Mhz tiene 3 pines, masa, alimentacin y salida. La salida es una onda senoidal de 5Vpp centrada en la mitad de la tensin, 2.5V. El inconveniente que haba (aunque en realidad no lo pude comprobar con un Osciloscopio, si no con simulaciones) es lo que se muestra en la figura de abajo:

Pgina 40 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 25 La seal senoidal es la que en el esquemtico est como B y la salida de la compuerta AND es la onda cuadrada y est etiquetada como A. El problema parece ser que el pulso bajo de la seal cuadrada no es del tiempo necesario para que se pueda escribir o leer en la memoria. Segn la hoja de datos este tiempo es de por lo menos 15nS, pero si medimos este tiempo en la simulacin tenemos que es de 9.7nS o sea que no vamos a poder almacenar ni leer nada. Esto me di cuenta luego de probar varias veces de adquirir a 40MSPS sin lograrlo. Una forma que se me ocurri de resolver el problema sin modificar mucho el impreso fue agregar un capacitor y un potencimetro como muestra la figura anterior. De esta forma puedo desplazar el la seal de reloj para que el pulso bajo sea mas extenso.

Pgina 41 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 26 Ahora agregamos el capacitor y el potenciometro y podemos correr el nivel de la seal para que se ajuste el pulso bajo al tiempo que necesitamos, esto es lo que muestra la figura que vemos arriba, en donde notamos que el pulso bajo se increment notablemente. Veamos el PCB de esta placa junto con algunas modificaciones que tuve que hacer despus. En la figura de abajo vemos el impreso de la placa de control de ambos lados y luego una vista con los componentes y la modificacin que le tuve que hacer para agregarle el potenciometro y el capacitor a la salida del oscilador de 40Mhz.

Pgina 42 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 27 Eso es todo en cuanto a la Placa de Control, veamos ahora por ultimo la Placa de Entrada. Placa de entrada La placa de entrada consiste en el conector BNC para introducir la seal al DSO, un par de llaves para seleccionar AC o DC y para seleccionar el nivel de atenuacin X1 o X10.

Pgina 43 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 28 Como vemos el switch SW2 deja pasar la seal a travs del capacitor C12 o la deja pasar directo hacia el conversor. El otro switch SW1 manda la seal de entrada directamente hacia el conversor o la hace pasar por la resistencia de 100K que junto con la impedancia de entrada del conversor que es de 10k forma un atenuador de 9:1 y a su vez manda 5V o 0V a la lnea nACK del puerto paralelo segn se seleccione el nivel de atenuacin. De esta forma el software de la PC sabe que nivel de atenuacin se est usando leyendo esta seal. Es justo reconocer que esta etapa es un poco precaria como entrada para el DSO, pero no pude dedicarle mucho tiempo a su diseo ya que lo mas importante era que las placas de captura y control funcionara bien. Sin ellas por mas que pudiera seleccionar varios niveles de atenuacin y por mas que la placa de entrada no introdujera nada de ruido, sera imposible que el DSO funcione. Por eso su diseo e implementacin fue dejada para la ultima parte del proyecto y no fue posible dedicarle la atencin necesaria. Otro componente que le falt a esta etapa es el filtro antialias. Momentneamente me limito a no adquirir seales superiores a 20Mhz aunque esta no es la solucin definitiva. Para la prxima versin en la que se van a agregar un buffer de alta impedancia y una mayor seleccin de niveles de atenuacin se agregar tambin el filtro pasa bajos. Debido al ruido que introduca la placa de entrada en las pruebas preliminares tuve que modificar ligeramente el impreso, cortar conexiones y usar cables coaxiales en un intento de mejorar la situacin. El ruido disminuy, pero no tanto como yo quera. Debido a esto se implemento un filtrado digital por software que veremos mas adelante. Adems de esto se us una placa cobreada entre la de captura y entrada para blindar la ultima del ruido producido por la placa de captura. Las superficies de esta placa estn conectadas a masa para intentar blindar la placa de entrada. Veamos el PCB de esta placa y las explicaciones a las modificaciones realizadas posteriormente para reducir el ruido.

Pgina 44 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Unir con coaxial

Figura 29 En la figura de la derecha vemos donde se cortaron las conexiones del impreso y que se usaron coaxiales para las lneas de nAIN y AIN que van hasta la placa de captura donde est el ADC. Tambin se us un coaxial para la conexin que va desde el BNC hasta la resistencia de 100K.

Pgina 45 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC 160mm


Entrada del Transformador de 9V

Robert Prez

Conector DB25 para el LPT de la PC

80m

160mm

Llave de Encendido

105m
X1 o X10 Llave para seleccionar AC o DC Placa de blindaje Placa de Control Placa de Entrada Separador de plstico Separador de plstico Placa de Captura Disipador para el regulador 7805 Conector BNC para entrada de la seal a

Pgina 46 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Descripcin del Software:


El software del lado de la PC es una aplicacin WIN32 (Windows de 32Bits, que corre en Windows 95 en adelante). No vamos a explicar todo el software que usamos ya que tendramos que explicar el funcionamiento las aplicaciones Windows cosa que estara fuera del alcance de este documento. Pero s explicaremos partes del mismo donde manejamos el hardware externo o cuando dibujamos la seal adquirida entre otras cosas. De todas formas el cdigo fuente completo del programa se encuentra en los apndices al final del documento y en el disco junto con el programa del PIC y dems documentos. Debido a que en Windows 2000 en adelante no se puede acceder a un puerto de la PC directamente, tuve que usar una librera (archivo .dll) para que haga de intermediario con el sistema operativo y as poder leer el puerto paralelo. Esto no pasa en Win9X ya que Microsoft cambi la arquitectura del sistema a partir de Win2K para mejorar la seguridad del mismo. Lectura de las muestras desde la PC: Para leer las muestras desde la PC usamos el siguiente cdigo:
if(IsDlgButtonChecked(hDlg,IDC_40MSPS)==BST_CHECKED) { highspeed = TRUE; F_SAMPLE = 40; } else { highspeed = FALSE; F_SAMPLE = (double)(2.50); }

Este cdigo se fija si est tildado el botn de 40MSPS y si es as pone a verdadero la variable highspeed y la variable F_SAMPLE a 40 indicando la frecuencia de muestreo que vamos a usar
if(highspeed == TRUE) Out32(CONTROL,Inp32(CONTROL)|4); else Out32(CONTROL,Inp32(CONTROL)&0xFB); //40MSPS //2.5MSPS

Luego de esto si vamos a adquirir a 40MSPS ponemos en 1 el bit 3 del puerto de CONTROL (parte del puerto paralelo), el PIC se fija en este bit para saber que frecuencia de muestreo usamos. Si vamos a adquirir a 2.5MSPS ponemos este bit en 0
//Secuencia para que el PIC empiece a adquirir. Out32(CONTROL,Inp32(CONTROL)&0xF7); // pongo en '0' nSelect (para el PIC es '1') Out32(CONTROL,(Inp32(CONTROL)|0x8)); // pongo en '1' nSelect (para el PIC es '0') Out32(CONTROL,Inp32(CONTROL)&0xF7); // pongo en '0' nSelect (para el PIC es '1')

Pgina 47 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Luego de esto la PC pone el bit 4 del puerto de CONTROL en 1,0,1, esta es la secuencia que est esperando el PIC para empezar a convertir.
GetSystemTime(&oldsystemtime); while((Inp32(STATUS)&0x80) == 0) // espera a que busy este a 1 { GetSystemTime(&systemtime); if(systemtime.wSecond > oldsystemtime.wSecond + 5) // espera 5 seg, si no responde aborta. { MessageBox(NULL,"El Hardware no ha respondido en 5seg., erifique que est conectado y encendido","Error",MB_OK); break; } }

Lo que hacemos ac es obtener el tiempo actual y esperar a que la seal de busy est en 1, as podemos leer las muestras por el puerto paralelo. Nos vamos fijando en el tiempo que transcurre, y si pasan mas de 5Seg sin que el Hardware responda, abortamos con un mensaje de error.
/* */ atenuacion = (Inp32(STATUS)&0x40); if(atenuacion != 0) Vdivision = 10*0.163/vertScale; else Vdivision = 0.163/vertScale; me fijo si el botn de X10 est apretado, si est acto en la escala para reflejar el cambio

Lo que sigue es leer desde el puerto paralelo el valor del bit 7 del puerto STATUS. Este bit est conectado a la llave que indica si la seal est pasando a travs del atenuador o no. Si este bit est en 1, multiplicamos la variable Vdivision x 10, que me fija la tensin por divisin que aparece en la grilla del software. Dividimos sobre vertScale que es el zoom que hacemos por software de la seal. Los valores tpicos para la variable vertScale son 0.5, 1, 2, 4 etc.....
for(x=0;x<NUM_SAMPLES;x++) { dato[x] = parallelrx(); }

Luego tenemos el loop donde leemos las NUM_SAMPLES muestras. Llamamos a la funcin parallelrx() que nos devuelve un valor de 8 bits que es igual al valor de la muestra y lo guardamos en el array dato en la posicin x. Cuando llegamos a 128*255 (NUM_SAMPLES) salimos del loop.
Out32(CONTROL,(Inp32(CONTROL)|0x8)); // pongo en '1' nSelect (para el PIC es '0') InvalidateRgn(hWndMain,NULL,TRUE);

Pgina 48 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


UpdateWindow(hWndMain);

Robert Prez

Lo que hacemos despus es poner el bit 4 del puerto de CONTROL en 0 para que el PIC sepa que terminamos de leer las muestras. Las ultimas dos funciones son llamadas a Windows para que dibuje la ventana de nuevo ya que hemos actualizado el buffer con las muestras. Dibujo de la seal en la PC: Para dibujar la seal en la PC lo que hacemos es unir los puntos de las muestras con una lnea y listo (bueno en realidad es un poco mas difcil si queremos desplazar la seal en la pantalla con una barra de desplazamiento). Abajo se muestra el cdigo necesario:
MoveToEx(hDC,Xmargin,intdato[m],NULL); for(x=m;x<(NUM_SAMPLES-Ifiltro); x++) { temp = (double)(x-m)*horScale; if(temp > largo) break; } // corta al final de la pantalla en forma horizontal

LineTo(hDC,Xmargin+temp,intdato[x]);

Este es el bucle en el que dibujamos la seal, primero movemos el cursor al 1 punto en la seal o sea la 1 muestra. Eso lo hacemos con la primer funcin MoveToEx() que es una funcin de Windows. El bucle for que sigue va recorriendo las muestras y uniendo los puntos de la seal. Empieza en la muestra m siendo m un valor que seteamos de acuerdo a donde queremos que comience a mostrar la seal. A partir de ah seguimos hasta el final del buffer, notar que el final del buffer est marcado por el valor (NUM_SAMPLES-Ifiltro), siendo Ifiltro el ndice del filtro (en caso de que no lo estemos usando este valor es 0). Esto es as dado que una vez que filtramos la seal con la PC (por medio de un Moving Average Filter como dijimos arriba), quedamos con un buffer de menos muestras del que tenamos originalmente. En realidad son pocas muestras, en caso de que el ndice de filtro que usemos sea 5, las ultimas 5 muestras del buffer original las perdemos, pero es insignificante en comparacin a casi 32K muestras. Al empezar el bucle calculamos la posicin en el eje X en que vamos a dibujar la lnea (la variable temp), luego en el if nos fijamos si nos pasamos del borde de la grilla, en ese caso abortamos. Y al final dibujamos la lnea desde la muestra anterior a la actual con la funcin LineTo() que es de Windows, nos pide entre otras cosas la coordenada final X e Y. Antes de eso dibujamos la grilla que consiste en 11 lneas horizontales y 11 verticales, as como tambin ponemos los valores de tiempo y tensin en los bordes de la misma. En la figura de abajo mostramos como luce el software mostrando una seal de video...

Pgina 49 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Figura 30 El programa se divide en 3 ventanas: La ventana principal es donde mostramos la seal adquirida junto con la grilla y valores de tiempo y tensin en los bordes de la misma. El cuadro con los controles es desde donde manejamos las escalas de la seal, donde activamos el filtro y donde damos la orden para adquirir muestras, salvar o cargarlas de un archivo en la PC. Por ultimo tenemos la ventana en donde mostramos informacin correspondiente a los dos cursores que vemos en la ventana principal. Con estos cursores podemos medir diferencias de tiempo o frecuencias.

Pgina 50 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Filtrado digital por software: Realmente qued bastante asombrado con esta tcnica, es realmente simple y disminuye en forma significativa el ruido aleatorio sumado a la seal. La desventaja que tiene es disminuir la pendiente de los flancos en la seal, pero no demasiado. Antes de explicar como funciona veamos una muestra. En la figura de abajo tenemos una seal de video filtrada con este mtodo y sin filtrar.

Figura 31 Obviamente la de arriba es la filtrada, fue filtrada con un ndice de 4 y aun as mantiene los flancos bastante rectos. Si seguimos aumentando el ndice disminuye el ruido an mas pero los flancos en la seal empiezan a perder su pendiente.

Pgina 51 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Este tipo de filtro es bueno para eliminar ruido aleatorio sumado a una seal y pero es ineficiente a la hora de separar bandas de frecuencia, cosa que no era necesario en nuestro caso. El funcionamiento es bastante simple, supongamos que tenemos dos buffers en memoria, uno lleno con muestras de una seal adquirida con ruido aleatorio superpuesto, y el otro totalmente vaco. Empecemos con la muestra 1 del buffer vaco, le asignamos un valor igual al promedio de n muestras adyacentes del buffer A partiendo de la 1, luego hacemos lo mismo con la muestra nro. 2 y as hasta el final (las n muestras son el nro. que especificamos como ndice de filtrado). Abajo mostramos una ecuacin donde se ve mas claro el procedimiento.
M 1

b ( j+ i)

aj

a(j) es el buffer de salida, y b(j) es el de entrada (el que contiene la seal a filtrar). Expandiendo esta sumatoria tenemos por ejemplo: usando 4 puntos en el filtro (M=4) para la muestra 20:
a20 b 20 + b 21 + b 22 + b 23 4

=0 M

y para la muestra 21 tenemos


a21 b 21 + b 22 + b 23 + b 24 4

y as hasta que terminamos. En la PC pasamos el algoritmo de filtrado al Lenguaje C, la parte del software que hace el filtrado de la seal es la siguiente:
//filtro int tempsum,i; if(Ifiltro != 0) { for(x=0;x<NUM_SAMPLES;x++) { tempsum = 0; for(i=0;i<Ifiltro;i++) tempsum += intdato[x+i]; } } intdato[x] = tempsum/Ifiltro;

Primero declaramos dos variables enteras de 16Bits tempsum e i. La variable Ifiltro es el ndice del filtro que se selecciona desde los controles del DSO, ya est definida al principio Pgina 52 I.T.S Montevideo-Uruguay Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

del programa. La constante NUM_SAMPLES es igual a 128*255 = 32640 y es el nro. de muestras que hay en el buffer. Lo que hacemos ahora es un loop recorriendo el buffer con las muestras y sacando el promedio de las Ifiltro muestras siguientes para asignarlas al buffer temporal (en realidad uso el mismo buffer, ya que no sacamos el promedio de las muestras hacia atrs, por lo tanto no se ve afectado). Al aumentar el ndice del filtro usamos mas muestras consecutivas en el promedio, esto tiene la ventaja de reducir aun mas el ruido, pero tambin hace que los flancos no sean tan rectos como en la seal original, distorsionando entonces la misma. Por lo que dice en el libro de donde saqu la idea de este filtro la gente que lo usa siempre queda con la idea de que hay que hacer algo mas, en realidad es lo que me pasa ya que fue muy simple implementarlo (desde que lo le hasta que tenia funcionando la 1er versin pasaron 5 o 10 minutos!!!!!!) y los resultados fueron bastante buenos.

Anlisis de Costos:
El costo de diseo del equipo no fue muy elevado dado que varios IC se consiguieron por medio de muestras gratis con las empresas que los fabrican. El costo mas grande fue el de las memorias (5 memorias de 32K @ 25nS de tiempo de acceso), ahora que empece a fijarme en PLDs y FPGAs para la lgica de control quiz hubiese comprado algn IC de ese tipo por el precio de las memoria. (precios de acuerdo a Eneka y Fablett y Bertoni) 5 Memorias 32Kbytes @ 25nS (gastos de envo + impuestos de aduana)U$S 70 Placa de fibra de vidrio doble faz $ 300 Gabinete de plstico $ 380 2 Contadores Muestras gratis de Philips Estimado U$S 20 ADC Muestras gratis de Analog Devices Estimado U$S 30 Buffer 245 $ 20 Cristal 20Mhz PIC $ 30 Oscilador 40Mhz $ 100 Conector para LPT $ 90 Microcontrolador PIC16F819 $ 100 4 Compuertas serie 74F $ 100 Hay que tomar en cuenta tambin el costo de la licencia del software Visual C++ 6.0 que se uso para crear la aplicacin Windows, aunque tambin hay compiladores gratuitos en Internet (quiz el costo de esta licencia ronde los U$S 800 o mas). Se emplearon mas de 250 horas desde el 02/01/2005 (en realidad el diseo empez mucho antes, en abril/2004 cuando cursamos la materia, algunos das me falt anotar las horas y no estn las horas correspondientes a escribir el Informe Final que aprx. son 60). O sea que si damos por finalizado el proyecto al 30/06/2005 tenemos 250Horas/6Meses = 41.7 Horas/Mes y si tomamos 4 semanas por mes tenemos 10.5Horas por semana. Vale destacar tambin que debido al trabajo, solo le poda dedicar mas tiempo los fines de semana, debido a esto se acumulan las 10.5 horas de promedio en el fin de semana...

Pgina 53 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Otra medida del tiempo empleado puede ser tambin las jornadas de 8 horas que hubiese llevado, si son 250 Horas/8horas por jornada, hubiesen sido 31.25 jornadas de 8 horas, poco mas de un mes de trabajo continuo. Lo que ms demor el comienzo del diseo y las pruebas fue conseguir los componentes. Segn la agenda pude conseguir las memorias cerca el 12/04 y qued demorado hasta 01/05 por exmenes. El costo de la memoria fue exagerado, pero en el mercado uruguayo no haba una memoria con tiempo de acceso tan bajo, por eso tuve que recurrir a comprar 5 memorias a travs de JAMECO que es un distribuidor internacional. Lo irnico fue que tuve que pagar mas por los costos de envo e impuestos de aduana que por las memorias. El costo del conversor y contadores es aproximado y no est tomado en cuenta los impuestos y costos de envo. De acuerdo a estos precios, el costo de fabricacin de un equipo sera aproximadamente de $2800 c/u. Estos costos se pueden reducir aun ms comprando los componentes por mayor cantidad y mas todava si centralizamos toda la lgica de control y memoria en un PLD o FPGA. Costo estimado de venta del producto: Como dije en la introduccin del informe, en el estado actual que est el proyecto no est en condiciones de ser un producto comercial. Pero dado que los Osciloscopios Analgicos de 20Mhz actualmente estn cerca de los U$S 600 en nuestro mercado, este producto en buenas condiciones podra venderse fcilmente a U$S 250 o U$S 300 (estimado de acuerdo al precio que tienen equipos similares fuera del pas y que adems hay que sumarle los impuestos de Aduana y envo). En cuanto a buenas condiciones me refiero a una buena etapa de entrada que haga posible seleccionar distintos niveles de atenuacin y seleccionar mas frecuencias de muestreo. Actualmente no est muy lejos de esto, pero creo que sera conveniente disearlo de nuevo con un IC de lgica programable (PLD o FPGA) como explico mas adelante.

Pgina 54 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Conclusin:
He quedado bastante satisfecho con el resultado final del equipo, no pens que podra llegar a trabajar a 40Mhz con placas hechas por mi mismo, realmente es gratificaste. Ahora lleg el momento de las criticas, si bien me gust el resultado hay muchas cosas para mejorar. Principalmente la etapa de entrada carece de un control de ganancia/atenuacin y de un blindaje o diseo mas cuidadoso de la etapa para evitar que el ruido se sume a la seal que nos interesa, adems de un buffer de alta impedancia y un filtro antialias. Quiz el conector BNC se debera haber situado mas cerca del ADC para evitar conexiones largas y por lo tanto mas ruido. Las primeras seales que adquir con el equipo que se ven con menos ruido que las actuales y es porque me estaba salteando la etapa de entrada e inyectando directamente la seal a la entrada del ADC, pero esto cambia al usar la punta para medir y luego pasar todo a travs de la placa de entrada, resultando en una seal mas ruidosa. En un principio pens en usar una etapa de entrada FET diferencial y luego mandar la seal diferencial a un amplificador controlado por DC para manejar el nivel de la seal por medio de una seal de continua con un potencimetro o con PWM desde el PIC (si nos fijamos en el esquemtico el pin de PWM en el PIC est libre, ya que lo haba dejado libre con este fin). Luego de pruebas fallidas con este amplificador opt por simplificar esta etapa y usar directamente la entrada del ADC. Al hacer esto el DSO queda con una impedancia de entrada de 10K que es la interna del ADC (se manejan 1Meg en los Osciloscopios normales, y para medir seales en lneas de transmisin se usan 50 o 75Ohm segn la impedancia caracterstica de la lnea). Carece tambin de un filtro anti-alias o pasa bajos, lo que dejara pasar seales al conversor que tengan componentes mayores a FS/2. Esto si bien es un problema hasta ahora no me trajo problemas visibles ya que no he tratado de adquirir seales mayores a FS/2, aunque puede ser la causa (entre otras cosas) del ruido que hay en la seal. En prximas versiones sin duda tendr que haber un filtro con estas caractersticas, quiz se pueda implementar en el mismo amplificador de entrada, usando algn operacional. Otra cosa para agregar sera una etapa de trigger y la posibilidad de realizar un muestreo continuo, ya que no se pudo implementar un muestreo de este tipo como tena pensado (principalmente por problemas de tiempo) no fue necesario un generador de trigger, pero es algo que debera agregar si considero el muestreo continuo en un futuro. Se pudiera haber usado una memoria FIFO para almacenar las muestras, de esta forma no necesitaramos de contadores para direccionar una memoria SRAM. En un principio se pens de esta forma pero al no encontrar memorias de este tipo opt por la memoria SRAM y los contadores ya que me haban llegado las muestras de Philips.

Pgina 55 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

La lgica usada para controlar el equipo y generar las seales es el principal limitante de la velocidad de operacin del mismo (los contadores llegaban hasta 115Mhz pero las compuertas y la memoria no). Por lo tanto para la prxima versin pienso implementar toda la lgica en un integrado programable (PLD o FPGA) ya que estos integrados operan a frecuencias mayores (normalmente hasta 250Mhz sin problemas y mas....) y me permiten implementar casi toda la lgica de control en un mismo integrado (contador, memoria, circuito de trigger). Adems sera mas fcil hacer actualizaciones al equipo porque todas las conexiones dentro del PLD o FPGA se manejan con software, para actualizarlo seria suficiente con descargar el software de nuevo al IC. La ventaja que tiene reducir la cantidad de componentes tambin es el costo de los mismos, en una produccin por cantidad, reducir 4 o 5 ICs a 1 sera una reduccin de costos interesante. Si pudiera implementarlo en un IC de este tipo incluso se podra reducir las dimensiones fsicas del equipo por lo tanto tambin la cantidad de placas, que determina otra reduccin en costos. Al software de la PC se le pueden agregar anlisis de seales como FFT y clculos entre seales, por ej. si tuviramos dos canales podramos hacer CH1/CH2 y si CH1 fuera una tensin y CH2 una corriente tendramos como vara la impedancia en funcin de la frecuencia. Obviamente para eso tendramos que poder convertir dos canales, cosa que no sera tan difcil como parece si usramos dos conversores y dos memorias o si simplemente intercalamos una muestra de cada canal, obviamente reduciendo la frecuencia de muestreo a la mitad ya que se reparte entre los dos canales. Como se puede ver quedan muchas cosas por corregir y mejoras por hacer pero estoy realmente motivado en seguir con el desarrollo del equipo. Robert Prez 7mo KA I.T.S Montevideo-Uruguay

Pgina 56 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

Apndice A Porqu usar software escrito en C para un Microcontrolador ? Entre algunas caractersticas porque es mas fcil de entender que el ensamblador. Para un programador con experiencia en ambos lenguajes quiz no hay diferencia entre las instrucciones en ensamblador
MOVLW 23 MOVWF reg_a

y su equivalente en C
reg_a = 23;

Pero para un programador con poca experiencia en ensamblador (o para alguien con experiencia cansado de leer muchas lneas de cdigo ) el C resulta mas simple de entender. Tambin es mas portable, ya que el mismo software escrito en C puede ser compilado para que corra en otro Microcontrolador (por ej un 8052 o AMR) que no sea un PIC y no tener que modificar tanto el cdigo, en vez de escribir todo el cdigo de nuevo si estuviera escrito en ensamblador para PIC y quisiramos implementarlo en un 8052 por ej. Estas son algunas de las ventajas que tiene el lenguaje C, como desventaja tiene entre otras el tiempo de ejecucin y tamao del cdigo generado. Debido a que el compilador genera el cdigo equivalente en ensamblador en forma automatizada (quiz haga alguna optimizacin al final de la compilacin) este cdigo puede ser menos eficiente que el generado por un programador con experiencia, pero en buenos compiladores es muy difcil generar cdigo a mano que sea mejor que el que genera el compilador. Porqu usamos entonces este lenguaje si en un Microcontrolador tenemos recursos tan limitados como RAM y EEPROM para almacenar el programa ? Porque los compiladores estn escritos pensando en estas limitaciones y por lo tanto rehusan las localidades de RAM de la mejor forma posible. En cuanto al espacio en EEPROM, tambin se cuida el tamao del cdigo generado rehusando cdigo o arreglando el cdigo en subrutinas para que no se repita varias veces en el programa. Adems siempre est la opcin de codificar partes del programa en ensamblador que sean crticas tanto en tiempo de ejecucin como en espacio de EEPROM. Podemos ver el cdigo que genera el compilador para una funcin dada y si pensamos que podemos implementarlo mejor se puede escribir en ensamblador en lnea, es decir incrustado dentro del cdigo C. Esto ha sido hecho en el software del Microcontrolador para este proyecto, principalmente en la funcin que enva las muestras a la PC y en las funciones para adquirir las muestras dado que se requiere la mayor velocidad de ejecucin. Pero el problema no era el compilador, sino que us una versin de evaluacin que no tiene todas las optimizaciones activadas, por lo tanto tuve que fijarme en la salida del compilador y optimizar el cdigo yo mismo a mano para que sea mas eficiente. (la versin completa ronda los U$S 200, el compilador se llama CC5X C Compiler FREE edition y tiene como limitacin la optimizacin del cdigo generado que solo se pueden compilar programas de hasta 1K) Pgina 57 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC Apndice B Listado del Software de la PC:


// Final Project.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" #include "commrutines.h" #define MAX_LOADSTRING100 #define NUM_SAMPLES double F_SAMPLE=40.00; unsigned char dato[NUM_SAMPLES]; unsigned int unsigned int unsigned int int extern int int short _stdcall void _stdcall int double int double char double char double int double char* double char* void HWND int HINSTANCE TCHAR TCHAR HWND ATOM BOOL LRESULT LRESULT LRESULT LRESULT LRESULT void void void void void void intdato[NUM_SAMPLES]; maxSample = 0; horLines[11], vertLines[11]; atenuacion =0, Invertir=1; int portLPT1; highspeed=TRUE; Ifiltro=0,IfiltroOld=0; Inp32(short PortAddress); Out32(short PortAddress, short data); 128*256

Robert Prez

m=0,bflag=0,bZoom=0,bmiddleY=0,bCur1=0,bCur2=0;; horScale = 1,vertScale = 1,temp=0; yOffset = 0; deltaX,deltaY,largo,ancho,middleX,middleY,middleYConst=1,offsetY; buffer[5]; // para obtener el texto de los controles timeCur1=0, timeCur2=0,timeDiff=0, voltCur1=0, voltCur2=0; ctimeCur1[10], ctimeCur2[10], cvoltCur1[10], cvoltCur2[10]; Vdivision=0.163; Xcur1=75,Xcur2=80; XScaleDouble[] = {8,4,2,1,0.5,0.25,0.125,0.0625,0.03125,0.015625}; XScaleText[] = {"X0.125","X0.25","X0.5","X1","X2","X4","X8","X16","X32","X64"}; YScaleDouble[] = {2,1,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5}; YScaleText[] = {"X2","X1","X0.5","X2","X2","X2","X2","X2","X2","X2"}; double2str(double valor,char* cadena); WndScrollYDiv,hWndScrollXDiv,hWndScrollYOff, hWndCursoresDlg,hWndScrollFiltro; nPosYDiv=1,nPosXDiv=1,nPosYOff=0; hInst; szTitle[MAX_LOADSTRING]; szWindowClass[MAX_LOADSTRING]; hWndMain,hWndControles; // // // // current instance The title bar text The title bar text Main Window

CALLBACK CALLBACK CALLBACK CALLBACK CALLBACK

MyRegisterClass(HINSTANCE hInstance); InitInstance(HINSTANCE, int); WndProc(HWND, UINT, WPARAM, LPARAM); About(HWND, UINT, WPARAM, LPARAM); ControlesProc(HWND, UINT, WPARAM, LPARAM); PuertosProc(HWND, UINT, WPARAM, LPARAM); CursoresProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); DrawGrid(HDC hDC, int Xmargin, int Vmargin); DrawWave(HDC hDC, int Xmargin); SaveToFile(void); LoadFile(void); appendTimeUnit(double time, char *time_buf); appendVoltUnit(double time, char *time_buf);

Pgina 58 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


void void appendHertzUnit(double time,char *time_buf); DrawCursors(HDC hdc, int Yfinal);

Robert Prez

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { int x=0; vertScale = YScaleDouble[nPosYDiv]; horScale = XScaleDouble[nPosXDiv]; initLPT(); MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_FINALPROJECT, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FINALPROJECT); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage is only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FINALPROJECT); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+2); wcex.lpszMenuName = (LPCSTR)IDC_FINALPROJECT; wcex.lpszClassName = szWindowClass;

Pgina 59 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


wcex.hIconSm } = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

Robert Prez

return RegisterClassEx(&wcex); // // FUNCTION: InitInstance(HANDLE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWndMain; hInst = hInstance; // Store instance handle in our global variable

hWndMain = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWndMain) { return FALSE; } ShowWindow(hWndMain, nCmdShow); //UpdateWindow(hWndMain); return TRUE; } // // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; int i=0; short int nPos,xPos,yPos,fwKeys,newM; static short int antX,antY,oldm,firstX,firstY,secondX,secondY,vertPromedio; int nScrollCode; HWND hwndScrollBar; SCROLLINFO scrollinfo; char sample_number[30],string[10]; int Xmargin = 70, Vmargin = 40; static int Hscrollconst=1,Vscrollconst=1; HPEN newPen,oldPen,otherPen; double time; char act_time[20]; unsigned int valor_muestra=0; RECT rect;

switch (message) { case WM_CREATE:

Pgina 60 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


SetScrollRange(hWnd,SB_HORZ,0,Hscrollconst,TRUE); return 0; case WM_HSCROLL: nScrollCode = (int) LOWORD(wParam); nPos = (short int) HIWORD(wParam); hwndScrollBar = (HWND) lParam;

Robert Prez

// scroll bar value // scroll box position // handle to scroll bar

switch(nScrollCode) { case SB_THUMBTRACK: m = (nPos)*(NUM_SAMPLES/Hscrollconst); SetScrollPos(hWnd,SB_HORZ,nPos,FALSE); InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); break; case SB_PAGERIGHT: m += NUM_SAMPLES/10; SetScrollPos(hWnd,SB_HORZ,m/5,TRUE); InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); break; case SB_PAGELEFT: m -= NUM_SAMPLES/10; SetScrollPos(hWnd,SB_HORZ,m/5,TRUE); InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); break; case SB_LINERIGHT: if(m<NUM_SAMPLES) { m += 2; SetScrollPos(hWnd,SB_HORZ,m/5,TRUE); InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); } break; case SB_LINELEFT: if(m>0) { m -= 2; SetScrollPos(hWnd,SB_HORZ,m/5,TRUE); InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); } break; } return 0;

case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDM_EXIT: DestroyWindow(hWnd); break; case ID_FILE_SAVETO: SaveToFile();

Pgina 61 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

break; case ID_FILE_LOAD: LoadFile(); InvalidateRgn(hWnd,NULL,TRUE); UpdateWindow(hWnd); break; case ID_HERRAMIENTAS_CURSORES: hWndCursoresDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_CURSORES), hWnd, (DLGPROC)CursoresProc); ShowWindow(hWndCursoresDlg,SW_SHOW); break; case ID_HERRAMIENTAS_CONTROLES: ShowWindow(CreateDialog(hInst, MAKEINTRESOURCE(ID_CONTROL), hWnd, (DLGPROC)ControlesProc),SW_SHOW); break; case ID_OPCIONES_PUERTOS: ShowWindow(CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOGLPT1), hWnd, (DLGPROC)PuertosProc),SW_SHOW); break; case ID_FILE_FITWAVEFORM: horScale = 0.025; vertScale = 1; middleYConst = 1; InvalidateRgn(hWnd,NULL,TRUE); UpdateWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_LBUTTONDOWN: fwKeys = wParam; xPos = LOWORD(lParam); yPos = HIWORD(lParam); // key flags // horizontal position of cursor // vertical position of cursor

SetCapture(hWnd); if( (xPos <= 30)|(yPos <= 30) ) break; // ignoro todo lo que est fuera de la grilla. if((fwKeys & MK_LBUTTON) && (xPos > (Xcur1-3)) && (xPos < (Xcur1+3))) bCur1 = TRUE; else bCur1 = FALSE; if((fwKeys & MK_LBUTTON) && (xPos > (Xcur2-3)) && (xPos < (Xcur2+3))) bCur2 = TRUE; else bCur2 = FALSE; hdc = GetDC(hWnd); firstX = xPos; firstY = yPos; xPos = m + (xPos - 30)/horScale; time = (double)xPos/F_SAMPLE; valor_muestra = intdato[xPos]; //agrega las unidades al final de la cadena (nS,uS,mS) appendTimeUnit(time,act_time); strcpy(sample_number,"Tiempo cursor: "); strcat(sample_number,act_time); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc,RGB(150,150,150)); oldm = xPos;

Pgina 62 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); bZoom = 1; break; case WM_LBUTTONUP: xPos = LOWORD(lParam); yPos = HIWORD(lParam); bCur1 = FALSE; bCur2 = FALSE; ReleaseCapture(); break; case WM_MOUSEMOVE: fwKeys = wParam; xPos = LOWORD(lParam); yPos = HIWORD(lParam);

Robert Prez

// horizontal position of cursor // vertical position of cursor

// key flags // horizontal position of cursor // vertical position of cursor

GetClientRect(hWnd, &rect); if( (xPos < Xmargin)|(xPos > rect.right-Xmargin) ) break; // ignoro todo lo que est fuera de la grilla. if((bCur1==TRUE) &&(fwKeys & MK_LBUTTON)) { Xcur1 = xPos; if(Xcur1 == Xcur2) Xcur1 = Xcur2 + 2; firstX = m + (xPos - Xmargin)/horScale; timeCur1 = 1000*(double)firstX/F_SAMPLE; appendTimeUnit(timeCur1,act_time); //agrega las unidades al final de la cadena (nS,uS,mS) SetDlgItemText(hWndCursoresDlg,IDC_CUR1TIME,act_time); } if((bCur2==TRUE)&&(fwKeys & MK_LBUTTON)) { Xcur2 = xPos; if(Xcur1 == Xcur2) // para que se separen si los llego a juntar Xcur1 = Xcur2 - 2; // actualizar el label en el cuadro cursores secondX = m + (xPos - Xmargin)/horScale; timeCur2 = 1000*(double)secondX/F_SAMPLE; //valor_muestra = intdato[xPos]; appendTimeUnit(timeCur2,act_time); //agrega las unidades al final de la cadena (nS,uS,mS) // actualizar el label en el cuadro cursores SetDlgItemText(hWndCursoresDlg,IDC_CUR2TIME,act_time); } if((fwKeys & MK_LBUTTON)) { int point=0,sign=0; timeDiff = timeCur2 - timeCur1; appendTimeUnit(timeDiff,act_time); //agrega las unidades al final de la cadena (nS,uS,mS) // actualizar el label en el cuadro cursores SetDlgItemText(hWndCursoresDlg,IDC_TIMEDIFF,act_time); //actualizar la frecuencia calcula como 1/timediff // para que se separen si los llego a // juntar..

Pgina 63 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

appendHertzUnit(timeDiff,act_time); SetDlgItemText(hWndCursoresDlg,IDC_FREC,act_time); InvalidateRgn(hWnd,NULL,TRUE); UpdateWindow(hWnd); } break; case WM_PAINT: hWndMain = hWnd; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd,&rect); DrawCursors(hdc,rect.bottom - Vmargin); DrawGrid(hdc,Xmargin,40); Hscrollconst = 10*((horScale*NUM_SAMPLES)/largo); if(Hscrollconst <= 0) Hscrollconst = 1; SetScrollRange(hWnd,SB_HORZ,0,Hscrollconst,TRUE); TextOut(hdc,Xcur1-4,Vmargin-15,"1",1); TextOut(hdc,Xcur2-4,Vmargin-15,"2",1); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Mesage handler for about box. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; } LRESULT CALLBACK ControlesProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { int idEditCtrl,nScrollCode; HWND hwndEditCtrl,hwndScrollBar; short int nPos; char charYOffset[10]; unsigned int x,serial,cnt; SYSTEMTIME oldsystemtime, systemtime; char buffer[10]; switch (message) {

Pgina 64 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

case WM_INITDIALOG: /* Inicializar los controles. */ hWndScrollYDiv = GetDlgItem(hDlg,IDC_SCROLLYDIV); hWndScrollXDiv = GetDlgItem(hDlg,IDC_SCROLLXDIV); hWndScrollYOff = GetDlgItem(hDlg,IDC_SCROLLYOFF); hWndScrollFiltro = GetDlgItem(hDlg,IDC_SCROLLIFILTRO); nPos = SetScrollRange(hWndScrollYDiv,SB_CTL,0,8,TRUE); SetScrollPos(hWndScrollYDiv,SB_CTL,nPosYDiv,FALSE); vertScale = YScaleDouble[nPosYDiv]; horScale = XScaleDouble[nPosXDiv]; yOffset = 0; Ifiltro = 0; CheckDlgButton(hDlg,IDC_40MSPS,BST_CHECKED); SetDlgItemText(hDlg,IDC_YDIV,YScaleText[nPosYDiv]); SetDlgItemText(hDlg,IDC_XDIV,XScaleText[nPosXDiv]); itoa(yOffset,charYOffset,10); SetDlgItemText(hDlg,IDC_YOFF,charYOffset); SetDlgItemText(hDlg,IDC_IFILTRO,itoa(Ifiltro,buffer,10)); InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); break; case WM_VSCROLL: nScrollCode = (int) LOWORD(wParam); // scroll bar value nPos = (short int) HIWORD(wParam); // scroll box position hwndScrollBar = (HWND) lParam; // handle to scroll bar switch(nScrollCode) { case SB_LINEUP: if(hwndScrollBar == hWndScrollYDiv) { if(nPosYDiv<2) nPosYDiv++; SetScrollPos(hWndScrollYDiv,SB_CTL,nPosYDiv,FAL SE); vertSca le = YScaleDouble[nPosYDiv]; if(atenuacion != 0) Vdivision=10*0.163/vertScale; else Vdivision=0.163/vertScale; InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_YDIV,YScaleText[nPosYDiv]); } else if(hwndScrollBar == hWndScrollXDiv) { if(nPosXDiv>0) nPosXDiv--; SetScrollPos(hWndScrollXDiv,SB_CTL,nPosXDiv,FALSE); horScale = XScaleDouble[nPosXDiv]; InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_XDIV,XScaleText[nPosXDiv]); } else if(hwndScrollBar == hWndScrollFiltro) { Ifiltro++; SetScrollPos(hWndScrollFiltro,SB_CTL,Ifiltro,FALSE);

Pgina 65 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_IFILTRO,itoa(Ifiltro,bu ffer,10)); } else { yOffset -= 4; SetScrollPos(hWndScrollYOff,SB_CTL,yOffset,FALS E); InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); itoa(yOffset,charYOffset,10); SetDlgItemText(hDlg,IDC_YOFF,charYOffset); } break; case SB_LINEDOWN: if(hwndScrollBar == hWndScrollYDiv) { if(nPosYDiv>0) nPosYDiv--; SetScrollPos(hWndScrollYDiv,SB_CTL,nPosYDiv,FAL SE); vertScale = YScaleDouble[nPosYDiv]; if(atenuacion != 0) Vdivision=10*0.163/vertScale; else Vdivision=0.163/vertScale; InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_YDIV,YScaleText[nPosYDiv]); } else if(hwndScrollBar == hWndScrollXDiv) { if(nPosXDiv<9) nPosXDiv++; SetScrollPos(hWndScrollXDiv,SB_CTL,nPosXDiv,FAL SE); horScale = XScaleDouble[nPosXDiv]; InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_XDIV,XScaleText[nPosXDiv]); } else if(hwndScrollBar == hWndScrollFiltro) { if(Ifiltro > 0) Ifiltro--; SetScrollPos(hWndScrollFiltro,SB_CTL,Ifiltro,FA LSE); InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_IFILTRO,itoa(Ifiltro,bu ffer,10)); } else { yOffset += 4;

Pgina 66 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez
SetScrollPos(hWndScrollYOff,SB_CTL,yOffset ,FALSE); InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); itoa(yOffset,charYOffset,10); SetDlgItemText(hDlg,IDC_YOFF,charYOffset); } break;

} break; case WM_CLOSE: DestroyWindow(hDlg); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_ADQUIRIR: { if(IsDlgButtonChecked(hDlg,IDC_40MSPS)==BST_CHE CKED) { highspeed = TRUE; F_SAMPLE = 40; } else { highspeed = FALSE; F_SAMPLE = (double)(2.50); } if(highspeed == TRUE) Out32(CONTROL,Inp32(CONTROL)|4); //40MSPS else Out32(CONTROL,Inp32(CONTROL)&0xFB); //2.5MSPS //Secuencia para que el PIC empieze a adquirir. Out32(CONTROL,Inp32(CONTROL)&0xF7); // pongo en '0' nSelect (para el PIC es '1') Out32(CONTROL,(Inp32(CONTROL)|0x8)); // pongo en '1' nSelect (para el PIC es '0') Out32(CONTROL,Inp32(CONTROL)&0xF7); // pongo en '0' nSelect (para el PIC es '1') GetSystemTime(&oldsystemtime); while((Inp32(STATUS)&0x80) == 0) // espera a que busy este a 1 { GetSystemTime(&systemtime); if(systemtime.wSecond > oldsystemtime.wSecond + 5) // espera 5 seg, si no responde aborta. { MessageBox(NULL,"El Hardware no ha respondido en 5seg., verifique que est conectado y encendido","Error",MB_OK); break; } } /*

Pgina 67 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez
me fijo si el boton de X10 est apretado, si est actuo en la escala para reflejar el cambio */ atenuacion = (Inp32(STATUS)&0x40); if(atenuacion != 0) Vdivision = 10*0.163/vertScale; else Vdivision = 0.163/vertScale; for(x=0;x<NUM_SAMPLES;x++) { dato[x] = parallelrx(); } Out32(CONTROL,(Inp32(CONTROL)|0x8)); // pongo en '1' nSelect (para el PIC es '0') InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); } break;

case IDC_LOAD: LoadFile(); InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); break; case IDC_SAVE: SaveToFile(); break; case IDOK: DestroyWindow(hDlg); return TRUE; break; case EN_UPDATE : idEditCtrl = (int) LOWORD(wParam); // identifier of edit control hwndEditCtrl = (HWND) lParam; // handle of edit control switch(idEditCtrl) { GetDlgItemText(hDlg,idEditCtrl,buffer,5); case IDC_EDIT_VERT: vertScale = atof(buffer); break; case IDC_EDIT_HORIZ: horScale = atof(buffer); break; case IDC_EDIT_OFFSVERT: middleYConst = atof(buffer); break; } break; case IDC_INVERTIR: if(IsDlgButtonChecked(hDlg,IDC_INVERTIR) == BST_CHECKED) Invertir = -1; else Invertir = 1;

Pgina 68 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); break;

Robert Prez

case IDC_ACTIVFILTRO: if(IsDlgButtonChecked(hDlg,IDC_ACTIVFILTRO) != BST_CHECKED) { IfiltroOld = Ifiltro; Ifiltro = 0; } else { if(IfiltroOld == 0) Ifiltro = 4; else Ifiltro = IfiltroOld; } InvalidateRgn(hWndMain,NULL,TRUE); UpdateWindow(hWndMain); SetDlgItemText(hDlg,IDC_IFILTRO,itoa(Ifiltro, buffer,10)); break; } break; } return FALSE; } LRESULT CALLBACK PuertosProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { char buffer[10]; switch (message) { case WM_INITDIALOG: /* Inicializar los controles. */ SetDlgItemText(hDlg,IDC_EDITLPT1,itoa(portLPT1,buffer,10)); break; case WM_CLOSE: DestroyWindow(hDlg); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: GetDlgItemText(hDlg,IDC_EDITLPT1,buffer,10); portLPT1 = atoi(buffer); DestroyWindow(hDlg); return TRUE; break; } break; } return FALSE; }

LRESULT CALLBACK CursoresProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { char buffer[10];

Pgina 69 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

switch (message) { case WM_INITDIALOG: appendTimeUnit(timeCur1,buffer); //agrega las unidades al final de la cadena (nS,uS,mS) SetDlgItemText(hDlg,IDC_CUR1TIME,buffer); appendTimeUnit(timeCur2,buffer); //agrega las unidades al final de la cadena (nS,uS,mS) SetDlgItemText(hDlg,IDC_CUR2TIME,buffer); appendTimeUnit(timeDiff,buffer); //agrega las unidades al final de la cadena (nS,uS,mS) SetDlgItemText(hDlg,IDC_TIMEDIFF,buffer); break; case WM_CLOSE: DestroyWindow(hDlg); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: GetDlgItemText(hDlg,IDC_EDITLPT1,buffer,10); portLPT1 = atoi(buffer); DestroyWindow(hDlg); return TRUE; break; } break; } return FALSE; } void DrawGrid(HDC hDC, int Xmargin, int Vmargin) { double act_time= 0.000, times[11], voltajes[11] ; /* Creo un nuevo pincel (newPen) gris para dibujar la grilla, y guardo el anterior en oldPen */ unsigned int HPEN RECT int unsigned char char int int int char double cnt2=0, sample=0,time_division=0,last_sample=0; newPen,oldPen,otherPen; rect; x=0,index=0,k=0; cnt=0; time_buf[10],time[10],volts[10],strVmedio[20]; point=0; sign=0; digits=4; time_buffer[10]; sum=0,stddev=0;

newPen = CreatePen(PS_SOLID,1,RGB(120,120,120)); oldPen = (HPEN)SelectObject(hDC,newPen); otherPen = CreatePen(PS_SOLID,1,RGB(160,160,160)); /* Obtengo las medidas de la ventana */ GetClientRect(hWndMain,&rect); largo = rect.right - rect.left - 2*Xmargin; ancho = rect.bottom - rect.top - 2*Vmargin; middleX = largo/2; middleY = ancho/2; deltaX = largo/10; deltaY = ancho/10;

Pgina 70 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


offsetY = ancho*vertScale/255; SetBkMode(hDC, TRANSPARENT); SetTextColor(hDC,RGB(150,150,150)); for(x=0;x<11;x++) { if((x == 5)|(x == 0)|(x == 10)) newPen = (HPEN)SelectObject(hDC,otherPen); if((x == 6)|(x == 1)|(x == 11)) otherPen = (HPEN)SelectObject(hDC,newPen);

Robert Prez

MoveToEx(hDC,x*deltaX+Xmargin,Vmargin,NULL); // 11 lineas verticales LineTo(hDC,x*deltaX+Xmargin,rect.bottom-Vmargin); MoveToEx(hDC,Xmargin,deltaY*x+Vmargin,NULL); // 11 lineas horizontales LineTo(hDC,rect.right-Xmargin,deltaY*x+Vmargin); // guardo las posiciones de las lineas horizontales y verticales, son // 11 cada una horLines[x] = x*deltaX+Xmargin; vertLines[x] = x*deltaY+Vmargin; times[x] = 1000*(m+(horLines[x]-Xmargin)/horScale)/F_SAMPLE; } for(x=0;x<5;x++) voltajes[x] = Vdivision*(5-x); for(x=0;x<5;x++) voltajes[10-x] = -1*voltajes[x]; SelectObject(hDC,oldPen); DeleteObject(newPen); DeleteObject(oldPen); DeleteObject(otherPen); // dibujo la seal en verde newPen = CreatePen(PS_SOLID,1,RGB(0,255,64)); oldPen = (HPEN)SelectObject(hDC,newPen); /* Escalado vertical y paso a un entero de 16 bits porque no me da con uno de 8bits. */ for(x=0;x<NUM_SAMPLES;x++) { intdato[x] = (-Invertir*127 + Invertir*dato[x])*offsetY + middleY + Vmargin + yOffset - 12; /* Esta parte del codigo elimina los saltos muy grandes en la seal que son un defecto del equipo. */ if ((dato[x] > (dato[x-1]+50)) | (dato[x] < (dato[x-1]-50)) ) intdato[x] = intdato[x-1]; } intdato[0] = intdato[1]; //filtro int tempsum,i;

if(Ifiltro != 0) { for(x=0;x<NUM_SAMPLES;x++)

Pgina 71 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


{ tempsum = 0; for(i=0;i<Ifiltro;i++) tempsum += intdato[x+i]; intdato[x] = tempsum/Ifiltro; } } MoveToEx(hDC,Xmargin,intdato[m],NULL); for(x=m;x<(NUM_SAMPLES-Ifiltro); x++) { temp = (double)(x-m)*horScale; if(temp > largo) break; } for(i=0;i<11;i++) { if((m==0)&(i==0)) { TextOut(hDC,horLines[i] - 6*digits ,rect.bottom20,"0.000nS",strlen("0.000nS")); } else { appendTimeUnit(times[i],time); TextOut(hDC,horLines[i] - 6*digits ,rect.bottom20,time,strlen(time)); } if((i==5)) TextOut(hDC,4,(rect.bottom/2) - 7," 0.00mV",strlen(" else { appendVoltUnit(voltajes[i],volts); TextOut(hDC,5,vertLines[i] - 7,volts,strlen(volts)); } } SelectObject(hDC,oldPen); DeleteObject(newPen); DeleteObject(oldPen); return; } void SaveToFile() { FILE* pfile;

Robert Prez

// corta al final de la pantalla en forma horizontal

LineTo(hDC,Xmargin+temp,intdato[x]);

0.00mV"));

if((pfile = fopen("C:\salida.dat","wb")) == NULL) { MessageBox(NULL,"No se puede crear el archivo","Error...",NULL); return; } fwrite(&atenuacion,sizeof(int),1,pfile); fwrite(&highspeed,sizeof(int),1,pfile); fwrite(&dato,NUM_SAMPLES*sizeof(char),1,pfile); fclose(pfile);

Pgina 72 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


return; } void LoadFile() { unsigned int i=0; FILE* pfile;

Robert Prez

if((pfile = fopen("C:\salida.dat","rb")) == NULL) { MessageBox(NULL,"No se puede crear el archivo","Error...",NULL); return; } fread(&atenuacion,sizeof(int),1,pfile); fread(&highspeed,sizeof(int),1,pfile); fread(&dato,NUM_SAMPLES*sizeof(char),1,pfile); if(atenuacion != 0) Vdivision = 10*0.163; else Vdivision = 0.163; if(highspeed == TRUE) F_SAMPLE = 40; else F_SAMPLE = (double)(2.50); fclose(pfile); return; } void double2str(double valor,char* cadena) { int digits = 5; int point=0; int sign=0; char temp[20]; char i,k=0; strcpy(cadena,"Vmed = "); strcpy(temp,_ecvt(valor,digits,&point,&sign)); i = strlen(cadena)-1; while(point-- > 0) { cadena[i++] = temp[k++]; } cadena[i++] = '.';

while((digits-point) > 0) { cadena[i++] = temp[k++]; digits--; } cadena[i] = '\0'; } void appendTimeUnit(double time, char *time_buf) { int point=0; int sign=0; int digits=4; int index=0; char time_buffer[10]; char time_temp[10];

Pgina 73 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


int k=0,mult=1;

Robert Prez

if(time < 0) mult = -1; // para manejar el valor absoluto... if(mult*time > 1000) { time /= 1000; strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"uS"); } else if(mult*time > 1000000) { time /=1000000; strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"mS"); } else { strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"nS"); } k=0; while(point>0) { time_buf[k] = time_temp[k]; k++; point--; } time_buf[k++] = '.'; index = digits - point; index++; while(index-->0) { time_buf[k] = time_temp[k-1]; k++; } time_buf[k] = '\0'; if(time < 0) strcpy(time_temp,"-"); else strcpy(time_temp," "); strcat(time_temp,time_buf); strcpy(time_buf,time_temp); } void appendVoltUnit(double time, char { int point=0; int sign=0; int digits=3; int index=0; char time_buffer[10]; char time_temp[10]; int k=0,mult=1; *time_buf)

if(time < 0) mult = -1; // para manejar el valor absoluto...

Pgina 74 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


if(mult*time > 1) { strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"0V"); } else { time *=1000; strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"0mV"); } k=0; while(point>0) { time_buf[k] = time_temp[k]; k++; point--; } time_buf[k++] = '.'; index = digits - point; index++; while(index-->0) { time_buf[k] = time_temp[k-1]; k++; } time_buf[k] = '\0'; if(time < 0) strcpy(time_temp,"-"); else strcpy(time_temp," "); strcat(time_temp,time_buf); strcpy(time_buf,time_temp); } void appendHertzUnit(double time, char { int int int int char char int point=0; sign=0; digits=6; index=0; time_buffer[20]; time_temp[20]; k=0, mult=1; *time_buf)

Robert Prez

if(time < 0) mult = -1; time /=1000; time = mult/time;

if(time <= 1) { time *= 1000;

Pgina 75 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"KHz"); } else if(time > 1) { strcpy(time_temp,_ecvt(time,digits,&point,&sign)); strcat(time_temp,"MegHz"); } k=0; while(point>0) { time_buf[k] = time_temp[k]; k++; point--; } time_buf[k++] = '.'; index = digits + 5 - point; index++; while(index-->0) { time_buf[k] = time_temp[k-1]; k++; } time_buf[k] = '\0'; if(time < 0) strcpy(time_temp,"-"); else strcpy(time_temp," "); strcat(time_temp,time_buf); strcpy(time_buf,time_temp); } void DrawCursors(HDC hdc, int Yfinal) { HPEN newPen, oldPen; newPen = CreatePen(PS_SOLID,1,RGB(200,200,200)); oldPen = (HPEN)SelectObject(hdc,newPen); MoveToEx(hdc,Xcur1,40,NULL); LineTo(hdc,Xcur1,Yfinal); MoveToEx(hdc,Xcur2,40,NULL); LineTo(hdc,Xcur2,Yfinal); SelectObject(hdc,oldPen); DeleteObject(newPen); DeleteObject(oldPen); }

Robert Prez

Pgina 76 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC Apendice C Listado del Software del Microcontrolador PIC
/*

Robert Prez

Firmware para DSO View (Osciloscopio de Almacenamiento Digital para PC por puerto paralelo), contiene rutinas de control del Hardware Autor: Robert Perez (proyectoits@adinet.com.uy) Fecha: 08/01/2005 Instituto Tecnolgico Superior de Electrnica y Electrotecnia (I.T.S) MONTEVIDEO-URUGUAY */ #pragma char ADCON1 @ 0x9F #pragma config = 0x3F62 bit bit bit bit bit bit bit bit bit bit bit bit bit hsclk_en nOE_WE start_conv gain_ctrl read_clk ls_encode powerdown datastb nAck nInit n2PC wait tc2cnt @ @ @ @ @ @ @ @ PORTB.0; PORTB.1; PORTB.2; PORTB.3; PORTB.4; PORTB.5; PORTB.6; PORTB.7; /* /* /* /* /* /* /* /* /* /* /* /* /* OUTPUT */ OUTPUT Lectura/escritura de la SRAM */ INPUT Inicia la conversion */ INPUT Control de ganancia ACTUALMENTE NO SE USA*/ OUTPUT genera el clk de lectura.*/ OUTPUT low speed encode. */ OUTPUT POWERDOWN para el ADC */ INPUT Seal del puerto paralelo Auto Line Feed... */ OUTPUT ACTUALMENTE NO SE USA, ESTA CONECTADO AL CONTROL DE GANANCIA*/ INPUT */ OUTPUT Habilita el 74245 para la PC*/ OUTPUT Seal del puerto paralelo, nBusy... */ INPUT */

@ PORTA.0; @ PORTA.1; @ PORTA.2; @ PORTA.3; @ PORTA.4;

void ResetCnt(void) { /* ls_encode = 1; read_clk = 0;

// deshabilito el encode, es solo para incrementar el contador

while(tc2cnt == 0) read_clk = !read_clk; while(tc2cnt == 1) read_clk = !read_clk; read_clk = 0; ls_encode = 0; */ unsigned char cnt; #asm BCF BCF BSF BCF 0x03,RP0 0x03,RP1 0x06,ls_encode 0x06,read_clk

m001

BTFSC 0x05,tc2cnt

Pgina 77 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


GOTO m002

Robert Prez

m002 BTFSS 0x05,tc2cnt GOTO m003 MOVLW .16 XORWF PORTB,1 GOTO m002 m003 BCF BCF #endasm 0x06,ls_encode 0x06,read_clk // me salteo las primeras 10 muestras

MOVLW .16 XORWF PORTB,1 GOTO m001

cnt = 10;

} void Delay1mS() { unsigned char cnt,cnt2=2; while(cnt2 != 0) { cnt = 0xFF; while(cnt != 0) { nop(); nop(); nop(); cnt--; } cnt2--; } } void Adquirir40MSPS() { ResetCnt(); nOE_WE = 1; /* */ #asm loop: hsclk_en = 1; while(tc2cnt == 0) ;

while(cnt != 0) { read_clk = !read_clk; read_clk = !read_clk; cnt--; }

// aprox. 10 ciclos * 255 * 0.4uS = 1020uS

// write... // here we gooooo !!!

BTFSS PORTA,4 GOTO loop #endasm } hsclk_en = 0;

; tc2cnt

// sin reloj de 40

Pgina 78 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

void Adquirir2_5MSPS() { unsigned char cnt,cnt2; ResetCnt(); nOE_WE = 1; hsclk_en = 0; cnt = 0xFF; cnt2 = 2; read_clk=0; #asm MOVLW 0b0001.0000 next: XORWF PORTB,F XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F // 128*2 veces para completar 128 ciclos de reloj // dejo todos los pines del PORTB iguales menos RB5 que lo hago subir y bajar. // read_clk = RB5 // write... // sin reloj de 40 //256*(128/2)*2=32768

Pgina 79 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC

Robert Prez

XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF

PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F

Pgina 80 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


XORWF PORTB,F XORWF PORTB,F XORWF PORTB,F XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF XORWF PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F PORTB,F

Robert Prez

DECFSZ cnt2,F GOTO next DECFSZ cnt,F GOTO next #endasm } /* Transmite un byte al LPT de la PC con el protocolo EPP void epptx() { /* wait = 0; while(datastb == 1) ; wait = 1; while(datastb == 0) ; */ #asm BCF NOP m001: PORTA,wait */

BTFSC PORTB,datastb GOTO m001

Pgina 81 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


BSF NOP PORTA,wait

Robert Prez

m002:

BTFSS PORTB,datastb GOTO m002 #endasm } void Inicializar() { /* Setear los Puertos, timers, interrupciones, etc..... */ ADCON1 = 0x06; /* */ TRISA = 0b1111.0010; TRISB = 0b1000.1100; powerdown = 1; ls_encode = 0; n2PC = 1; read_clk = 0; GIE = 0; hsclk_en = 0; } void EnviarMuestras() { ResetCnt(); nOE_WE = 0; // lectura /* El ADC arranca deshabilitado (output en HI-Z). */ /* Reloj del ADC arranca en 0. */ /* No se transmite nada a la PC */ /* deshabilitar interrupciones */ /* todava nada de clocks...*/ PORTA es todo digital I/O, con otros valores podemos definir algunas entradas analogicas para usar el ADC interno

} void main() { unsigned char cnt,cnt2; Inicializar(); while(1) { if(start_conv == 0) goto loop; loop2: if(start_conv == 1) goto loop2; loop3: // Setear los registros TRIS y deshabilitar // interrupciones.

while(tc2cnt == 0) { read_clk = !read_clk; read_clk = !read_clk; epptx(); }

loop:

Pgina 82 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC


if(start_conv == 0) goto loop3; powerdown = 0; // Habilitar el ADC

Robert Prez

if(nInit == 1) Adquirir40MSPS(); else Adquirir2_5MSPS(); powerdown = 1; // // Mandar el ADC al modo de bajo consumo, tambien // pone sus salidas en Hi-Z

mandar unos ls_encode antes de seguir para asegurar el powerdown. read_clk = 1; cnt = 40; while(cnt != 0) { ls_encode = !ls_encode; cnt--; } ls_encode = 0; read_clk = 0; n2PC = 0; EnviarMuestras(); n2PC = 1; } // pasa todo a la PC. // no sale nada hacia la PC, estoy almacenando...

return;

Pgina 83 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti

Proyecto Final DSO para PC Referencias 1) https://www.cs.tcd.ie/courses/baict/bac/jf/labs/scope/oscilloscope.html Diagramas en bloques y explicacin detallada de Osciloscopios.

Robert Prez

2) Understanding Flash ADCs 3) Understanding Pipelined ADCs 4) Understanding SAR ADCs 5) Understanding Sigma-Delta ADCs 6) Understanding Integrating ADCs Todos los links estn en la pagina principal http://www.maxim-ic.com/tarticle/article.cfm 7) SIGMA-DELTA (SD) MEASUREMENT ADCS 8) An Introduction to the Sampling Theorem National Semiconductor Application Note 236 9) Introduccin a los sistemas de comunicaciones F.G. Stremler 10) The Scientist and Engineer's Guide to Digital Signal Processing (Moving Average Filters)

Pgina 84 I.T.S Montevideo-Uruguay

Prof.: Pablo Fosatti