Pic16f84a Mando a Distancia Para Pc

March 22, 2018 | Author: chuchis | Category: Infrared, Modulation, Remote Control, Light, Computer Program


Comments



Description

UNIVERSIDAD TECNOLOGICA NACIONALFACULTAD REGIONAL SAN NICOLAS INGENIERIA EN ELECTRONICA PROBLEMA DE INGENIERÍA TECNICAS DIGITALES III MANDO A DISTANCIA PARA PC Integrantes: - Buxman Jorge A. - De Nicoló Lisandro. - Gallina Luciano . Docentes: - Profesor: Poblete Felipe - Auxiliar: González Mariano AÑO 2007 Técnicas Digitales III – Problema de ingeniería INDICE OBJETIVOS DEL TRABAJO 3 MATERIAS INTEGRADAS......................................................................................................... 3 POSIBLES APLICACIONES........................................................................................................ 3 PROFESORES ENTREVISTADOS.............................................................................................. 3 BIBLIOGRAFÍA ........................................................................................................................... 3 DESARROLLO 4 INTRODUCCIÓN......................................................................................................................... 4 TEORIA DE FUNCIONAMIENTO .............................................................................................. 4 EL ENLACE INFRARROJO............................................................................................................4 RECEPCION DE INFRARROJO ....................................................................................................6 PROTOCOLO DE PHILIPS RC-05..................................................................................................9 EL URC SBC-RU-240/38 DE PHILIPS..........................................................................................12 ESTANDAR RS- 232 ....................................................................................................................13 DIAGRAMAS Y CIRCUITOS..................................................................................................... 15 PRIMER INTENTO .......................................................................................................................15 RECEPTOR ...................................................................................................................................16 EL CODIGO FUENTE DEL PIC16F84A.....................................................................................19 ESTRUCTURA DE UN PROGRAMA WINDOWS GUI............................................................. 20 Parámetros de entrada de "WinMain"..............................................................................................22 Función WinMain típica .................................................................................................................23 Declaración.....................................................................................................................................24 Inicialización ..................................................................................................................................24 Bucle de mensajes...........................................................................................................................24 El procedimiento de ventana ......................................................................................................... 25 Sintaxis...........................................................................................................................................25 Prototipo de procedimiento de ventana............................................................................................26 Implementación del procedimiento de ventana simple.....................................................................26 RESULTADOS DE LAS PRUEBAS ........................................................................................... 27 CONCLUSIONES 29 ANEXOS 33 Anexo A: LISTADO DE PROGRAMAS...................................................................................... 33 Código fuente para el PIC16F84A: .................................................................................................33 Código fuente para la PC: ...............................................................................................................41 Anexo B: Sitios en la WEB........................................................................................................... 57 Anexo C: GL3276A-datasheets (no incluído en este documento) .................................................. 57 Anexo D: MAX232-datasheets (no incluído en este documento)................................................... 57 2 Técnicas Digitales III – Problema de ingeniería OBJETIVOS DEL TRABAJO Lograr el manejo o accionamiento de los comandos básicos de programas multimedia en plena reproducción mediante un mando a distancia enlazado con la PC a través de un enlace de señal infrarroja. La implementación requiere de la utilización de un control remoto comercial del tipo universal o cualquier otro control remoto de cualquier equipo en desuso (Equipo de audio o Tv, etc.). MATERIAS INTEGRADAS  Informática I y II.  Técnicas digitales I, II, y III.  Física II y III. POSIBLES APLICACIONES  Implementación de control sobre archivos multimedia en plena reproducción logrando una mayor comodidad, ya sean de audio o video. PROFESORES ENTREVISTADOS  Ramiro Vota (Interfaz RS-232 en Windows XP).  Mariano Gonzales (Ídem). BIBLIOGRAFÍA  Turbo C/C++ Manual de referencia-Herbert Schildt (serie McGary-Hill de Informática).  Programación Elemental en C++ Manual de Referencia Abreviado revisión 1.2 (Universidad de Málaga Dpto. de Ing. Informática)  Programación en C Metodología, algoritmos y estructura de datos.-Luis Joyanes Aguilar / Ignacio Zahonero Martínez.  Protocolo Philips RC-5 para control remoto descripción por Eduardo J. Carletti (Comunicacion_protocolorc5.htm).  RS-232 Ingeniería en microcontroladores Ing. Eric López Pérez.  Hojas de datos de los sistemas involucrados (apéndices).  Organización de las computadoras-un enfoque estructurado-Andrew S. Tanembaum.  Diversos sitios web (ver al final de este informe). 3 Técnicas Digitales III – Problema de ingeniería DESARROLLO INTRODUCCIÓN Probablemente los botones más frecuentemente pulsados en cualquier casa son los del mando a distancia de la televisión, y es que actualmente el control remoto de aparatos electrónicos es algo habitual. Resulta evidente que los mandos por infrarrojos han sido una revolución. Por otra parte, es indudable que la presencia de ordenadores personales en hogares y oficinas, que duplican su capacidad a velocidades vertiginosas, facilita la extensa tarea en las diversas actividades que realiza el ser humano. La tendencia actual es optimizar el ordenador al máximo. Por todo ello, ¿por qué no aplicar las comodidades del control remoto al ordenador? . Se pretende recibir la información enviada desde un emisor de infrarrojos, que será un mando a distancia convencional, procesar esa información y enviarla vía RS-232 a un ordenador personal. La información extraída del mando es una serie de pulsos que, en principio, no sirve de nada si no se procesa adecuadamente. Para llevar a cabo este proceso se utiliza un PIC modelo 16F84A de Microchip, que es un pequeño microcontrolador de 18 pines. Dicho PIC dispone de un entorno de desarrollo para la confección del programa que ejecutará y se encargará de procesar convenientemente la trama recibida del IR, obteniéndose así otra trama de ceros y unos que ahora sí es comprensible por cualquier sistema (palabra digital de 6 bits). Finalmente, como esta información se desea transmitir vía serie siguiendo el estándar RS-232, se utilizará un integrado comercial (MAX232) que adecua los niveles de la trama extraída por el PIC (trama TTL) a los requeridos por la norma. Importante señalar que el PIC ya se ha encargado de añadir los bits de STOP y START a cada una de las palabras digitales, no utilizándose control de flujo hardware. Se emplea como emisor un mando a distancia universal al que se le ha programado el código 033 correspondiente a los mandos PHILIPS (RC-05). TEORIA DE FUNCIONAMIENTO EL ENLACE INFRARROJO Un enlace infrarrojo consiste en una comunicación vía señalización lumínica. La luz infrarroja no es más que una onda electromagnética como las de radio (claro es, que se trata de una frecuencia muy diferente) y como las del resto de las ondas que constituyen el espectro de luz visible (desde el infrarrojo hasta el ultravioleta). El nombre de luz infrarroja, que significa por debajo del rojo, proviene de la primera vez que fue observada al dividir la luz solar en diferentes colores por medio de un prisma que separaba la luz en su espectro de manera que a ambos extremos aparecen visibles, las componentes del rojo al violeta (en ambos extremos). 4 Técnicas Digitales III – Problema de ingeniería Aunque estas experiencias habían sido realizadas anteriormente por Isaac Newton, William Herschel observó en el año 1800 que se recibía radiación debajo del rojo al situar medidores de calor en las diferentes zonas no visiblemente irradiadas por el espectro. Imagen de un perro tomada con radiación infrarroja media («térmica») y coloreada: Su longitud de onda es del orden de los 700 nano-metros: 5 La demodulación se realiza analógicamente con un sencillo filtro paso banda (eliminar todas las frecuencias que no sean próximas a la frecuencia de emisión) junto con un rectificador/integrador. dependiendo del fabricante y modelo del mando a distancia. No tenemos que perder de vista que todo lo que se haga para emitir la señal. La señal emitida por un mando está modulada a una frecuencia entre 32 y 40 KHz. luego durante la recepción se tendrá que deshacer. normalmente negro. luego se tendrá que recibir. si esta señal se modula con una portadora luego se tendrá que eliminar (filtrar) esa portadora. Los diseñadores de mandos a distancia tuvieron que añadir una característica diferenciadora a la luz emitida desde un mando a distancia para hacerla distinguible del resto de fuentes luminosas.Técnicas Digitales III – Problema de ingeniería Y su frecuencia: Todos estos parámetros son característicos de cualquier tipo de onda: RECEPCION DE INFRARROJO Todos los dispositivos semiconductores son sensibles a la luz (a todo tipo de luz). independientemente de la fuente que la genere. 6 . Un sensor de infrarrojos está construido básicamente por una unión semiconductora recubierta por un cristal que sólo deja pasar la luz infrarroja (photodiodo). de hecho este es el principal factor que determina el encapsulado de los chips: un plástico completamente opaco. Si se emite luz infrarroja. Un sensor de infrarrojos construido de esa forma será capaz de detectar la presencia de cualquier luz infrarroja. Luz infrarroja modulada a una frecuencia de 36 KHz (para nuestro caso de RC-05). es el medio de comunicación entre el emisor (mando a distancia) y el receptor (PIC16F84A). esto es. Margen de variación de f0 reducido.  Salida a colector abierto con resistencia de pull-up. los bits que identifican la tecla del mando a distancia que se ha pulsado. ocupando un cierto ancho de banda alrededor de la frecuencia de la onda portadora (f0). Capacitores externos de capacidades bajas.Técnicas Digitales III – Problema de ingeniería Una onda modulada es una forma de onda obtenida mediante una operación matemática implementada a través de circuitos electrónicos y en la que intervienen la señal que se quiere transmitir (moduladora) y al onda portadora. Es el GL3276A el circuito mencionado y brevemente podemos decir que consta de los siguientes bloques funcionales: Características del integrado:  Menor numero de errores asociados a la alta frecuencia emanada por luces fluorescentes (impulsos luminiscentes) mediante circuito trampa interna.  Pocos elementos externos necesarios. Ahora queda por determinar cómo se transmite la información. Para la realización de la tarea de recibir el dato empleamos un circuito integrado comercial estándar cuyas especificaciones se pueden consultar en el Anexo A (hoja de datos). 7 . Resistencias de pull-ups y filtros internas. Esta onda portadora es de una frecuencia mucho más alta que la de la señal moduladora (la señal que contiene la información a transmitir).  Frecuencia de portadora (demodulación) preselecionable mediante resistencia instalada en el pin f0 en un rango de 30 a 80 KHz. pero esto se detallara en el apartado del protocolo RC-05. Al modular una señal desplazamos su contenido espectral en frecuencia. Esto nos permite multiplexar en frecuencia varias señales simplemente utilizando diferentes ondas portadoras y conseguir así un uso más eficiente del espectro de frecuencias. Como se muestra en su diagrama de bloques consta en una primera instancia de un amplificador de entada. un filtro pasa banda.Técnicas Digitales III – Problema de ingeniería Este es un circuito integrado analógico diseñado especialmente para este tipo de aplicaciones. seguido de u limitador. un circuito detector y un acondicionador de forma de onda que va directo a la etapa de salida a colector abierto. Para 36 KHz seria al rededor de 156 KΩ. 8 . tanto es así que el fabricante nos aporta el circuito de aplicación típico que obviamente se consigue en cualquier tienda de electrónica completo dentro de una caja de chapa que hace a las veces de jaula de Faraday para disminuir el efecto de interferencias por ondas electromagnéticas. El valor de R(f0) lo encontramos mediante las curvas aportadas por el fabricante del circuito integrado. Como veremos a este se acopla directamente el photodiodo receptor y un conjunto mínimo de componentes de seteo y demás. 9 . En este ejemplo se transmite la dirección $05 y el comando $35. Tiempo de bit constante de 1.. Protocolo La imagen muestra un típico tren de pulsos en un mensaje RC-05. En esta codificación. La mitad del bit es un tren de pulsos de la portadora de 36 KHz. Descubramos un poco que es y como esta hecho el protocolo de Philips.) Modulación El protocolo está basado en una modulación Manchester de doble fase sobre una portadora de 36 KHz. de 1. el RC-06.778 ms (64 ciclos de 36 KHz. que deben ser dos "1" lógicos. Además. y por tanto sólo es necesario una línea (de datos) para recibirla. El cero lógico es representado por un tren de pulsos en la primera mitad (primer nible) del tiempo que corresponde al bit. que tiene más capacidades. dentro de este protocolo hay comandos predefinidos para distintos artefactos.Técnicas Digitales III – Problema de ingeniería PROTOCOLO DE PHILIPS RC-05 Es evidente. también llamada código Manchester) Frecuencia de portadora de 36 KHz. lo que reduce el consumo de energía. El uno lógico es representado por un tren de pulsos en la segunda mitad de este tiempo. que la información se transmite en serie. Philips ha comenzado a utilizar un nuevo protocolo. debido a la amplia disponibilidad de controles remotos baratos que se basan en él. un bit detrás de otro. Nótese que transcurre medio tiempo de bit hasta que el receptor se entera de que ha comenzado el mensaje. y en la otra mitad la señal está plana. todos los bits tienen la misma longitud. posiblemente. una característica que aporta una mayor compatibilidad al utilizarlo con muchos equipos hogareños.778 ms. Los dos primeros bits son los de inicio (start). dada la forma de modular la señal. es de 1/3 o 1/4. El código RC-05 de Philips es. esto es. Características Dirección de 5 bit y comando de 6 bit (7 bits de comando para RC-05X) Codificación de doble fase o bi-fase (Bi-phase. el protocolo más utilizado por los experimentadores. La relación entre pulso y pausa en la portadora de 36 KHz. que sumados dan una duración total del mensaje de 25 ms. también con su bit más significativo en primer lugar. enfrente del control remoto. De esta manera el receptor puede distinguir entre una tecla que permanece presionada (mientras lo esté. obviamente. no es necesario pasarle a la PC toda la cadena. Un mensaje. El bit de conmutación mantendrá el mismo nivel lógico durante la repetición de un mensaje. Ya que hacemos esto. para quien es el mensaje). lo que permitiría tener dos videocaseteras juntas sin tener problemas para comandarlas por separado. basta con que le pasemos el dato de comando para que la PC ejecute una tarea respectiva. Mientras se mantenga presionada la tecla. 10 . entonces. marcado como “T” en el dibujo. En la cadena que le pasamos a la PC haremos que. Esto asegura compatibilidad entre artefactos de un mismo tipo y evita que la tecla que cambia de canal en un televisor produzca al mismo tiempo algún efecto en una videocasetera que también esté allí. Comandos predefinidos Philips ha creado una lista de comandos estandarizados. consiste de un total de 14 bits. el bit 6 (cadena 0~7 bits) de dicha cadena sea “1” lógico para informar no repetición de la tecla y “0” lógico para representar repetición de la tecla y así la PC pueda hacer alguna discriminación de ser necesario. ya que nos sobran dos bis para completar el byte (6 bits de comando). Una característica interesante es que la mayoría de los artefactos están representados dos veces.Técnicas Digitales III – Problema de ingeniería El protocolo RC-05 extendido (RC-05x) tiene un solo bit de inicio y este es en realidad el que utilizaremos pues es el que mas abunda aunque lo sigamos llamando RC-05. es el bit de conmutación (toggle). poniendo en primer lugar el bit más significativo de la dirección. A esta dirección le sigue el comando de 6 bits. Para nuestra aplicación lo que haremos es que el PIC16f84A decodifique el mensaje enviado por el control remoto y envíe los datos a la PC mediante el puerto serie. el mensaje se repite cada 114 ms. Entonces el dato correspondiente al dispositivo que “nos habla” se lo queda el PIC para lograr el reconocimiento del mismo y así impedir leer mensajes de otros controles remotos circundantes. El bit que sigue al bit “T” es el primero de la dirección del dispositivo receptor de infrarrojos (identificación de quien nos habla y por esto. Este bit es invertido cada vez que se libera una tecla en el control remoto y se la presiona de nuevo o se presiona otra diferente. A veces puede parecer que un mensaje es más corto debido a que la primera parte del bit de inicio S1 es inactiva. El tercer bit del protocolo RC-05. el comando que le corresponde se repite indefinidamente en la señal) y una misma tecla a la que se la presiona varias veces. 10 Sat2 $0A .22 SatA $36 .9 Cámara $09 .3 Video $03 .7 Experimental $07 .28 $1D .3 3 3 $04 .10 -/-- -/-- $0C .19 Brillo - $11 .12 Espera Espera $0B .27 $1C .23 Grabador2 $37 .17 Volumen - $0F .2 Teletexto $02 .Técnicas Digitales III – Problema de ingeniería La lista que sigue no es exhaustiva.4 4 4 $05 .6 6 6 $07 .16 Volumen + $0E .11 $0C .31 Teléfono 11 .2 2 2 $03 .20 Reproductor CD $34 .26 CDR $1B .25 $1A .1 1 1 $02 .53 Reproducir $16 .16 Preamplificador $13 .13 Camcorder $10 .55 Grabar $18 .54 Detener $17 .32 Programa + Programa + $12 .4 LV1 $04 .13 Silenciar $0D .12 CDV $0D .14 $11 .8 8 8 $09 .0 TV1 $00 .5 VCR1 $05 .50 Retroceso rápido $14 .9 9 9 $0A .52 Retroceso rápido $15 .7 7 7 $08 . Dirección RC-5 Dispositivo Comando RC-5 Comando TV Comando VCR $00 .30 Iluminación $1F .33 Programa - Programa - $13 .17 Sintonizador $20 .24 $19 .8 Sat1 $08 .1 TV2 $01 .29 Iluminación $1E .5 5 5 $06 .19 Preamplificador $32 .15 $12 .6 VCR2 $06 .21 Teléfono $35 .18 Grabador1 $21 .18 Brillo + $10 .0 0 0 $01 . En el código fuente del programa de la PC haremos la siguiente tabla de asignaciones por defecto (el usuario puede modificar dicha tabla cuando abre el programa).Técnicas Digitales III – Problema de ingeniería EL URC SBC-RU-240/38 DE PHILIPS Utilizamos este control remoto universal de Philips y lo configuramos para trabaja con una VRC pues nos habilita la mayor cantidad de botones posible permitiéndonos. con el sistema operativo Windows. los podemos comprobar y lo hicimos mediante el ordenador. del programa) de reproducción de archivos multimedia y además nos permitirá interactuar en lo que a las principales funciones respecta. el mayor rango de interacción con la PC. en definitiva. Esta es una asignación por defecto para controlar el programa WINAMP (configuración de teclado por defecto. Conseguimos entonces las siguientes salidas del control hacia nuestro sistema receptor: Estos códigos de salida además de aparecer en la tabla antes mostrada. 12 . 232 La transmisión de datos en serie es una de las más comunes para aquellas aplicaciones en las que la velocidad no es demasiado importante. destello de led indicador de envío dos veces. Esta última UART es más reciente y mucho más potente (aunque solo sea por unos pequeños detalles) y cada vez está más extendida. 13 . teniendo en cuenta todos los tiempos necesarios para lograr una correcta comunicación y aliviando a la CPU de esta pesada tarea. en particular en las actuales placas base. El circuito que estudiado es el 8250 de National. en nuestro caso VCR. o no es posible conseguirla (por ejemplo. para nuestro caso es “033”.  Ingresar el código correspondiente al protocolo que el control remoto debe emitir. Ahora tenemos el mando a distancia configurado para emitir en protocolo RC-05X en modo VCR. aunque existen diferencias respecto al 16550.  Mantener presionado los botones “numero 1” y “numero 3”. fabricado también por Intel.Técnicas Digitales III – Problema de ingeniería Para la configuración del control remoto:  Elegir dispositivo (uno de cuatro los botones superiores). ESTANDAR RS. destello de led indicador de envío una vez. Para simplificar el proceso de enviar los bits uno por uno han surgido circuitos integrados que realizan la función. vía red telefónica). no se necesitan señales de reloj como se requieren para otras comunicaciones como es por ejemplo el I2C y por esto se considera al protocolo RS-232 asíncrono. se envía un bit a 0 ó bit de inicio. 14 . El ACE 8250 (Asynchronous Communication Element) integra en un solo chip una UART (Universal Asynchronous Receiver/Transmitter) y un BRG (Baud Rate Generator). aparecerá un bit (a veces un bit y medio ó dos bits) a 1. en nuestro caso es de 9600 baudios. Desde un punto de vista eléctrico la norma RS-232 establece:  Un “1” lógico es un voltaje comprendido entre –5v y –15ven el transmisor y entre -3v y 25v en el receptor. El MAX 232 necesita solamente una fuente de +5V para su operación. 6 ó 5): estos bits están espaciados con un intervalo temporal fijo y preciso.Técnicas Digitales III – Problema de ingeniería La línea que transmite los datos en serie está inicialmente en estado alto. Al comenzar la transferencia. Para adaptar las salidas del micro controlador al protocola se usa el MAX232 este chip se utiliza en aquellas aplicaciones donde no se dispone de fuentes dobles de +12 y –12 Volts. Para llevar a cabo ala comunicación el integrado consta de varios registros en los que se aloja bandera de estado. Lo de medio bit significa que la señal correspondiente en el tiempo a un bit dura la mitad. Soporta velocidades de hasta 625000 baudios con relojes de hasta 10 MHz. Al final. ligado a la velocidad de transmisión que se esté empleando. MAX233. El BRG incorporado divide la frecuencia base para conseguir las velocidades estándar de la RS-232. que son los bits de parada o bits de stop. LT1180A. haciendo que los relojes de ambas vayan a la par. Tras él irán los 8 bits de datos a transmitir (en ocasiones son 7. DS14C232. el registro de salida secuencial bit a bit e ídem para la entrada. Tras ellos podría venir o no un bit de paridad generado automáticamente por la UART.  Un “0” lógico es un voltaje comprendido entre +5v y +15v en el trasmisor y entre +3v y +25 v en el receptor. A la hora de transmitir los bits de datos unos tras otros. La presencia de bits de arranque y paro permite sincronizar la estación emisora con la receptora. internamente tiene un elevador de voltaje que convierte el voltaje de +5V al de doble polaridad de +12V y -12V. los datos a enviar. Cabe mencionar que existen una gran variedad de CI que cumplen con la norma RS-232 como lo son: MAX220. También están los registros buffer en los que se encuentran los datos recibidos. configuración de línea y modem. pudimos ver que la salida no podía acompañar a la entrada en tiempo y forma.Técnicas Digitales III – Problema de ingeniería Implementación cableada En la siguiente tabla se muestra las señales y configuración RS-232 más común según se implemente ficha DV9 o DV25: DIAGRAMAS Y CIRCUITOS PRIMER INTENTO Parea enriquecimiento de nuestra experiencia en un primer intento por querer logra la comunicación vía puerto serie de la PC e ignorantes totalmente de la existencia del MAX232 intentamos hacer la adaptación de niveles de voltaje a través de un circuito a base de amplificadores operacionales (LM324) puestos como comparadores. Así que intentamos resolver el problema bajando la velocidad de transmisión. así que para evitar mayores perdidas de tiempo nos inclinamos a la implementación de integrado. Como fuese. al atravesarlo un dato a transmitir. y problema resuelto. Conseguimos una leve mejora a 330 baudios. Al observar el comportamiento del amplificador operacional configurado de esa manera con un osciloscopio. 15 . así que debíamos intentar configurar el operacional como amplificador inverso de alguna manera. por supuesto nos demandaba una fuente bipolar. Además el otro método. ya teníamos el hardware armado. el dato transmitido era muy distante del que realmente queríamos enviar. Si bien conseguimos la comunicación. había que modificar el hardware y a su vez ya nos habíamos enterado de MAX232. Técnicas Digitales III – Problema de ingeniería RECEPTOR E sistema de recepción esta compuesto por un hardware de detección-decodificación. Para logra el cometido anterior. Este circuito integrado adapta la señal de 0V~5V que emite el PIC16F84A en su salida de dato a la PC a los respectivos niveles 10V~ (-10V) necesarios para representar el estado lógico en el protocolo RS-232. integrado por un microcontrolador PIC16F84A. el PIC16F84A. La transmisión a través del puerto serie se hace a 9600 baudios (baudio=bit/segundos) preseleccionados en la programación del PIC16F84A (ver código en PIC16F84A). hace el reconocimiento del dispositivo y envía el dato de comando mas el de repetición a la PC mediante el protocolo RS-232 a través del puerto serie de la misma. entre el PIC16F84A se instala un driver adaptador de nivel de señal MAX232. toma el dato serie (onda cuadrada) que el GL3276A proporciona como salida al recibir la señal del mando a distancia. Separa el código de mando del de dispositivo. Este es un esquemático del hardware de detección-decodificación: 16 . y en el código fuente del programa que correrá en el ordenador (ver código en PC). y la PC para la ejecución de una tarea determinada. En el circuito de detección-decodificación.  Led “Led V”: emite un destello por cada dato enviado a la PC.Técnicas Digitales III – Problema de ingeniería Es un circuito muy sencillo:  Led “PWR”: se enciende al alimentar el circuito. y viceversa (enciende por un segundo una vez “Led V”).” durante cierto tiempo el led enciende por un segundo dos veces para indicar salida de dato paralelo y una ves para indicar salida de datos serie. De presionar el pulsador “Borrar disp. el receptor consta de un pulsador “Borrar disp. etc. permanece encendido durante un segundo. A partir de entonces el receptor solo reconocerá mensajes provenientes de ese mando a distancia y con ese código de dispositivo.  Led “Led R”: al encender el receptor. Si se quiere cambiar el código de dispositivo de reconocimiento por cualquier razón. aproximadamente (simultáneamente con “Led R”) de no poder concretar la comunicación. se debe quita el buffer MAX232 lo cual se puede llevar a cabo interponiendo un conector entre este y la electrónica principal. Esta comunicación envía el dato en dos partes como puede verse en el código fuente del PIC16F84A.  Pulsador “Borrar disp. Nota: para que el hardware pueda comunicarse con el ordenador mediante el puerto paralelo. se encenderá entonces el “Led R”. si estaba transmitiendo en serie lo hará en paralelo entonces (enciende por un segundo dos veces “Led V”). cambia su modo de transmisión de datos a la PC. En una primera instancia se envían los cuatro bits más significativos. Si el pulsador se presiona durante un tiempo prolongado el receptor. además de desvincular el mendo a distancia. En este conector también se debe conectar el adaptador de conexiones para efectuar la comunicación vía puerto paralelo.” Que al presionarlo durante un tiempo reducido deshace la vinculación encendiendo nuevamente “Led R” y poniendo al receptor a la espera del nuevo código de reconocimiento.…) entonces esta situación se ve indicada por la permanencia de este led encendido.”: pensionándolo durante un breve lapso de tiempo se deshace la vinculación del receptor y el código de dispositivo (código de reconocimiento). La situación se revierte al enviarle algún mensaje desde el control remoto (presionando cualquier tecla del control). este no esta vinculado a ningún dispositivo (TV. se espera un determinado tiempo 17 . pines 15. El registro PORT 889. es de solo lectura. 4 y 3 teniendo en cuenta que el bit 7 funciona en modo invertido. puerto de datos. EL controlador de la comunicación consta de tres registros de 8 bit cada uno (un byte). Adaptación: Para enviar el dato a la PC utilizamos del puerto de estado los pines 10. Esto es así para aprovechar mejor y de manera más simple las características del puerto según nuestras necesidades. inclusive. también inclusive. 12. por este registro se envían los datos al exterior de la PC. podremos enviar o recibir señales eléctricas. puerto de estado. (dirección en memoria 888). es de solo escritura. De los 8 bits de este registro solo se utilizan los cuatro de menor peso o sea el 0. de este registro solo se utilizan los cinco bits de más peso. Puerto paralelo: El puerto paralelo se implementa en hardware a través de una ficha DV25 (25 pines) macho (hembra en la PC) de los cuales desde el pin 18. y 3 están invertidos.Técnicas Digitales III – Problema de ingeniería una confirmación por parte de la PC y se procede al envío del pedazo restante para completar el byte. que son el bit 7. El registro PORT 890. 1. por aquí se enviaremos señales eléctricas al ordenador. 2 y 3. es decir. E4 y E3 respectivamente). 10 y 11. 6. Pines del 2 al 9. La conexión cableada deberá hacerse como se indica a continuación: 18 . 13. E5. pin 2 (D0). hasta el pin 25. 13. es de lectura/escritura. 5. Para la confirmación la esperamos por el puerto de datos. con un pequeño detalle. y 15 (E6. 12. los bits 0. sirven de masa. El registro PORT 888. 1. según nuestras necesidades. puerto de control. Técnicas Digitales III – Problema de ingeniería EL CODIGO FUENTE DEL PIC16F84A Este código fuente debe encargarse de las tareas descriptas antes. 19 . Para entender más fácilmente el código se muestra el siguiente diagrama de bloque del algoritmo. Es importante remarcar que la comunicación con la PC mediante el protocolo RS-232 se debe programar porque no viene incorporada a diferencia del siguiente modelo de microcontrolador de Microchip PIC16F873. el MPLAB 9. Se utilizo Dev-C 4. (Ver código fuente para PIC16F84A en Anexo C). un producto de Bloodshed y se programo WIN API (Appication Programming Interface) con clases. el acceso a los dispositivos físicos se hace a través de interfaces. y nunca se accede 20 .Técnicas Digitales III – Problema de ingeniería Código fuente: Para la elaboración de este código fuente se utilizo un entorno de desarrollo integrado distribuido en forma gratuita por Microchip. ESTRUCTURA DE UN PROGRAMA WINDOWS GUI Para el desarrollo de este código fuente se utilizo un entorno de desarrollo integrado también.0 IDE. Para esta ultima tarea también se hizo uso de una tarjeta de programación llamada ProPic 2 Programer. el IC-Prog. Para la programación o grabado del código en la memoria del PIC16F84A se uso otro programa de distribución libre y gratuita.9. Los programas Windows son independientes de la máquina en la que se ejecutan (o al menos deberían serlo). Los programas en Windows están orientados a eventos. Esto es así porque Windows es un sistema operativo multitarea. y después lo reservará para su uso.Técnicas Digitales III – Problema de ingeniería directamente a ellos. Existen recursos físicos. el teclado o el ratón y recursos virtuales o lógicos. Un evento puede ser por ejemplo. Un concepto importante es el de recurso. etc. esto no sería posible. si existe y si no lo está usando otra aplicación. una pulsación de una tecla. ya que no hay que preocuparse por el modelo de tarjeta gráfica o de impresora. como los gráficos. si nuestra aplicación requiere el uso de un puerto serie. la llegada de información desde el puerto serie. la aplicación funcionará con todas.. el sistema no podría atender al resto. Si los programas fueran secuenciales puros. el movimiento del ratón. Por ejemplo. Desde el punto de vista de Windows. un recurso es todo aquello que puede ser usado por una o varias aplicaciones. la activación de un menú. y será el sistema operativo el que se encargue de que así sea. la impresora. y el tiempo del microprocesador ha de repartirse entre todos los programas que se estén ejecutando. primero debe averiguar si está disponible. esto significa que normalmente los programas están esperando a que se produzca un acontecimiento que les incumba. Esto es necesario porque este tipo de recurso no puede ser compartido.. es decir. que son los dispositivos que componen el ordenador. y mientras tanto permanecen aletargados o dormidos. Esta es una de las principales ventajas para el programador. Ejemplo de programa secuencial: Ejemplo de programa por eventos: 21 . ya que hasta que una aplicación finalizara. como la memoria. los iconos o las cadenas de caracteres. LPSTR La función WinMain tiene cuatro parámetros de entrada:  hInstance es un manipulador para la instancia del programa que estamos ejecutando. pueden existir varias versiones de la misma aplicación ejecutándose. esta cadena contiene los argumentos de entrada del comando de línea. // Ficheros include: #include <windows. LPARAM). UINT. Algunas de estas diferencias se deben a que los programas GUI estás basados en mensajes. ya que en Win32 usa un segmento distinto para cada instancia y este parámetro es siempre NULL. // Función de entrada: int WINAPI WinMain(HINSTANCE hInstance. y la correspondiente a un programa Windows GUI. y de ese modo se podían compartir los datos comunes a todas las instancias. 22 . HINSTANCE hPrevInstance. int nCmdShow) { // Declaración: // Inicialización: // Bucle de mensajes: return Message.wParam. Se divide en tres partes claramente diferenciadas: declaración. inicialización y bucle de mensajes. Normalmente. este parámetro nos servía para saber si nuestra aplicación ya se estaba ejecutando. varias instancias.h> // Prototipos: LRESULT CALLBACK WindowProcedure(HWND.Técnicas Digitales III – Problema de ingeniería Hay algunas diferencias entre la estructura de un programa C/C++ normal. y le pasa un manipulador de dicha instancia a la aplicación. lpszCmdParam. } // Definición de La función de entrada de un programa Windows es "WinMain".1. LPSTR lpszCmdParam. en lugar de la conocida "main". hPrevInstance es un manipulador a instancias previas de la misma aplicación. la definición de esta función cambia muy poco de una aplicación a otra. otros son sencillamente debidos a que siempre hay un determinado número de tareas que hay que realizar. Pero eso era antes. Como Windows es multitarea. Parámetros de entrada de "WinMain" int WINAPI WinMain(HINSTANCE lpszCmdParam. WPARAM. HINSTANCE hPrevInstance. Windows crea una Instancia para ella. Cada vez que se ejecuta una aplicación. En Windows 3. int nCmdShow) hInstance. sólo se conserva por motivos de compatibilidad. WS_OVERLAPPEDWINDOW. CW_USEDEFAULT. /* Usar icono y puntero por defecto */ wincl. HINSTANCE hPrevInstance. 544. wincl.style = CS_DBLCLKS.hIcon = LoadIcon(NULL. wincl. /* Inicialización: */ /* Estructura de la ventana */ wincl. wincl.lpfnWndProc = WindowProcedure. wincl.cbClsExtra = 0. int nCmdShow) { /* Declaración: */ HWND hwnd. 375. hThisInstance. CW_USEDEFAULT. wincl.cbSize = sizeof(WNDCLASSEX). IDI_APPLICATION). IDI_APPLICATION). wincl.hInstance = hInstance. wincl. salir del programa */ if(!RegisterClassEx(&wincl)) return 0. "Ejemplo 001". NULL. Función WinMain típica int WINAPI WinMain(HINSTANCE hInstance. /* Registrar la clase de ventana.hIconSm = LoadIcon(NULL. wincl.lpszMenuName = NULL.Técnicas Digitales III – Problema de ingeniería nCmdShow. LPSTR lpszCmdParam.cbWndExtra = 0.lpszClassName = "NUESTRA_CLASE". hwnd = CreateWindowEx( 0. wincl. HWND_DESKTOP.hCursor = LoadCursor(NULL. Se recomienda no usar este parámetro en la función ShowWindow la primera vez que se ésta es llamada. Para ver sus posibles valores consultar valores de ncmdshow. este parámetro especifica cómo se mostrará la ventana.hbrBackground = (HBRUSH)COLOR_BACKGROUND. WNDCLASSEX wincl. NULL ). En su lugar debe usarse el valor SW_SHOWDEFAULT. IDC_ARROW). 23 . MSG mensaje. wincl. si falla. "NUESTRA_CLASE". Técnicas Digitales III – Problema de ingeniería ShowWindow(hwnd. sin ir más lejos. 0. La primera vez que se llama a ésta función. como se recomienda por Windows. que como mínimo serán tres: HWND hWnd. el procedimiento de ventana. Existe otra estructura para registrar clases que se usaba antiguamente. la siguiente. después de crear la ventana. icono. MSG Message. 24 . } return mensaje. SW_SHOWDEFAULT). una variable para manipular los mensajes que lleguen a nuestra aplicación. Ya sabemos que nuestra aplicación necesitará al menos una ventana. 0. Inicialización Esta zona se encarga de registrar la clase o clases de ventana. En el caso de usar una estructura WNDCLASS se debe registrar la clase usando la función RegisterClass. se trata de WNDCLASS. se puede usar el parámetro nCmdShow de WinMain como parámetro o mejor aún. el valor SW_SHOWDEFAULT. como color de fondo. Cualquiera de estas dos funciones nos devuelve un manipulador de ventana que podemos necesitar en otras funciones. /* Bucle de mensajes: */ while(TRUE == GetMessage(&mensaje. una estructura que se usará para registrar la clase particular de ventana que usaremos en nuestra aplicación. la función CreateWindow ha caído prácticamente en desuso. 0)) { TranslateMessage(&mensaje). Para registrar la clase primero hay que rellenar adecuadamente la estructura WNDCLASSEX. Para que la ventana sea visible hay que llamar a la función ShowWindow. WNDCLASSEX wincl. crear la ventana y visualizarla en pantalla. Después hay que llamar a la función RegisterClassEx. un manipulador para la ventana principal de la aplicación.wParam. que define algunas características que serán comunes a todas las ventanas de una misma clase. Pero esto no muestra la ventana en la pantalla. A continuación se crea la ventana usando la función CreateWindowEx. etc. DispatchMessage(&mensaje). menú por defecto. pero que ha sido desplazada por esta nueva versión. } Declaración En la primera zona declararemos las variables que necesitamos para nuestra función WinMain. el programa jamás terminará. DispatchMessage(&mensaje). que indica un error. } NOTA: El problema con este bucle es que si GetMessage regresa con un valor -1. 0. Normalmente. y es la encargada de procesar adecuadamente todos los mensajes enviados a una determinada clase de ventana. y el bucle continúa. esta función se conoce como procedimiento de ventana. El valor -1 indica un error. 0)) { TranslateMessage(&mensaje). Si el error es permanente. estas funciones están basadas en una estructura "switch" donde cada "case" corresponde aun determinado tipo de mensaje. Sintaxis LRESULT CALLBACK WindowProcedure( 25 . y se recuperarán con las siguientes llamadas a GetMessage. aunque no sea el que se usa habitualmente.Técnicas Digitales III – Problema de ingeniería Bucle de mensajes Este es el núcleo de la aplicación. como se ve en el ejemplo el programa permanece en este bucle mientras la función GetMessage retorne con un valor TRUE. while(TRUE == GetMessage(&mensaje. La razón es que la función GetMessage puede retornar tres valores: TRUE. 0)) { TranslateMessage(&mensaje). FALSE ó -1. donde será tratado adecuadamente. 0. El procedimiento de ventana Cada ventana tiene una función asociada. así que en este caso se debería abandonar el bucle. 0. la condición del "while" se considera verdadera. } Este es el bucle de mensajes recomendable. El bucle de mensajes que encontraremos habitualmente es este: while(GetMessage(&mensajee. DispatchMessage(&mensaje). Los mensajes traducidos se reenvían a la lista de mensajes del proceso. 0. La función TranslateMessage se usa para traducir los mensajes de teclas virtuales a mensajes de carácter. Es la responsable de todo lo relativo al aspecto y al comportamiento de una ventana. La función DispatchMessage envía el mensaje al procedimiento de ventana. lParam).Técnicas Digitales III – Problema de ingeniería HWND hwnd. /* envía un mensaje WM_QUIT a la cola de mensajes */ break. El nombre de la función puede cambiar. LPARAM). pero el valor de retorno y los parámetros deben ser los mismos. UINT msg. // Mensaje WPARAM wParam. lParam es el parámetro de tipo doble palabra asociado al mensaje. habrá tantos procedimientos de ventana como programas diferentes y todos serán distintos. varía LPARAM lParam // Parámetro doble palabra. wParam es el parámetro de tipo palabra asociado al mensaje. LPARAM lParam) { switch (msg) /* manipulador del mensaje */ { case WM_DESTROY: PostQuitMessage(0). default: /* para los mensajes de los que no nos ocupamos */ return DefWindowProc(hwnd. msg es el código del mensaje. pero también tendrán algo en común: todos ellos procesarán los mensajes que lleguen a una clase de ventana. } En general. Prototipo de procedimiento de ventana LRESULT CALLBACK WindowProcedure(HWND. El miembro lpfnWndProc de la estructura WNDCLASS es un puntero a una función de este tipo. Podemos considerar este prototipo como una plantilla para crear nuestros propios procedimientos de ventana. UINT. tendremos que asignar a ese miembro el puntero a nuestro procedimiento de ventana. Implementación del procedimiento de ventana simple /* Esta función es llamada por la función del API DispatchMessage() */ LRESULT CALLBACK WindowProcedure(HWND hwnd.     hwnd es el manipulador de la ventana a la que está destinado el mensaje. msg. } return 0. WPARAM. se trata de WM_DESTROY que es el mensaje que se envía a una ventana cuando se recibe un comando de cerrar. Cuando registremos nuestra clase de ventana. // Manipulador de ventana UINT msg. En este ejemplo sólo procesamos un tipo de mensaje. WPARAM wParam. wParam. 26 . ya sea por menú o mediante el icono de aspa en la esquina superior derecha de la ventana. varía ). esa función es la que se encargará de procesar todos los mensajes para esa clase de ventana. // Parámetro palabra. efectivamente cierra la aplicación. El archivo ejecutable de la aplicación resultante consta de la siguiente representación grafica básica: Haciendo click sobre el botón “Principal” El ítem “Reorganizar Botones” modifica la organización de la tabla cargada por defecto mostrada en el apartado “EL URC SBC-RU-240/38 DE PHILIPS”. Este es el camino que sigue el mensaje WM_QUIT cuando llega. y lo hace enviándole un mensaje WM_QUIT. guardar variables. Al presionar este item se abre un nuevo cuadro de dialogo que nos permite elegir la combinación de teclas a reordenar y a continuación el programa se dispone a esperar el correspondiente código emitido por el control remoto. ya sabemos hacer el esqueleto de una aplicación de Windows. y le da una oportunidad de dejar las cosas en su sitio: cerrar ficheros. (ver código fuente para la PC en Anexo C).Técnicas Digitales III – Problema de ingeniería Este mensaje sólo sirve para informar a la aplicación de que el usuario tiene la intención de abandonar la aplicación. Para entender el resto del código que se presenta a continuación se pide al lector remitirse a la bibliografía. el programa nos devuelve un mensaje de código guardado. En este ejemplo se selecciona la opción 2 (Alt). liberar memoria. Incluso. DefWindowProc. Finalmente conseguimos “fabricar” tanto la aplicación de la PC como el Hardware externo para el resolver el problema de ingeniería que se nos propuso. y simplemente se cede su tratamiento a la función del API que hace el proceso por defecto para cada mensaje. etc. A grandes rasgos. mediante la función PostQuitMessage. RESULTADOS DE LAS PRUEBAS Las pruebas fueron satisfactorias. básicamente. Hubo que realizar algunas modificaciones antes de alcanzar el material o información expuesta en este informe. En el caso del ejemplo. ya que el proceso por defecto para este mensaje es cerrar la aplicación. la aplicación puede decidir que aún no es el momento adecuado para abandonar la aplicación. El resto de los mensajes se procesan en el caso "default". Cuando la PC recibe este dato. 27 . 28 .Técnicas Digitales III – Problema de ingeniería Después de aceptar la elección. presionamos un botón del mando a distancia y el programa nos informa de su recepción: El ítem “Recordatorios” nos permite colocar una etiqueta recordatorio para cada combinación de tecla disponible. probamos por última vez con el puerto serie y nos anduvo. 29 . la cual la aprendimos por necesidad para poder solucionar el problema de no funcionamiento del puerto serie. En primer lugar era tema de total desconocimiento para todos nosotros. Por ello es que en el código fuente de la aplicación para la PC no aparece la interacción con el puerto paralelo a pesar de que el PIC16F84A si es capaz de soportarla (en teoría pues no la alcanzamos a probar). así mismo con la comunicación por puerto paralelo. de dicha comunicación. carga la tabla indicada en el apartado “EL URC SBC-RU-240/38 DE PHILIPS” en el caso de que el usuario no encuentre una mejor disposición del control remoto. En los comienzos logramos antes que nada establecer la comunicación serie en Windows 98 con un código programado en Borland C++ que andaba pero al no ser una aplicación de Windows. en el código fuente de la PC. Tuvimos muchísimos problemas. algunos comentados en este informe. en un principio con la comunicación por el puerto serie. En cuanto a la programación en entorno Windows tuvimos que leer muchísimo para así a duras penas poder hacer algo. Por suerte justo antes de hacer la implementación. no podíamos de ninguna manera simular el teclado. el ítem “Comenzar” provoca que el programa se disponga a “vigilar” el puerto serie en espera por la entrada de cada nuevo comando.Técnicas Digitales III – Problema de ingeniería El ítem “Default”. Entonces ya con medio proyecto realizado tuvimos que echarnos atrás. Por ultimo. desistir del Borland C++ y utilizar las API de Windows. CONCLUSIONES Durante la realización del proyecto el grupo tuvo que enfrentarse a muchísimos problemas. void impcart(void). entrada. 30 . nosound(). lcr. dll. void ventana(void). case '2': { sound(1250). ventana(). divisor. void transdat(void). princ: clrscr(). sound(1250). delay(100). mcr. } break.Técnicas Digitales III – Problema de ingeniería Código en Borland: #include #include #include #include <dos. delay(225). scanf ("%d". &com). lsr. base. sound(1250). switch (opc) { case '1': { sound(1250). opc=getch(). void correr(void).h> <conio. msr.h> #define #define #define #define #define #define #define #define #define LCR IER DLL DLM MCR MSR LSR RBR THR #define #define #define #define #define #define DR OE PE FE BI DSR (base+3) (base+1) (base+0) (base+1) (base+4) (base+6) (base+5) (base+0) (base+0) 1 2 4 8 16 32 /* /* /* /* /* /* /* /* /* registro de control de linea */ registro de activacion de interrupciones */ parte baja del divisor */ parte alta del divisor */ registro de control del modem */ registro de estado del modem */ registro de estado de linea */ registro buffer de recepcion */ registro de retencion de transmision */ /* /* /* /* /* /* bit bit bit bit bit bit dato disponible del LSR */ de error de overrun del LSR */ de error de paridad del LSR */ de error en bits de stop del LSR */ de error de break en el LSR */ de data set ready */ unsigned com. delay(225). con=0.c='z'. printf("\n\r1:Eleccion de puerto serie\n\r2:Correr programa\n\r3:Salir\n\rOpcion: ").h> <stdio. nosound(). dlm.h> <stdlib. void main() { com=1. impcart(). void error(void). delay(225). char opc='z'. delay(250). nosound(). msr=inportb(MSR). return. finc: c='z'. delay(100). sin paridad */ corr: outportb (MCR. 0x83). } divisor=115200/8300. printf("dato: %d". if(c=='e') goto finc. clrscr(). goto finc. transdat().Técnicas Digitales III – Problema de ingeniería nosound(). } if(opc=='3'). correr(). else goto princ. /* if (lsr & (PE|FE|BI)) { error(). entrada=inportb(RBR). goto corr. 1). if(kbhit()) c=getche(). } break. if(lsr & DR) outportb(MCR. divisor%256). //parte entera de la division por 256 dll=inportb(DLL). } void correr() { clrscr(). divisor/256). /* DLAB=1. 0x03). dlm=inportb(DLM). delay(225). outportb (LCR. 1 stop. if (base==0) { error(). sound(1250). 1 stop. 8 bits. 8 bits. 0). sin paridad */ outportb (IER. entrada). /* DLAB=0. 0). //resto de la division por 256 outportb (DLM. goto corr. (com-1)*2). }*/ }while(!(lsr & DR) && !kbhit()). //limpio el control de modem do { lsr=inportb(LSR). } void error() { 31 . //para 9600 baudios outportb (LCR. impcart(). nosound(). base=peek(0x40. outportb (DLL. entrada).1). \n"). "%d". cprintf(" error en la comunicacion textcolor(7). textcolor(1).txt". aprendimos mucho acerca de Windows como sistema operativo y de la PC como sistema eléctrico. cprintf(" ingrese el puerto preferido: textcolor(7). } void ventana() { gotoxy(23. "w"). textbackground(3). También consideramos haber aprendido mucho de cómo es que se encara un trabajo particular a nivel profesional. return. } void impcart() { gotoxy(23. return.11).Técnicas Digitales III – Problema de ingeniería gotoxy(23. fclose(archi). El grupo entero considera un enriquecimiento muy importante de conocimientos. textbackground(0). textcolor(4). "). archi=fopen("trans. return. textbackground(4). Agradecemos la interacción constante por parte de los profesores entrevistados. textcolor(6). cprintf(" control remoto IR textcolor(7).11). Si bien esta técnica presenta muchos problemas de errores conceptuales. agradecemos toda su paciencia y participación para con los alumnos y los problemas con los que nos enfrentamos… Gracias Ramiro… 32 . conseguíamos una mínima interacción entre el control remoto y la PC. textbackground(0). fprintf(archi. En este código se puede ver el intento de envío del dato recibido por el puerto a través de un archivo de texto para interactuar con el programa que simulaba el teclado y que si corría bajo Windows. textbackground(3). getch(). } "). return. } void transdat() { FILE *archi. textbackground(0). 5 pub.0 pub.1 aux.6 aux.0 esta.2 pub.4 aux.4 inte.7 inte.7 inte.1 pub.3 aux.Técnicas Digitales III – Problema de ingeniería ANEXOS Anexo A: LISTADO DE PROGRAMAS Código fuente para el PIC16F84A: List P=16F84 pua pub copua copub inte coti opci esta equ equ equ equ equ equ equ equ cblock 05h 06h 85h 86h 0Bh 01h 81h 03h 0X0C cnttrb cbyte byte cont1 cont2 cont3 disp1 disp contr contr1 contr2 aux endc #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define ir rts dtr txd rxd dsr cts bot ledv ledr prvz resul aplv tsp terr resu bit cop toif rbo tmro todas rbof car z org 00h pub.2 aux.2 inte.3 pub.6 pub.7 pua.2 aux.2 33 .5 aux.1 esta.5 inte.0 aux.4 pub.0 pua. k+1 .Técnicas Digitales III – Problema de ingeniería goto org goto inicio 04h intsub clrf bsf movlw movwf movlw movwf clrf bsf bcf clrf bsf clrf bsf bsf clrf clrf clrf movlw movwf clrf clrf clrf movlw movwf esta esta.************** .771*k+3=>si 771*k+3=20 ms/1 .desendente opci. para un reloj de 4 Mhz son: .7 esta. 5 b'10001111' copub b'11111010' copua opci .2*k . .1*k .la cantidad de pulsos de 1us .1 con1 bot esper clrf bcf bsf call btfss goto movlw xorwf bsf call bcf btfss goto call bsf disp1 prvz ledr retalar bot esper b'00001000' aux.1 . 5 pua ledr pub dsr rxd inte aux disp h'ff' disp disp1 byte cbyte b'10010000' inte .255*k+k=256*k .us=25000=>k=32.1*k .1 . 1 ledv retalar ledv tsp esper retalar ledv inicio esper con1 con2 .iterrupcion por flanco . .2*255*k=510*k .1 con2 cont1.habilita IR rcecptor btfss goto bot esper movlw movwf d'33' cont1 movlw movwf d'255' cont2 decfsz goto decfsz goto btfss goto cont2.para retardo del pulsador .42~33 34 . 0 btfss z goto etmr comie btfss toif goto comie movlw d'36' movwf coti bcf toif decf cnttrb.TOIF= .25~35 .5 .1 .Técnicas Digitales III – Problema de ingeniería call retalar bcf ledv goto esper .125=> . pero .es a TOIF/2 movwf coti .tin=146.pero experimentalmente .****************************************************** ledat bsf esta.tin~146.1 movlw d'12' subwf cnttrb.1 btfss bit 35 . .sincr btfss ir goto entce movlw d'147' .0 btfss z goto dsipo bcf bit incf cnttrb.voy a esperar .=>con div=4.para corregir tb el ultimo nibble goto cmnz dsipo movlw b'01000000' xorwf aux.~36 entce .div*(257 us-tin)+2=889 bcf esta.experimentalmente ~147 bcf toif clrf byte bcf bit clrf disp1 movlw d'26' movwf cnttrb etmr btfss toif goto etmr bcf toif movlw d'36' movwf coti decf cnttrb.778 ms movwf opci .bit de .tin=257-887/4=35.con un reloj de 4 Mhz: movlw b'10000001' .tb'=889 us .1 movlw d'24' subwf cnttrb.que pase el primer .pero la primer pregunta .->tb=2*tb'=1.con div=4=> .5 . en byte guarda los 6 bit del comando sgdz crz parch acoreg ."T" y los 5 de .1 cmnz .1 comie btfsc goto bcf rlf goto disp1.pongo un cero en el bit 7 36 .dispositivo cerx sgdo ceroz cmnz comma crxz .0 listim car disp1.en disp1 esta guardando 1 .1 parch btfsc goto bcf rlf byte.1 decfsz goto cnttrb.1 comie btfss goto movlw movwf bcf toif cmnz d'36' coti toif movlw xorwf btfss goto btfsc goto bsf goto b'01000000' aux.0 parch bcf byte.0 listim car disp1.0 listim car byte.0 goto comie bcf goto disp1.Técnicas Digitales III – Problema de ingeniería goto btfsc goto bsf sgdo ir cerx disp1.0 comie btfss goto btfss goto bcf rlf goto ir ceroz disp1.1 bit sgdz ir crxz byte.0 listim car byte.bit de .0 goto parch btfss goto btfss goto bcf rlf goto ir crz byte. ****************************************************** cmprb movf disp1.0 btfsc z bsf cop finto return .1 disp1.exactamente al reves.6 listi bsf bsf goto disp.comprobado con .de byte si se da .0 movwf disp bsf prvz bcf ledr bsf ledv call retalar bcf ledv fingdi call cmprb btfss cop 37 .codigo de repeticion btfsc goto bcf goto disp.0 subwf disp.1 byte.5 byte.5 ciro byte.5 byte.sciloscopio ciro not .6 listi . .6 listi bcf bsf goto disp.pongo un uno en el bit 7 .5 not disp.1 movlw andwf andwf btfss goto btfss goto bcf goto b'00111111' disp1.de byte si no se da .los datos estan .1 byte.codigo de repeticion bcf rrf comf car byte.Técnicas Digitales III – Problema de ingeniería .6 listi bsf terr cir listim listi return .****************************************************** intsub bcf todas call ledat btfsc terr goto finle btfsc prvz goto disp1.5 cir byte. Técnicas Digitales III – Problema de ingeniería goto bcf bsf btfss goto call goto finle cop ledv tsp serie datopcp finle call datopcs serie finle bcf ledv bcf terr bcf rbof bsf todas retfie .5 .para 25ms =>con div=128=> .16/2= .contesta.el TMRO: movwf coti . y .205.tin~61.us/257us=0.experimentalmente ~206 38 ..espero un rato lo que dura un ..con un reloj de 4 Mhz.92~206 .=>adopto div=2 y preseteo .us=>TOIF=(257us*div)+2 .tb=1/9600=104.=>div=102. pero .5 movlw d'61' movwf coti bcf toif agnte btfss dtr goto acseg btfss toif goto agnte bsf ledr call retalar bcf ledr goto fintr acseg bsf esta.398 movlw d'206' .16 .16 us bcf rxd .****************************************************** datopcs movf byte.TOIF->104. fue.tin=257-102.16 us=> .7~62.experimentalmente ~61 movlw b'10000110' movwf opci movlw b'10001111' movwf copub bcf esta.16 .0 movwf cbyte movlw d'09' movwf contr bcf dsr .5 movlw b'10000000' movwf opci bcf esta.mensaje (25ms) y si la pc no me .para 9600 b/s: bcf toif .=>(257-in)*2us+2us= .104.5 . bsf esta. transmitiendo el LSB.5 aquie clrf coti bcf toif pruev btfss toif goto pruev decfsz cont1. 1 bsf cbyte.************************************************* retalar movlw d'20' movwf cont1 bsf esta. Se .0 goto bsf rrf goto escer rxd cbyte. 2 bsf cbyte.1 estmr btfss goto bsf toif dtlst rxd estmr .de lo contrario.1 goto aquie return .1 btfss goto movlw movwf bcf decfsz goto toif sgteb d'206' coti toif contr. 0 bsf cbyte. . 5 movlw b'10000101' movwf copub bcf esta.modifica el sentido de . 6 btfsc byte. 3 39 . 7 .5 movlw b'10000111' movwf opci bcf esta. 5 clrf cbyte btfsc byte.1 sgteb bcf rrf rxd cbyte.0 para empezar.Técnicas Digitales III – Problema de ingeniería bcf goto toif sgteb btfss cbyte.******************************************************* datopcp bsf esta. 5 btfsc byte.rotacion tb escer sgteb dtlst fintr bsf dsr bsf rxd return . contesta.*************************************************** END 40 .mensaje . .7~62.(25ms) y si la pc no me . 4 cbyte. 3 cbyte. fue. 1 cbyte.para 25ms =>con div=128=> .. 0 pub .pero experimentalmente ~61 agntep acsegp fintra call retalar clrf pub return . 5 cbyte. .espero un rato lo que dura un . 1 cbyte. 3 byte. 7 cbyte..5 d'61' coti toif btfsc goto btfss goto bsf call bcf goto dtr acsegp toif agntep ledr retalar ledr fintra clrf btfsc bsf btfsc bsf btfsc bsf btfsc bsf movf movwf cbyte byte. 0 pub bsf esta.Técnicas Digitales III – Problema de ingeniería btfsc bsf movf movwf byte. 6 byte. 6 cbyte. .5 movlw movwf bcf movlw movwf bcf b'10000110' opci esta.tin~61. 5 byte. h> <windows. void LeeSerie(). *ide. int num[50]. WPARAM. void comenzar(void). // Prototipos: void IniciarBuffers(). BOOL CALLBACK DlgProc(HWND. char diide[20]="C:\\iden. UINT. bool FinComunicacion(void). void actualizar(). BOOL CALLBACK DlgProc2(HWND. *cad. void cargar_archivo(). bool InicioComunicacion(void).h> <assert.h> <IDS3. // Variables globales: tipoOpciones Ops. char Paridad[25].txt".h> <cstdlib> using namespace std. typedef struct { char Puerto[5]. int aux2. void actualizaride(). DCB dcb.txt". WPARAM. con1. FILE *numeros. int BitsDatos. WPARAM. int lee_el_puerto(void). /* Declaración del procedimiento de ventana */ LRESULT CALLBACK WindowProcedure (HWND. char dinum[20]="C:\\nume. bool Comunicacion. hSalida.Técnicas Digitales III – Problema de ingeniería Código fuente para la PC: WinMain: #include #include #include #include #include #include #include #include <windows. int BitsStop. LPARAM). char idtf[22][80]. } tipoOpciones. UINT. void crear_la_tabla(). // Opciones HGLOBAL hCadena.h> <iostream> <string. void crear_la_tablaide(). void cargar_archivoide(). UINT. // Puerto serie HANDLE idComDev. LPARAM). void LiberarBuffers(). tec[50]. 41 . LPARAM).h> <stdlib. int Baudios. // Buffers int *sal. /* clase o la ventana */ /* Usar el color de fondo por defecto para la ventana */ wincl. /* Registrar la clase de ventana. wincl. /* Usar icono y puntero por defecto */ wincl. wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND.hInstance = hThisInstance. /* Sin información adicional para la */ wincl. LPSTR lpszArgument. char identif17[80]. char identif1[80].style = CS_DBLCLKS. char identif15[80]. wincl. si falla. char identif19[80]. char identif21[80].hIconSm = LoadIcon (hThisInstance. /* Estructura de datos para la clase de ventana */ num[0]=EOF. char identif18[80]. 42 .cbWndExtra = 0. char identif12[80]. char identif3[80]. "icono").cbClsExtra = 0. /* Mensajes recibidos por la aplicación */ WNDCLASSEX wincl. /* Estructura de la ventana */ wincl. /* Captura los doble-clicks */ wincl. wincl. int nFunsterStil) { HWND hwnd. tec[0]=EOF. char identif8[80]. IDC_ARROW). char identif14[80]. } DATOS. wincl.Técnicas Digitales III – Problema de ingeniería /* Declaraciones de tipos */ typedef struct stDatos { int Teclas. idtf[21][0]=EOF. wincl. salir del programa */ if(!RegisterClassEx(&wincl)) return 0.hCursor = LoadCursor (NULL. HINSTANCE hPrevInstance. char identif2[80]. char identif16[80].hIcon = LoadIcon (hThisInstance. char identif5[80].lpszClassName = "NUESTRA_CLASE". char identif4[80]. char identif7[80]. char identif13[80]. "icono"). char identif11[80].lpszMenuName = "Menu". int WINAPI WinMain (HINSTANCE hThisInstance.lpfnWndProc = WindowProcedure. /* Esta función es invocada por Windows */ wincl. char identif9[80]. char identif10[80]. char identif6[80]. char identif20[80].cbSize = sizeof (WNDCLASSEX). /* Manipulador de ventana */ MSG mensaje. Teclas = 1. /* Ancho */ 100. } /* Salir con valor de retorno */ return mensaje. /* Alto en pixels */ HWND_DESKTOP. 0)) { /* Traducir mensajes de teclas virtuales a mensajes de caracteres */ TranslateMessage(&mensaje). /* Bucle de mensajes. (LPARAM)&Datos). if(LOWORD(wParam) == CM_DIALOGO3) { comenzar().Técnicas Digitales III – Problema de ingeniería /* La clase está registrada. break. hwnd. /* Manipulador de instancia */ NULL /* No hay datos de creación de ventana */ ). 43 . LPARAM lParam) { static HINSTANCE hInstance. /* donde se coloca la ventana */ 200. (LPARAM)&Datos). NULL. /* Tipo por defecto */ CW_USEDEFAULT. 0. /* La ventana es hija del escritorio */ NULL. /* Posibilidades de variación */ "NUESTRA_CLASE". return 0. SW_SHOWDEFAULT). "DialogoTeclasmos". se ejecuta hasta que haya error o GetMessage devuelva FALSE */ while(TRUE == GetMessage(&mensaje. static DATOS Datos. UINT msg. /* Nombre de la clase */ "Control Remoto". switch (msg) /* manipulador del mensaje */ { case WM_CREATE: hInstance = ((LPCREATESTRUCT)lParam)->hInstance. /* Texto del título */ WS_OVERLAPPEDWINDOW. if(LOWORD(wParam) == CM_DIALOGO2) DialogBoxParam(hInstance. WPARAM wParam. hwnd. /* Sin menú */ hThisInstance. /* Enviar mensaje al procedimiento de ventana */ DispatchMessage(&mensaje). /* Mostrar la ventana */ ShowWindow(hwnd. /* Inicialización de los datos de la aplicación */ Datos. /* Windows decide la posición */ CW_USEDEFAULT. } if(LOWORD(wParam) == CM_DIALOGO4) crear_la_tabla(). "DialogoTeclas". DlgProc2. case WM_COMMAND: if(LOWORD(wParam) == CM_DIALOGO) DialogBoxParam(hInstance. DlgProc.wParam. crear la ventana */ hwnd = CreateWindowEx( 0. } /* Esta función es invocada por la función DispatchMessage() */ LRESULT CALLBACK WindowProcedure(HWND hwnd. auxi2=num[nume-1]. for(con1=0. SetFocus(GetDlgItem(hDlg. break. ID_TECLAS)). case IDCANCEL: 44 . FALSE). default: /* para los mensajes de los que no nos ocupamos */ return DefWindowProc(hwnd. MB_OK). MB_ICONEXCLAMATION | MB_OK). int nume.con1++) if(num[con1]==auxi) num[con1]=auxi2. (UINT)datos->Teclas. "Número no válido". "Entrada Invalida". auxi.Técnicas Digitales III – Problema de ingeniería break. "Codigo Guardado". wParam. switch (msg) /* manipulador del mensaje */ { case WM_INITDIALOG: datos = (DATOS *)lParam. cargar_archivo(). if(NumeroOk) { inv: datos->Teclas = nume. static DATOS *datos. MessageBox(hDlg.con1<21. /* envía un mensaje WM_QUIT a la cola de mensajes */ break. auxi2. if(nume>21 || nume<1) { MessageBox(hDlg. con1++. else fclose(numeros). } return 0. EndDialog(hDlg. ID_TECLAS. } else MessageBox(hDlg. lParam). num[nume-1]=auxi. FALSE). MB_OK). actualizar(). case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: nume = GetDlgItemInt(hDlg. if((numeros=fopen(dinum. UINT msg. return FALSE. "rb"))==NULL) crear_la_tabla(). return FALSE. WPARAM wParam. "Relacionando". } BOOL CALLBACK DlgProc(HWND hDlg. "Relacionando". ID_TECLAS. &NumeroOk. SetDlgItemInt(hDlg. LPARAM lParam) { BOOL NumeroOk. "Error". msg. FALSE). } auxi=lee_el_puerto(). case WM_DESTROY: PostQuitMessage(0). datos->identif2). ID_IDENT1. datos->identif6). strcpy(idtf[0]. SetDlgItemText(hDlg. ID_IDENT10. ID_IDENT12. strcpy(idtf[6]. SetDlgItemText(hDlg. 80). case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: GetDlgItemText(hDlg. UINT msg. idtf[4]).Técnicas Digitales III – Problema de ingeniería EndDialog(hDlg. idtf[9]). 80). idtf[17]). idtf[7]). datos->identif7). SetDlgItemText(hDlg. SetDlgItemText(hDlg. ID_IDENT21. SetDlgItemText(hDlg. ID_IDENT1)). SetDlgItemText(hDlg. strcpy(idtf[1]. ID_IDENT14. GetDlgItemText(hDlg. ID_IDENT19. ID_IDENT11. ID_IDENT6. GetDlgItemText(hDlg. SetDlgItemText(hDlg. idtf[6]). switch (msg) /* manipulador del mensaje */ { case WM_INITDIALOG: datos = (DATOS *)lParam. 80). "a"))==NULL) crear_la_tablaide(). idtf[13]). datos->identif5. ID_IDENT1. idtf[11]). idtf[10]). idtf[0]). ID_IDENT18. ID_IDENT3. SetFocus(GetDlgItem(hDlg. SetDlgItemText(hDlg. ID_IDENT8. datos->identif4. strcpy(idtf[3]. } return TRUE. ID_IDENT4. idtf[19]). idtf[14]). } BOOL CALLBACK DlgProc2(HWND hDlg. SetDlgItemText(hDlg. idtf[3]). ID_IDENT15. idtf[18]). SetDlgItemText(hDlg. datos->identif3). SetDlgItemText(hDlg. ID_IDENT7. 80). ID_IDENT16. GetDlgItemText(hDlg. datos->identif7. ID_IDENT3. } return FALSE. GetDlgItemText(hDlg. SetDlgItemText(hDlg. ID_IDENT20. idtf[8]). strcpy(idtf[5]. strcpy(idtf[4]. idtf[1]). ID_IDENT13. datos->identif6. idtf[2]). ID_IDENT6. datos->identif5). strcpy(idtf[2]. ID_IDENT7. break. datos->identif2. datos->identif1). if((ide=fopen(diide. ID_IDENT4. cargar_archivoide(). 80). idtf[20]). 80). SetDlgItemText(hDlg. ID_IDENT2. ID_IDENT9. GetDlgItemText(hDlg. idtf[16]). 45 . GetDlgItemText(hDlg. else fclose(ide). idtf[5]). SetDlgItemText(hDlg. ID_IDENT5. WPARAM wParam. datos->identif4). SetDlgItemText(hDlg. datos->identif1. 80). SetDlgItemText(hDlg. idtf[15]). FALSE). SetDlgItemText(hDlg. LPARAM lParam) { static DATOS *datos. SetDlgItemText(hDlg. idtf[12]). ID_IDENT5. return FALSE. ID_IDENT17. ID_IDENT2. datos->identif3. SetDlgItemText(hDlg. SetDlgItemText(hDlg. SetDlgItemText(hDlg. ID_IDENT19. GetDlgItemText(hDlg. 80).Técnicas Digitales III – Problema de ingeniería GetDlgItemText(hDlg. Ops. datos->identif17).Baudios = 9600. break. strcpy(idtf[16]. 80). IniciarBuffers(). break. datos->identif9. ID_IDENT13. datos->identif11). datos->identif19. Ops. GetDlgItemText(hDlg. param. datos->identif18. datos->identif11. GetDlgItemText(hDlg. strcpy(idtf[11]. id. ID_IDENT14. case IDCANCEL: EndDialog(hDlg. DWORD n. datos->identif13.BitsDatos = 8. ID_IDENT21. strcpy(idtf[18]. // Inicializar opciones del puerto serie: strcpy(Ops. } return TRUE. GetDlgItemText(hDlg. 80). GetDlgItemText(hDlg. GetDlgItemText(hDlg. 80). return 1. FALSE). DWORD dwEvtMask. } int lee_el_puerto(void) { int c. datos->identif21. 80). 80). strcpy(idtf[17]. datos->identif16). ID_IDENT17. 80). "COM1"). strcpy(idtf[8]. datos->identif14). strcpy(idtf[19]. datos->identif18). ID_IDENT18.Puerto. ID_IDENT9. ID_IDENT16.Paridad. GetDlgItemText(hDlg. 80). strcpy(idtf[13]. EndDialog(hDlg. strcpy(idtf[12]. datos->identif20. datos->identif21). FALSE). datos->identif12). datos->identif15). ID_IDENT10. 80). GetDlgItemText(hDlg. 80). GetDlgItemText(hDlg. GetDlgItemText(hDlg. actualizaride(). strcpy(idtf[7]. strcpy(Ops. datos->identif8). strcpy(idtf[14]. GetDlgItemText(hDlg. if(!InicioComunicacion()) { LiberarBuffers(). datos->identif17. ID_IDENT15. // No se ha establecido comunicación: Comunicacion = false. strcpy(idtf[9]. datos->identif9). 80). ID_IDENT20. datos->identif14.BitsStop = 1. datos->identif10). strcpy(idtf[10]. datos->identif16. datos->identif15. datos->identif19). datos->identif13). strcpy(idtf[20]. 80). ID_IDENT11. datos->identif8. ID_IDENT12. Ops. } 46 . 80). GetDlgItemText(hDlg. 80). GetDlgItemText(hDlg. strcpy(idtf[15]. datos->identif12. ID_IDENT8. } return FALSE. datos->identif10. datos->identif20). "Sin paridad"). Paridad. c=c&63.Paridad. if(idComDev ==INVALID_HANDLE_VALUE) return false. GlobalUnlock(hSalida). 0. // Leer estructura de control del puerto serie.BaudRate = Ops.Puerto. } // Iniciar el puerto serie: bool InicioComunicacion(void) { bool fSuccess. cad = (int *)GlobalLock(hCadena).ByteSize = Ops. break.Parity = ODDPARITY. } // Reservar memoria global para buffers del puerto serie: void IniciarBuffers() { hCadena = GlobalAlloc(GMEM_MOVEABLE. 47 . OPEN_EXISTING.StopBits = ONESTOPBIT.BitsDatos. // Abrir el fichero asociado al puerto: idComDev = CreateFile(Ops. switch(Ops. // Modificar el dcb según las opciones definidas: dcb. c=*cad. break. } // Liberar memoria global de buffers del puerto serie: void LiberarBuffers() { GlobalUnlock(hCadena). if(!strcmp(Ops. &dwEvtMask. GENERIC_READ | GENERIC_WRITE. 4096). hSalida = GlobalAlloc(GMEM_MOVEABLE. 4096). NULL).BitsStop) { case 1: dcb. case 2: dcb.Paridad. "Paridad impar")) dcb. GlobalFree(hSalida). LiberarBuffers(). aux2=aux2-c. cdb: fSuccess = GetCommState(idComDev. GlobalFree(hCadena). dcb. NULL. NULL))&&(dwEvtMask & EV_RXCHAR))). 0.Técnicas Digitales III – Problema de ingeniería do { }while(!((WaitCommEvent(idComDev.Parity = NOPARITY. &dcb). return(c). LeeSerie(). if(!strcmp(Ops.Baudios.StopBits = TWOSTOPBITS. aux2=c&127.Parity = EVENPARITY. if(!strcmp(Ops. FinComunicacion(). sal = (int *)GlobalLock(hSalida). if(!fSuccess) return false. "Paridad par")) dcb. "Sin paridad")) dcb. NULL). &x. j. &x.cbInQue caracteres: ReadFile(idComDev. return. return true. "r"))==NULL) crear_la_tablaide(). else fclose(ide). // Comunicación establecida: Comunicacion = true. 0). &dcb).Técnicas Digitales III – Problema de ingeniería } // Modificar la estructura de control del puerto serie: fSuccess = SetCommState(idComDev. k. sirve para // averiguar el número de bytes en el buffer de entrada: ClearCommError(idComDev. //inicio if((numeros=fopen(dinum. DWORD x. EV_RXCHAR)) return false. } // Leer datos del puerto serie: void LeeSerie() { int i. } // Finalizar comunicación por puerto serie: bool FinComunicacion(void) { // Liberar máscara de eventos del puerto serie: SetCommMask(idComDev. "rb"))==NULL) crear_la_tabla(). k=0. else fclose(numeros). if(!fSuccess) return false. COMSTAT cs. aux. otra: 48 . } void comenzar() { int delcontr. // Cerrar el puerto serie: CloseHandle(idComDev).i++) tec[i]=i+1. // Comunicación interrumpida: Comunicacion = false. return true.cbInQue. cad. // Leer cs. tec[21]=EOF. i. // Especifica que queremos monitorizar la recepción de datos: if(!SetCommMask(idComDev.i<21. // Actualizar el fin de cadena: cad[x]=0. // Actualizar COMSTAT. cargar_archivo(). cs. cargar_archivoide(). &cs). for(i=0. if((ide=fopen(diide. 0).0xb8. case 13: keybd_event(VK_BACK. 0).0 . // Suelta Flecha arriba break.0). KEYEVENTF_KEYUP.0 . case 12: keybd_event(VK_SPACE. case 3: keybd_event(VkKeyScan('B').0).0 . // Presiona 'L' keybd_event(VkKeyScan('L'). // Presiona 'X' keybd_event(VkKeyScan('X'). // Suelta Esape break. 0). while(num[con1]!=delcontr && (con1<100)) con1++.KEYEVENTF_KEYUP. con1=0.0 .0x9c.0 .0).0xc8.KEYEVENTF_KEYUP. case 10: keybd_event(VK_DOWN. KEYEVENTF_KEYUP.0xa6. // Suelta Barra espaciadora break.0).0xb9. // Presiona 'B' keybd_event(VkKeyScan('B'). 0). case 4: keybd_event(VkKeyScan('Z').0). if((num[con1]==EOF)||((aux!=9)&&(aux!=10)&&(aux2==0))) goto otra. // Periona Shift derecho keybd_event(VkKeyScan('L'). // Periona Flecha derecha keybd_event(VK_RIGHT. // Periona Flecha arriba keybd_event(VK_UP.0xa6. // Presiona Esape keybd_event(VK_ESCAPE.0xb6. 0).0). 0).KEYEVENTF_KEYUP. KEYEVENTF_KEYUP. case 2: if((k%2)==0) keybd_event(VK_MENU. //Presiona Alt else keybd_event(VK_MENU.KEYEVENTF_KEYUP.0xac.0 .0). case 5: keybd_event(VkKeyScan('X').0).KEYEVENTF_KEYUP.0 .0xd0.0xb0.0 . KEYEVENTF_KEYUP.0 . case 8: keybd_event(VK_RSHIFT.0xb6. // Periona Enter keybd_event(VK_RETURN. // Suelta Shift derecho break.0 .0xcd. // Presiona Barra espaciadora keybd_event(VK_SPACE.0). // Suelta 'Z' break.0xad. switch(aux) { case 1: keybd_event(VK_RIGHT.0). // Suelta Alt k++.0 .0 . 0). // Suelta 'L' break. 0). // Suelta Enter break.0xd0. 0).0xac. case 6: keybd_event(VK_RETURN.0xcd. aux=tec[con1].0). // Suelta Flecha abajo break. // Suelta 'B' break. 0).0xb9.0x81. // Suelta Flecha derecha break. 0).0 .Técnicas Digitales III – Problema de ingeniería delcontr=lee_el_puerto().0x8e. KEYEVENTF_KEYUP.0xb0. // Presiona 'Z' keybd_event(VkKeyScan('Z'). // Suelta 'L' keybd_event(VK_RSHIFT. // Suelta 'X' break. case 11: keybd_event(VK_ESCAPE. 0).0).0xad.0xc8.0xa6. //Presiona Flecha abajo keybd_event(VK_DOWN.0xa6.0x81. 0).0x9c. // Presiona Back Space 49 . case 7: keybd_event(VkKeyScan('L'). KEYEVENTF_KEYUP. case 9: keybd_event(VK_UP. // Presiona 'L' keybd_event(VkKeyScan('L').0 . break.KEYEVENTF_KEYUP. KEYEVENTF_KEYUP.0xb8.0). 0). } goto otra. num[8]=32. case 16: keybd_event(VK_CONTROL.0xcb.0).0 . num[13]=15. KEYEVENTF_KEYUP. // Suelta Windows break. // Periona Ctrl keybd_event(VK_TAB.0xb8. case 15: keybd_event(VK_MENU. num[9]=33. KEYEVENTF_KEYUP.0xb8.0 . //Presiona Alt keybd_event(VK_SPACE. // Periona Shift derecho keybd_event(VK_TAB. 0).0).0). //Prtesiona tab keybd_event(VK_TAB.Técnicas Digitales III – Problema de ingeniería keybd_event(VK_BACK.0).0xb9. // Flecha izquierda keybd_event(VK_LEFT.0 .0).0 . 0). //Presiona Alt keybd_event(VK_F4. 0). // Periona Windows keybd_event(VK_LWIN.0xbe. 0). // Suelta 'M' keybd_event(VK_LWIN.0xb8.0).0x8f.0x9c. case 19: keybd_event(VK_LWIN. // Suelta Windows break.0).KEYEVENTF_KEYUP. num[12]=48. //suelta tab keybd_event(VK_RSHIFT. case 21: keybd_event(VK_RSHIFT.KEYEVENTF_KEYUP.0).0x8f. } void crear_la_tabla() { num[0]=52. 0).KEYEVENTF_KEYUP.0 . 0).0x8f. KEYEVENTF_KEYUP. // Suelta Ctrl break. // Flecha izquierda break. KEYEVENTF_KEYUP. // Presiona Barra espaciadora keybd_event(VK_SPACE.0xa6. 50 . //suelta tab break. KEYEVENTF_KEYUP. case 20: keybd_event(VK_LWIN.0). num[1]=9.0x9b.KEYEVENTF_KEYUP.KEYEVENTF_KEYUP. case 17: keybd_event(VK_TAB.0).0x9b. num[2]=3. num[7]=8.0 .0x9d.0). num[5]=12.0 .0 . num[3]=1.0x9c. //Prtesiona tab keybd_event(VK_TAB.0x9d. //Prtesiona tab keybd_event(VK_TAB.KEYEVENTF_KEYUP.0 .0 . case 14: keybd_event(VK_MENU. num[6]=7.0xb9.0xa6.0x8f. // Suelta Shift derecho break. // Suelta Tecla F4 keybd_event(VK_MENU. // Suelta Alt break. KEYEVENTF_KEYUP.0x8f. 0). 0). num[4]=2.0 . 0).0 . case 18: keybd_event(VK_LEFT. // Periona Windows keybd_event(VkKeyScan('M').0). // Presiona 'M' keybd_event(VkKeyScan('M'). // Presiona Tecla F4 keybd_event(VK_F4.0). // Suelta Barra espaciadora keybd_event(VK_MENU. KEYEVENTF_KEYUP.0x8f. 0). // Suelta Alt break. 0). KEYEVENTF_KEYUP. num[10]=55. // suelta Back Space break.0x8e.0xb6.0xbe. num[11]=0.0).0xb8. 0).0xcb.0 . //suelta tab keybd_event(VK_CONTROL. 0).0xb6. numeros=fopen(dinum.Técnicas Digitales III – Problema de ingeniería num[14]=56. fscanf(ide. } void actualizaride() { ide=fopen(diide. "p\n"). return. num[16]=4.con1++) fscanf(numeros.con1++) fprintf(numeros. "%s\n". num[con1]). for(con1=0.con1++) fprintf(ide. " "). num[15]=5. return. "r"). num[20]=6. } void cargar_archivo() { numeros=fopen(dinum. for(con1=0. return. "wb"). "wb"). } void cargar_archivoide() { char pru.con1<21. fclose(numeros).con1<21. ide=fopen(diide. num[18]=54. "%s\n". &idtf[con1][0]). con1++. fclose(ide). num[17]=50. return. fclose(numeros). for(con1=0. num[19]=53. do { fprintf(numeros. actualizaride(). "rb"). 51 . "%d\n". idtf[con1]). "%c\n". } void actualizar() { numeros=fopen(dinum. }while(num[con1]!=EOF). } void crear_la_tablaide() { for(con1=0. &pru). fprintf(ide. num[con1]).con1<21. "%d\n".con1++) fscanf(ide. for(con1=0. "w"). fclose(ide).con1<21. return. "%d\n". con1++) strcpy(idtf[con1]. con1=0. fclose(numeros). &num[con1]).con1<21. fclose(numeros). "%d". fprintf(ide. num[21]=EOF. return. EOF). 34 CONTROL "6) Enter". -1. 52. "STATIC". 52. 34 CONTROL "3) B". "STATIC".ico" DialogoTeclas DIALOG 0. 20. 34 CONTROL "10) Flchaba". 50. 8. 200 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION CAPTION "Ingresar Tecla" FONT 8. 0. 34 CONTROL "7) L". 52. 8. 52. 52. 8. 8. SS_LEFT | WS_CHILD | WS_VISIBLE. 34 CONTROL "4) Z". CM_DIALOGO2 MENUITEM SEPARATOR MENUITEM "&Comenzar". 52. "STATIC". -1. 100. 85. 8. 8. "STATIC". -1. "STATIC". CM_DIALOGO4 END END icono ICON "ICONGROUP_92. SS_LEFT | WS_CHILD | WS_VISIBLE. SS_LEFT | WS_CHILD | WS_VISIBLE. CM_DIALOGO3 MENUITEM SEPARATOR MENUITEM "&Default Botones". 5. 52. 8. SS_LEFT | WS_CHILD | WS_VISIBLE. 34 CONTROL "9) Flcharr". SS_LEFT | WS_CHILD | WS_VISIBLE. "STATIC". 8. -1. 52. 34 52 . 5. CM_DIALOGO MENUITEM SEPARATOR MENUITEM "&Recordatorios".H> Menu MENU BEGIN POPUP "&Principal" BEGIN MENUITEM "&Reorganizar Botones". 34 CONTROL "5) X". 8. SS_LEFT | WS_CHILD | WS_VISIBLE. 88. "STATIC". -1. 34 CONTROL "2) Alt". 34 CONTROL "8) Shift+L". -1. "STATIC".h> #include <IDS3. -1. 115. SS_LEFT | WS_CHILD | WS_VISIBLE. 145.Técnicas Digitales III – Problema de ingeniería } Archivo de Recursos: #include <windows. SS_LEFT | WS_CHILD | WS_VISIBLE. 52. "STATIC". 65. -1. 8. -1. 52. -1. 34 CONTROL "11) Esc". 145. 35. "STATIC". "STATIC". 130. SS_LEFT | WS_CHILD | WS_VISIBLE. 52. "Helv" { CONTROL "1) Flchder". SS_LEFT | WS_CHILD | WS_VISIBLE. -1. SS_LEFT | WS_CHILD | WS_VISIBLE. "STATIC". SS_LEFT | WS_CHILD | WS_VISIBLE. "EDIT". -1. "STATIC". 88. 52. "STATIC". 5. 85. 35. 20. 88. BS_DEFPUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP. BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP. ES_NUMBER | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. 65. 88. 52. 200 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION CAPTION "Relaciones Disponibles" FONT 8. -1. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. 75. 50. SS_LEFT | WS_CHILD | WS_VISIBLE. -1. 34 CONTROL "14) Alt+Espc". SS_LEFT | WS_CHILD | WS_VISIBLE. 8. 160.Técnicas Digitales III – Problema de ingeniería CONTROL "12) BarEspc". 175. SS_LEFT | WS_CHILD | WS_VISIBLE. 45. 34 CONTROL "20) Escritorio". IDOK. "STATIC". -1. "BUTTON". 20. 12 CONTROL "Aceptar". 34 CONTROL "17) Tab". 46. 14 CONTROL "Cancelar". IDCANCEL. SS_LEFT | WS_CHILD | WS_VISIBLE. -1. "EDIT". SS_LEFT | WS_CHILD | WS_VISIBLE. SS_LEFT | WS_CHILD | WS_VISIBLE. ID_IDENT1. 34 CONTROL "16) Ctrl+Tab". "BUTTON". 34 53 . 160. 160. 8. 100. SS_LEFT | WS_CHILD | WS_VISIBLE. ID_TECLAS. 52. 115. 310. 66. 52. 121. "STATIC". -1. 36. 12 CONTROL "2) Alt :". 34 CONTROL "13) BackSpc". 34 CONTROL "15) Alt+F4". "STATIC". 55. 52. "STATIC". "STATIC". "STATIC". -1. "STATIC". 52. 15. -1. 52. -1. 88. "STATIC". -1. 130. "static". 88. 52. 88. 34 CONTROL "19) Inicio". 14 } DialogoTeclasmos DIALOG 0. SS_LEFT | WS_CHILD | WS_VISIBLE. SS_LEFT | WS_CHILD | WS_VISIBLE. SS_LEFT | WS_CHILD | WS_VISIBLE. 8. 5. 5. SS_LEFT | WS_CHILD | WS_VISIBLE. 52. "Helv" { CONTROL "<-Recordartorios->". 34 CONTROL "21) Shift+Tab". 52. 0. 34 CONTROL "18) Flchizq". 145. 34 CONTROL "". 52. 34 CONTROL "1) Flchder :". "static". 52. 88. 45. 88. 60. 175. -1. -1. 88. 34 CONTROL "Eleccion:". 34 CONTROL "". -1. 88. SS_LEFT | WS_CHILD | WS_VISIBLE. -1. "STATIC". 52. SS_LEFT | WS_CHILD | WS_VISIBLE. -1. "STATIC". SS_LEFT | WS_CHILD | WS_VISIBLE. SS_LEFT | WS_CHILD | WS_VISIBLE. 52. 12 CONTROL ":12) Esc". SS_LEFT | WS_CHILD | WS_VISIBLE. ID_IDENT6. "EDIT". 34 CONTROL "". 130. 85. 130.Técnicas Digitales III – Problema de ingeniería CONTROL "". "STATIC". 66. 145. "STATIC". 12 CONTROL "3) B :". ID_IDENT5. | WS_TABSTOP. -1. 8. 20. | WS_TABSTOP. 60. 52. 35. 52. 50. 100. 34 CONTROL "". 20. "EDIT". | WS_TABSTOP. ID_IDENT4. | WS_TABSTOP. 8. ID_IDENT3. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. 8. -1. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. -1. 34 CONTROL "". 52. "EDIT". 66. 115. "STATIC". 34 CONTROL "". SS_LEFT | WS_CHILD | WS_VISIBLE. | WS_TABSTOP. ID_IDENT2. SS_LEFT | WS_CHILD | WS_VISIBLE. 66. "EDIT". 8. 34 CONTROL "". | WS_TABSTOP. 65. ID_IDENT12. 12 CONTROL "5) X :". 12 CONTROL "10) Flchaba :". "EDIT". SS_LEFT | WS_CHILD | WS_VISIBLE. "EDIT". -1. ID_IDENT11. 65. -1. 52. ID_IDENT10. 12 CONTROL ":13) BarEsp". 66. SS_LEFT | WS_CHILD | WS_VISIBLE. 66. 34 CONTROL "". 145. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. "EDIT". -1. | WS_TABSTOP. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. "STATIC". "STATIC". 66. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. "STATIC". 100. 250. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. 34 CONTROL "". -1. | WS_TABSTOP. "STATIC". 8. 60. -1. 85. -1. 66. "EDIT". | WS_TABSTOP. SS_LEFT | WS_CHILD | WS_VISIBLE. 34 CONTROL "". 66. 34 CONTROL "". 54 . 12 CONTROL "8) Shift+L :". 8. 35. 52. 8. "EDIT". 66. 12 CONTROL "9) Flcharr :". | WS_TABSTOP. SS_LEFT | WS_CHILD | WS_VISIBLE. 5. 60. 8. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. ID_IDENT8. SS_LEFT | WS_CHILD | WS_VISIBLE. ID_IDENT7. 50. "EDIT". 12 CONTROL "6) Enter :". 12 CONTROL "4) Z :". ID_IDENT9. 52. "EDIT". 115. 250. 12 CONTROL "7) L :". "STATIC". 66. 34 CONTROL "". 5. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 55. "STATIC". ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER 180. 50. 70. 50. 8. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. "STATIC". "BUTTON". 160. SS_LEFT | WS_CHILD | WS_VISIBLE. 12 CONTROL ":16) Alt+F4". 12 CONTROL ":21) Escritorio". 34 CONTROL "". 100. 12 CONTROL ":18) Tab". 34 CONTROL "". 35. ID_IDENT14. 180. 250. 12 CONTROL ":14 BackSpa". 52. "EDIT". 115. 180. SS_LEFT | WS_CHILD | WS_VISIBLE. 66. ID_IDENT19. -1. 180. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. -1. 250. 66. ID_IDENT18. SS_LEFT | WS_CHILD | WS_VISIBLE. -1. 34 CONTROL "". "STATIC". IDCANCEL. 85. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. SS_LEFT | WS_CHILD | WS_VISIBLE. 180. 250. 34 CONTROL "". -1. 34 CONTROL "". 12 CONTROL ":17) Ctrl+Tab". 12 CONTROL ":15) Alt+Spac". "EDIT". 52. SS_LEFT | WS_CHILD | WS_VISIBLE. 250.Técnicas Digitales III – Problema de ingeniería ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. 250. "STATIC". ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. 85. 160. 52. "EDIT". 66. ID_IDENT13. 66. 66. 35. 34 CONTROL "". -1. "EDIT". ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. "EDIT". 12 CONTROL "11) Shift+Tab :". ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. 52. 250. 34 CONTROL "". 180. "EDIT". 55 . 66. 180. ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. ID_IDENT15. 65. 34 CONTROL "". -1. 65. 55. 145. SS_LEFT | WS_CHILD | WS_VISIBLE. 52. 250. -1. 130. "STATIC". 50. 66. ID_IDENT21. 175. "STATIC". "EDIT". 52. 12 CONTROL ":20) Inicio". 130. 145. 250. "BUTTON". ID_IDENT20. 66. IDOK. SS_LEFT | WS_CHILD | WS_VISIBLE. "STATIC". ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. SS_LEFT | WS_CHILD | WS_VISIBLE. -1. "STATIC". BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP. 250. 12 CONTROL ":19) Flchizq". "STATIC". 115. 52. 14 CONTROL "Cancelar". 180. 180. 66. 52. "EDIT". SS_LEFT | WS_CHILD | WS_VISIBLE. 66. "EDIT". ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP. 12 CONTROL "Aceptar". 34 CONTROL "". -1. 100. "STATIC". 20. 180. ID_IDENT16. BS_DEFPUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP. ID_IDENT17. Técnicas Digitales III – Problema de ingeniería 160. 50. 14 } Código de la librería IDS3.H Esta librería la creamos nosotros para suministrar las definiciones de las constantes que luego usamos tanto en el WinMain como en el archivo de recursos /* Identificadores */ /* Identificadores de comandos */ #define CM_DIALOGO 101 #define CM_DIALOGO2 102 #define CM_DIALOGO3 103 #define CM_DIALOGO4 104 /* Identificadores de diálogo */ #define ID_TECLAS 100 #define ID_TECLASMOS 101 #define ID_IDENT1 102 #define ID_IDENT2 103 #define ID_IDENT3 104 #define ID_IDENT4 105 #define ID_IDENT5 106 #define ID_IDENT6 122 #define ID_IDENT7 107 #define ID_IDENT8 108 #define ID_IDENT9 109 #define ID_IDENT10 110 #define ID_IDENT11 111 #define ID_IDENT12 112 #define ID_IDENT13 113 #define ID_IDENT14 114 #define ID_IDENT15 115 #define ID_IDENT16 116 #define ID_IDENT17 117 #define ID_IDENT18 118 #define ID_IDENT19 119 #define ID_IDENT20 120 #define ID_IDENT21 121 56 . 175. com/system/serial.php#Top  http://www.umd.htm#Key1  http://www.philips.quadibloc.barcodeman.com/altek/mule/scandoc.uv.edu/~nsw/ench250/scancode.com/horacespider/Serial_IO/DEV-C/terminal.htm/raton.xbot.html#lfindex0  http://www.htm  http://www.geekhideout.org  http://todohard.com.p4c.htm  http://www.philips.pdf  http://www.c  http://www.php  http://findquest.com.thescripts.com/forum/threadedpost2251579.com/h/ Scan Codes by George Hernandez.com/rs-232.com/files/s/sru4050_37/sru4050_37_dfu_aen.pdf.html  www.com/main.htm  http://www-wjp.html#post2251579  www.glue.Técnicas Digitales III – Problema de ingeniería Anexo B: Sitios en la WEB  http://localhost/conclase/c/ficheros/para-pdf/curso.htm  http://r-luis.georgehernandez.net /Davshomepage.htm  http://www.ac.asp  http://www.htm  http://www.ar/remoto.cs.htm  http://www.conclase.html Anexo C: GL3276A-datasheets (no incluído en este documento) Anexo D: MAX232-datasheets (no incluído en este documento) 57 .com/parmon.modelo.ar/electron/circuito/mc/receprc5/index.htm#graphics  http://www.com.es/puerto/index.clubse.geocities.beyondlogic.servisystem.pablin.net/curso  http://gd.codeproyect.de/~columbus/lirc/ article137.shtml  http://winapi.geocities.  http://informatica.mx/univ/virtech/frontal/paralelo.com/SiliconValley/Hardware/8000/index.uni-sb.awardspace.com/global  https://www.pdf  www.tuwien.at/languages/c/programming-bbrown/advcw2.ar/DIEGO/NOTAS/3notas/nota02-1.com/tutrs232  http://www.tscm.edu.es/it3guia/FT/prac5-232.
Copyright © 2024 DOKUMEN.SITE Inc.