Control remoto - Facultad Regional San Nicolás

Anuncio
UNIVERSIDAD TECNOLOGICA NACIONAL
FACULTAD 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
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), de hecho este es el
principal factor que determina el encapsulado de los chips: un plástico completamente opaco,
normalmente negro. 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).
Un sensor de infrarrojos construido de esa forma será capaz de detectar la presencia de cualquier luz
infrarroja, independientemente de la fuente que la genere. 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. La señal emitida por un mando está modulada a
una frecuencia entre 32 y 40 KHz, 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, luego durante la recepción se
tendrá que deshacer. Si se emite luz infrarroja, luego se tendrá que recibir; si esta señal se modula con
una portadora luego se tendrá que eliminar (filtrar) esa portadora. 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.
6
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.
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).
Al modular una señal desplazamos su contenido espectral en frecuencia, ocupando un cierto ancho de
banda alrededor de la frecuencia de la onda portadora (f0). 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.
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). Ahora queda por
determinar cómo se transmite la información, esto es, los bits que identifican la tecla del mando a
distancia que se ha pulsado, pero esto se detallara en el apartado del protocolo RC-05.
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). 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.
 Frecuencia de portadora (demodulación) preselecionable mediante resistencia instalada en el
pin f0 en un rango de 30 a 80 KHz. Margen de variación de f0 reducido.
 Pocos elementos externos necesarios. Resistencias de pull-ups y filtros internas. Capacitores
externos de capacidades bajas.
 Salida a colector abierto con resistencia de pull-up.
7
Técnicas Digitales III – Problema de ingeniería
Este es un circuito integrado analógico diseñado especialmente para este tipo de aplicaciones, 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.
Como veremos a este se acopla directamente el photodiodo receptor y un conjunto mínimo de
componentes de seteo y demás. Como se muestra en su diagrama de bloques consta en una primera
instancia de un amplificador de entada, seguido de u limitador, un filtro pasa banda, un circuito
detector y un acondicionador de forma de onda que va directo a la etapa de salida a colector abierto.
El valor de R(f0) lo encontramos mediante las curvas aportadas por el fabricante del circuito integrado.
Para 36 KHz seria al rededor de 156 KΩ.
8
Técnicas Digitales III – Problema de ingeniería
PROTOCOLO DE PHILIPS RC-05
Es evidente, dada la forma de modular la señal, que la información se transmite en serie, esto es, un bit
detrás de otro, y por tanto sólo es necesario una línea (de datos) para recibirla. Descubramos un poco
que es y como esta hecho el protocolo de Philips.
El código RC-05 de Philips es, posiblemente, el protocolo más utilizado por los experimentadores,
debido a la amplia disponibilidad de controles remotos baratos que se basan en él.
Además, dentro de este protocolo hay comandos predefinidos para distintos artefactos, una
característica que aporta una mayor compatibilidad al utilizarlo con muchos equipos hogareños.
Philips ha comenzado a utilizar un nuevo protocolo, el RC-06, que tiene más capacidades.
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, también llamada código Manchester)
Frecuencia de portadora de 36 KHz.
Tiempo de bit constante de 1,778 ms (64 ciclos de 36 KHz.)
Modulación
El protocolo está basado en una modulación Manchester de doble fase sobre una portadora de 36 KHz.
En esta codificación, todos los bits tienen la misma longitud, de 1,778 ms. La mitad del bit es un tren
de pulsos de la portadora de 36 KHz., y en la otra mitad la señal está plana.
El cero lógico es representado por un tren de pulsos en la primera mitad (primer nible) del tiempo que
corresponde al bit. El uno lógico es representado por un tren de pulsos en la segunda mitad de este
tiempo. La relación entre pulso y pausa en la portadora de 36 KHz. es de 1/3 o 1/4, lo que reduce el
consumo de energía.
Protocolo
La imagen muestra un típico tren de pulsos en un mensaje RC-05. En este ejemplo se transmite la
dirección $05 y el comando $35.
Los dos primeros bits son los de inicio (start), que deben ser dos "1" lógicos. Nótese que transcurre
medio tiempo de bit hasta que el receptor se entera de que ha comenzado el mensaje.
9
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. El tercer bit del protocolo
RC-05, marcado como “T” en el dibujo, es el bit de conmutación (toggle). 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.
De esta manera el receptor puede distinguir entre una tecla que permanece presionada (mientras lo
esté, el comando que le corresponde se repite indefinidamente en la señal) y una misma tecla a la que
se la presiona varias veces. 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. Ya que
hacemos esto, no es necesario pasarle a la PC toda la cadena, basta con que le pasemos el dato de
comando para que la PC ejecute una tarea respectiva. 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. En la cadena que le pasamos a la PC haremos que,
ya que nos sobran dos bis para completar el byte (6 bits de comando), 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.
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, obviamente, para quien es el mensaje), poniendo en
primer lugar el bit más significativo de la dirección. A esta dirección le sigue el comando de 6 bits,
también con su bit más significativo en primer lugar.
Un mensaje, entonces, consiste de un total de 14 bits, que sumados dan una duración total del mensaje
de 25 ms. A veces puede parecer que un mensaje es más corto debido a que la primera parte del bit de
inicio S1 es inactiva.
Mientras se mantenga presionada la tecla, el mensaje se repite cada 114 ms. El bit de conmutación
mantendrá el mismo nivel lógico durante la repetición de un mensaje.
Comandos predefinidos
Philips ha creado una lista de comandos estandarizados. 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í, enfrente del control remoto.
Una característica interesante es que la mayoría de los artefactos están representados dos veces, lo que
permitiría tener dos videocaseteras juntas sin tener problemas para comandarlas por separado.
10
Técnicas Digitales III – Problema de ingeniería
La lista que sigue no es exhaustiva.
Dirección
RC-5
Dispositivo
Comando
RC-5
Comando TV
Comando VCR
$00 - 0
TV1
$00 - 0
0
0
$01 - 1
TV2
$01 - 1
1
1
$02 - 2
Teletexto
$02 - 2
2
2
$03 - 3
Video
$03 - 3
3
3
$04 - 4
LV1
$04 - 4
4
4
$05 - 5
VCR1
$05 - 5
5
5
$06 - 6
VCR2
$06 - 6
6
6
$07 - 7
Experimental
$07 - 7
7
7
$08 - 8
Sat1
$08 - 8
8
8
$09 - 9
Cámara
$09 - 9
9
9
$0A - 10
Sat2
$0A - 10
-/--
-/--
$0C - 12
Espera
Espera
$0B - 11
$0C - 12
CDV
$0D - 13
Silenciar
$0D - 13
Camcorder
$10 - 16
Volumen +
$0E - 14
$11 - 17
Volumen -
$0F - 15
$12 - 18
Brillo +
$10 - 16
Preamplificador
$13 - 19
Brillo -
$11 - 17
Sintonizador
$20 - 32
Programa +
Programa +
$12 - 18
Grabador1
$21 - 33
Programa -
Programa -
$13 - 19
Preamplificador
$32 - 50
Retroceso rápido
$14 - 20
Reproductor CD
$34 - 52
Retroceso rápido
$15 - 21
Teléfono
$35 - 53
Reproducir
$16 - 22
SatA
$36 - 54
Detener
$17 - 23
Grabador2
$37 - 55
Grabar
$18 - 24
$19 - 25
$1A - 26
CDR
$1B - 27
$1C - 28
$1D - 29
Iluminación
$1E - 30
Iluminación
$1F - 31
Teléfono
11
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, en definitiva, el mayor rango de
interacción con la PC. 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, los podemos comprobar y lo
hicimos mediante el ordenador. 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).
Esta es una asignación por defecto para controlar el programa WINAMP (configuración de teclado
por defecto, del programa) de reproducción de archivos multimedia y además nos permitirá interactuar
en lo que a las principales funciones respecta, con el sistema operativo Windows.
12
Técnicas Digitales III – Problema de ingeniería
Para la configuración del control remoto:
 Elegir dispositivo (uno de cuatro los botones superiores), en nuestro caso VCR.
 Mantener presionado los botones “numero 1” y “numero 3”, destello de led indicador de envío
dos veces.
 Ingresar el código correspondiente al protocolo que el control remoto debe emitir, para nuestro
caso es “033”, destello de led indicador de envío una vez.
Ahora tenemos el mando a distancia configurado para emitir en protocolo RC-05X en modo VCR.
ESTANDAR RS- 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, o no es posible conseguirla (por ejemplo, vía red telefónica).
Para simplificar el proceso de enviar los bits uno por uno han surgido circuitos integrados que realizan
la función, teniendo en cuenta todos los tiempos necesarios para lograr una correcta comunicación y
aliviando a la CPU de esta pesada tarea. El circuito que estudiado es el 8250 de National, fabricado
también por Intel, aunque existen diferencias respecto al 16550.
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, en particular en las actuales placas base.
13
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,
se envía un bit a 0 ó bit de inicio. Tras él irán los 8 bits de datos a transmitir (en ocasiones son 7, 6
ó 5): estos bits están espaciados con un intervalo temporal fijo y preciso, ligado a la velocidad de
transmisión que se esté empleando, en nuestro caso es de 9600 baudios. Tras ellos podría venir o no un
bit de paridad generado automáticamente por la UART. Al final, aparecerá un bit (a veces un bit y
medio ó dos bits) a 1, que son los bits de parada o bits de stop.
Lo de medio bit significa que la señal correspondiente en el tiempo a un bit dura la mitad. La presencia
de bits de arranque y paro permite sincronizar la estación emisora con la receptora, haciendo que los
relojes de ambas vayan a la par. A la hora de transmitir los bits de datos unos tras otros, 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.
El ACE 8250 (Asynchronous Communication Element) integra en un solo chip una UART (Universal
Asynchronous Receiver/Transmitter) y un BRG (Baud Rate Generator). Soporta velocidades de hasta
625000 baudios con relojes de hasta 10 MHz. El BRG incorporado divide la frecuencia base para
conseguir las velocidades estándar de la RS-232. Para llevar a cabo ala comunicación el integrado
consta de varios registros en los que se aloja bandera de estado, configuración de línea y modem.
También están los registros buffer en los que se encuentran los datos recibidos, los datos a enviar, el
registro de salida secuencial bit a bit e ídem para la entrada.
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.
 Un “0” lógico es un voltaje comprendido entre +5v y +15v en el trasmisor y entre +3v y +25 v
en el receptor.
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. El MAX 232 necesita
solamente una fuente de +5V para su operación, internamente tiene un elevador de voltaje que
convierte el voltaje de +5V al de doble polaridad de +12V y
-12V. Cabe mencionar que
existen una gran variedad de CI que cumplen con la norma RS-232 como lo son: MAX220,
DS14C232, MAX233, LT1180A.
14
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. Si bien conseguimos la comunicación, el dato transmitido era
muy distante del que realmente queríamos enviar. Al observar el comportamiento del amplificador
operacional configurado de esa manera con un osciloscopio, al atravesarlo un dato a transmitir,
pudimos ver que la salida no podía acompañar a la entrada en tiempo y forma. Así que intentamos
resolver el problema bajando la velocidad de transmisión, ya teníamos el hardware armado.
Conseguimos una leve mejora a 330 baudios, así que debíamos intentar configurar el operacional
como amplificador inverso de alguna manera. Como fuese, había que modificar el hardware y a su vez
ya nos habíamos enterado de MAX232, así que para evitar mayores perdidas de tiempo nos inclinamos
a la implementación de integrado, y problema resuelto. Además el otro método, por supuesto nos
demandaba una fuente bipolar.
15
Técnicas Digitales III – Problema de ingeniería
RECEPTOR
E sistema de recepción esta compuesto por un hardware de detección-decodificación, integrado por un
microcontrolador PIC16F84A, y la PC para la ejecución de una tarea determinada.
En el circuito de detección-decodificación, el PIC16F84A, 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, 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. Para logra el
cometido anterior, entre el PIC16F84A se instala un driver adaptador de nivel de señal MAX232. 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.
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), y en el código
fuente del programa que correrá en el ordenador (ver código en PC).
Este es un esquemático del hardware de detección-decodificación:
16
Técnicas Digitales III – Problema de ingeniería
Es un circuito muy sencillo:
 Led “PWR”: se enciende al alimentar el circuito.
 Led “Led V”: emite un destello por cada dato enviado a la PC, permanece encendido durante
un segundo, aproximadamente (simultáneamente con “Led R”) de no poder concretar la
comunicación. De presionar el pulsador “Borrar disp.” 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.
 Led “Led R”: al encender el receptor, este no esta vinculado a ningún dispositivo (TV, etc.…)
entonces esta situación se ve indicada por la permanencia de este led encendido. La situación se
revierte al enviarle algún mensaje desde el control remoto (presionando cualquier tecla del
control). A partir de entonces el receptor solo reconocerá mensajes provenientes de ese mando
a distancia y con ese código de dispositivo. Si se quiere cambiar el código de dispositivo de
reconocimiento por cualquier razón, el receptor consta de un pulsador “Borrar disp.” 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.
 Pulsador “Borrar disp.”: 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), se encenderá
entonces el “Led R”. Si el pulsador se presiona durante un tiempo prolongado el receptor,
además de desvincular el mendo a distancia, cambia su modo de transmisión de datos a la PC,
si estaba transmitiendo en serie lo hará en paralelo entonces (enciende por un segundo dos
veces “Led V”), y viceversa (enciende por un segundo una vez “Led V”).
Nota: para que el hardware pueda comunicarse con el ordenador mediante el puerto paralelo, se debe
quita el buffer MAX232 lo cual se puede llevar a cabo interponiendo un conector entre este y la
electrónica principal. En este conector también se debe conectar el adaptador de conexiones para
efectuar la comunicación vía puerto paralelo.
Esta comunicación envía el dato en dos partes como puede verse en el código fuente del PIC16F84A.
En una primera instancia se envían los cuatro bits más significativos, se espera un determinado tiempo
17
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.
Esto es así para aprovechar mejor y de manera más simple las características del puerto según nuestras
necesidades.
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, inclusive, hasta el pin 25, también inclusive, sirven de masa.
EL controlador de la comunicación consta de tres registros de 8 bit cada uno (un byte). El registro
PORT 888, puerto de datos, (dirección en memoria 888), Pines del 2 al 9, es de solo escritura, por este
registro se envían los datos al exterior de la PC. El registro PORT 889, puerto de estado, es de solo
lectura, por aquí se enviaremos señales eléctricas al ordenador, de este registro solo se utilizan los
cinco bits de más peso, que son el bit 7, 6, 5, 4 y 3 teniendo en cuenta que el bit 7 funciona en modo
invertido, pines 15, 13, 12, 10 y 11. El registro PORT 890, puerto de control, es de lectura/escritura, es
decir, podremos enviar o recibir señales eléctricas, según nuestras necesidades. De los 8 bits de este
registro solo se utilizan los cuatro de menor peso o sea el 0, 1, 2 y 3, con un pequeño detalle, los bits 0,
1, y 3 están invertidos.
Adaptación:
Para enviar el dato a la PC utilizamos del puerto de estado los pines 10, 12, 13, y 15 (E6, E5, E4 y E3
respectivamente). Para la confirmación la esperamos por el puerto de datos, pin 2 (D0). La conexión
cableada deberá hacerse como se indica a continuación:
18
Técnicas Digitales III – Problema de ingeniería
EL CODIGO FUENTE DEL PIC16F84A
Este código fuente debe encargarse de las tareas descriptas antes. 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.
Para entender más fácilmente el código se muestra el siguiente diagrama de bloque del algoritmo.
19
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, el MPLAB 9.0 IDE. Para la programación o grabado del código en la
memoria del PIC16F84A se uso otro programa de distribución libre y gratuita, el IC-Prog. Para esta
ultima tarea también se hizo uso de una tarjeta de programación llamada ProPic 2 Programer. (Ver
código fuente para PIC16F84A en Anexo C).
ESTRUCTURA DE UN PROGRAMA WINDOWS GUI
Para el desarrollo de este código fuente se utilizo un entorno de desarrollo integrado también. Se
utilizo Dev-C 4.9, un producto de Bloodshed y se programo WIN API (Appication Programming
Interface) con clases.
Los programas Windows son independientes de la máquina en la que se ejecutan (o al menos deberían
serlo), 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
directamente a ellos. Esta es una de las principales ventajas para el programador, ya que no hay que
preocuparse por el modelo de tarjeta gráfica o de impresora, la aplicación funcionará con todas, y será
el sistema operativo el que se encargue de que así sea.
Un concepto importante es el de recurso. Desde el punto de vista de Windows, un recurso es todo
aquello que puede ser usado por una o varias aplicaciones. Existen recursos físicos, que son los
dispositivos que componen el ordenador, como la memoria, la impresora, el teclado o el ratón y
recursos virtuales o lógicos, como los gráficos, los iconos o las cadenas de caracteres, etc. Por ejemplo,
si nuestra aplicación requiere el uso de un puerto serie, primero debe averiguar si está disponible, es
decir, si existe y si no lo está usando otra aplicación; y después lo reservará para su uso. Esto es
necesario porque este tipo de recurso no puede ser compartido.
Los programas en Windows están orientados a eventos, esto significa que normalmente los programas
están esperando a que se produzca un acontecimiento que les incumba, y mientras tanto permanecen
aletargados o dormidos.
Un evento puede ser por ejemplo, el movimiento del ratón, la activación de un menú, la llegada de
información desde el puerto serie, una pulsación de una tecla...
Esto es así porque Windows es un sistema operativo multitarea, y el tiempo del microprocesador ha de
repartirse entre todos los programas que se estén ejecutando. Si los programas fueran secuenciales
puros, esto no sería posible, ya que hasta que una aplicación finalizara, el sistema no podría atender al
resto.
Ejemplo de programa secuencial:
Ejemplo de programa por eventos:
21
Técnicas Digitales III – Problema de ingeniería
Hay algunas diferencias entre la estructura de un programa C/C++ normal, y la correspondiente a un
programa Windows GUI. Algunas de estas diferencias se deben a que los programas GUI estás
basados en mensajes, otros son sencillamente debidos a que siempre hay un determinado número de
tareas que hay que realizar.
// Ficheros include:
#include <windows.h>
// Prototipos:
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
// Función de entrada:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow)
{
// Declaración:
// Inicialización:
// Bucle de mensajes:
return Message.wParam;
}
// Definición de
La función de entrada de un programa Windows es "WinMain", en lugar de la conocida "main".
Normalmente, la definición de esta función cambia muy poco de una aplicación a otra. Se divide en
tres partes claramente diferenciadas: declaración, inicialización y bucle de mensajes.
Parámetros de entrada de "WinMain"
int WINAPI WinMain(HINSTANCE
lpszCmdParam, int nCmdShow)
hInstance,
HINSTANCE
hPrevInstance,
LPSTR
La función WinMain tiene cuatro parámetros de entrada:
 hInstance es un manipulador para la instancia del programa que estamos ejecutando. Cada vez
que se ejecuta una aplicación, Windows crea una Instancia para ella, y le pasa un manipulador
de dicha instancia a la aplicación.
hPrevInstance es un manipulador a instancias previas de la misma aplicación. Como Windows es
multitarea, pueden existir varias versiones de la misma aplicación ejecutándose, varias instancias.
En Windows 3.1, este parámetro nos servía para saber si nuestra aplicación ya se estaba
ejecutando, y de ese modo se podían compartir los datos comunes a todas las instancias. Pero eso
era antes, ya que en Win32 usa un segmento distinto para cada instancia y este parámetro es
siempre NULL, sólo se conserva por motivos de compatibilidad.
lpszCmdParam, esta cadena contiene los argumentos de entrada del comando de línea.
22
Técnicas Digitales III – Problema de ingeniería
nCmdShow, este parámetro especifica cómo se mostrará la ventana. Para ver sus posibles valores
consultar valores de ncmdshow. Se recomienda no usar este parámetro en la función ShowWindow
la primera vez que se ésta es llamada. En su lugar debe usarse el valor SW_SHOWDEFAULT.
Función WinMain típica
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
/* Declaración: */
HWND hwnd;
MSG mensaje;
WNDCLASSEX wincl;
/* Inicialización: */
/* Estructura de la ventana */
wincl.hInstance = hInstance;
wincl.lpszClassName = "NUESTRA_CLASE";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
/* Usar icono y puntero por defecto */
wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
/* Registrar la clase de ventana, si falla, salir del programa */
if(!RegisterClassEx(&wincl)) return 0;
hwnd = CreateWindowEx(
0,
"NUESTRA_CLASE",
"Ejemplo 001",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
544,
375,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);
23
Técnicas Digitales III – Problema de ingeniería
ShowWindow(hwnd, SW_SHOWDEFAULT);
/* Bucle de mensajes: */
while(TRUE == GetMessage(&mensaje, 0, 0, 0))
{
TranslateMessage(&mensaje);
DispatchMessage(&mensaje);
}
return mensaje.wParam;
}
Declaración
En la primera zona declararemos las variables que necesitamos para nuestra función WinMain, que
como mínimo serán tres:
HWND hWnd, un manipulador para la ventana principal de la aplicación. Ya sabemos que nuestra
aplicación necesitará al menos una ventana.
MSG Message, una variable para manipular los mensajes que lleguen a nuestra aplicación.
WNDCLASSEX wincl, una estructura que se usará para registrar la clase particular de ventana que
usaremos en nuestra aplicación. Existe otra estructura para registrar clases que se usaba
antiguamente, pero que ha sido desplazada por esta nueva versión, se trata de WNDCLASS.
Inicialización
Esta zona se encarga de registrar la clase o clases de ventana, crear la ventana y visualizarla en
pantalla.
Para registrar la clase primero hay que rellenar adecuadamente la estructura WNDCLASSEX, que
define algunas características que serán comunes a todas las ventanas de una misma clase, como color
de fondo, icono, menú por defecto, el procedimiento de ventana, etc. Después hay que llamar a la
función RegisterClassEx.
En el caso de usar una estructura WNDCLASS se debe registrar la clase usando la función
RegisterClass.
A continuación se crea la ventana usando la función CreateWindowEx, la función CreateWindow ha
caído prácticamente en desuso. Cualquiera de estas dos funciones nos devuelve un manipulador de
ventana que podemos necesitar en otras funciones, sin ir más lejos, la siguiente.
Pero esto no muestra la ventana en la pantalla. Para que la ventana sea visible hay que llamar a la
función ShowWindow. La primera vez que se llama a ésta función, después de crear la ventana, se
puede usar el parámetro nCmdShow de WinMain como parámetro o mejor aún, como se recomienda
por Windows, el valor SW_SHOWDEFAULT.
24
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, 0, 0, 0)) {
TranslateMessage(&mensaje);
DispatchMessage(&mensaje);
}
Este es el bucle de mensajes recomendable, aunque no sea el que se usa habitualmente. La razón es
que la función GetMessage puede retornar tres valores: TRUE, FALSE ó -1. El valor -1 indica un
error, así que en este caso se debería abandonar el bucle.
El bucle de mensajes que encontraremos habitualmente es este:
while(GetMessage(&mensajee, 0, 0, 0)) {
TranslateMessage(&mensaje);
DispatchMessage(&mensaje);
}
NOTA: El problema con este bucle es que si GetMessage regresa con un valor -1, que indica un error,
la condición del "while" se considera verdadera, y el bucle continúa. Si el error es permanente, el
programa jamás terminará.
La función TranslateMessage se usa para traducir los mensajes de teclas virtuales a mensajes de
carácter.
Los mensajes traducidos se reenvían a la lista de mensajes del proceso, y se recuperarán con las
siguientes llamadas a GetMessage.
La función DispatchMessage envía el mensaje al procedimiento de ventana, donde será tratado
adecuadamente.
El procedimiento de ventana
Cada ventana tiene una función asociada, esta función se conoce como procedimiento de ventana, y es
la encargada de procesar adecuadamente todos los mensajes enviados a una determinada clase de
ventana. Es la responsable de todo lo relativo al aspecto y al comportamiento de una ventana.
Normalmente, estas funciones están basadas en una estructura "switch" donde cada "case"
corresponde aun determinado tipo de mensaje.
Sintaxis
LRESULT CALLBACK WindowProcedure(
25
Técnicas Digitales III – Problema de ingeniería
HWND hwnd, // Manipulador de ventana
UINT msg,
// Mensaje
WPARAM wParam, // Parámetro palabra, varía
LPARAM lParam // Parámetro doble palabra, varía
);




hwnd es el manipulador de la ventana a la que está destinado el mensaje.
msg es el código del mensaje.
wParam es el parámetro de tipo palabra asociado al mensaje.
lParam es el parámetro de tipo doble palabra asociado al mensaje.
Podemos considerar este prototipo como una plantilla para crear nuestros propios procedimientos de
ventana. El nombre de la función puede cambiar, pero el valor de retorno y los parámetros deben ser
los mismos. El miembro lpfnWndProc de la estructura WNDCLASS es un puntero a una función de
este tipo, esa función es la que se encargará de procesar todos los mensajes para esa clase de ventana.
Cuando registremos nuestra clase de ventana, tendremos que asignar a ese miembro el puntero a
nuestro procedimiento de ventana.
Prototipo de procedimiento de ventana
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
Implementación del procedimiento de ventana simple
/* Esta función es llamada por la función del API DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
switch (msg)
/* manipulador del mensaje */
{
case WM_DESTROY:
PostQuitMessage(0); /* envía un mensaje WM_QUIT a la cola de mensajes */
break;
default:
/* para los mensajes de los que no nos ocupamos */
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
En general, habrá tantos procedimientos de ventana como programas diferentes y todos serán distintos,
pero también tendrán algo en común: todos ellos procesarán los mensajes que lleguen a una clase de
ventana.
En este ejemplo sólo procesamos un tipo de mensaje, se trata de WM_DESTROY que es el mensaje
que se envía a una ventana cuando se recibe un comando de cerrar, ya sea por menú o mediante el
icono de aspa en la esquina superior derecha de la ventana.
26
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, y le da una oportunidad de dejar las cosas en su sitio: cerrar ficheros, liberar memoria,
guardar variables, etc. Incluso, la aplicación puede decidir que aún no es el momento adecuado para
abandonar la aplicación. En el caso del ejemplo, efectivamente cierra la aplicación, y lo hace
enviándole un mensaje WM_QUIT, mediante la función PostQuitMessage.
El resto de los mensajes se procesan en el caso "default", y simplemente se cede su tratamiento a la
función del API que hace el proceso por defecto para cada mensaje, DefWindowProc.
Este es el camino que sigue el mensaje WM_QUIT cuando llega, ya que el proceso por defecto para
este mensaje es cerrar la aplicación.
A grandes rasgos, básicamente, ya sabemos hacer el esqueleto de una aplicación de Windows. Para
entender el resto del código que se presenta a continuación se pide al lector remitirse a la bibliografía.
(ver código fuente para la PC en Anexo C).
RESULTADOS DE LAS PRUEBAS
Las pruebas fueron satisfactorias. Hubo que realizar algunas modificaciones antes de alcanzar el
material o información expuesta en este informe. 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. 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”. 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. Cuando la PC recibe este
dato, el programa nos devuelve un mensaje de código guardado. En este ejemplo se selecciona la
opción 2 (Alt).
27
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.
28
Técnicas Digitales III – Problema de ingeniería
El ítem “Default”, 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.
Por ultimo, el ítem “Comenzar” provoca que el programa se disponga a “vigilar” el puerto serie en
espera por la entrada de cada nuevo comando.
CONCLUSIONES
Durante la realización del proyecto el grupo tuvo que enfrentarse a muchísimos problemas, algunos
comentados en este informe.
Tuvimos muchísimos problemas, en un principio con la comunicación por el puerto serie. En primer
lugar era tema de total desconocimiento para todos nosotros, así mismo con la comunicación por
puerto paralelo, la cual la aprendimos por necesidad para poder solucionar el problema de no
funcionamiento del puerto serie. Por suerte justo antes de hacer la implementación, de dicha
comunicación, en el código fuente de la PC, probamos por última vez con el puerto serie y nos anduvo.
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).
En cuanto a la programación en entorno Windows tuvimos que leer muchísimo para así a duras penas
poder hacer algo.
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, no
podíamos de ninguna manera simular el teclado. Entonces ya con medio proyecto realizado tuvimos
que echarnos atrás, desistir del Borland C++ y utilizar las API de Windows.
29
Técnicas Digitales III – Problema de ingeniería
Código en Borland:
#include
#include
#include
#include
<dos.h>
<conio.h>
<stdio.h>
<stdlib.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, base, dll, dlm, entrada, lsr, lcr, mcr, msr, divisor, con=0;
char opc='z',c='z';
void impcart(void);
void error(void);
void correr(void);
void ventana(void);
void transdat(void);
void main()
{
com=1;
princ:
clrscr();
impcart();
printf("\n\r1:Eleccion de puerto serie\n\r2:Correr
programa\n\r3:Salir\n\rOpcion: ");
opc=getch();
switch (opc)
{
case '1':
{
sound(1250);
delay(250);
nosound();
ventana();
scanf ("%d", &com);
sound(1250);
delay(225);
nosound();
delay(100);
sound(1250);
delay(225);
nosound();
} break;
case '2':
{
sound(1250);
delay(225);
30
Técnicas Digitales III – Problema de ingeniería
nosound();
delay(100);
sound(1250);
delay(225);
nosound();
correr();
}
break;
}
if(opc=='3');
else
goto princ;
}
void correr()
{
clrscr();
impcart();
base=peek(0x40, (com-1)*2);
if (base==0)
{
error();
goto finc;
}
divisor=115200/8300; //para 9600 baudios
outportb (LCR, 0x83); /* DLAB=1, 8 bits, 1 stop, sin paridad */
outportb (IER, 0);
outportb (DLL, divisor%256); //resto de la division por 256
outportb (DLM, divisor/256); //parte entera de la division por 256
dll=inportb(DLL);
dlm=inportb(DLM);
outportb (LCR, 0x03); /* DLAB=0, 8 bits, 1 stop, sin paridad */
corr:
outportb (MCR, 1);
//limpio el control de modem
do
{
lsr=inportb(LSR);
msr=inportb(MSR);
if(lsr & DR)
outportb(MCR, 0);
/*
if (lsr & (PE|FE|BI))
{
error();
goto corr;
}*/
}while(!(lsr & DR) && !kbhit());
entrada=inportb(RBR);
if(kbhit())
c=getche();
if(c=='e')
goto finc;
clrscr();
printf("dato: %d", entrada);
transdat();
goto corr;
finc:
c='z';
return;
}
void error()
{
31
Técnicas Digitales III – Problema de ingeniería
gotoxy(23,11);
textcolor(6);
textbackground(4);
cprintf("
error en la comunicacion
textcolor(7);
textbackground(0);
getch();
return;
}
void impcart()
{
gotoxy(23,1);
textcolor(4);
textbackground(3);
cprintf("
control remoto IR
textcolor(7);
textbackground(0);
return;
}
void ventana()
{
gotoxy(23,11);
textcolor(1);
textbackground(3);
cprintf("
ingrese el puerto preferido:
textcolor(7);
textbackground(0);
return;
}
void transdat()
{
FILE *archi;
archi=fopen("trans.txt", "w");
fprintf(archi, "%d", entrada);
fclose(archi);
return;
}
");
\n");
");
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. Si
bien esta técnica presenta muchos problemas de errores conceptuales, conseguíamos una mínima
interacción entre el control remoto y la PC.
El grupo entero considera un enriquecimiento muy importante de conocimientos, aprendimos mucho
acerca de Windows como sistema operativo y de la PC como sistema eléctrico.
También consideramos haber aprendido mucho de cómo es que se encara un trabajo particular a nivel
profesional.
Agradecemos la interacción constante por parte de los profesores entrevistados, agradecemos toda su
paciencia y participación para con los alumnos y los problemas con los que nos enfrentamos…
Gracias Ramiro…
32
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,0
pub,1
pub,2
pub,3
pub,4
pub,5
pub,6
pub,7
pua,0
pua,2
aux,0
aux,1
aux,2
aux,3
aux,4
aux,5
aux,6
aux,7
inte,2
inte,4
inte,5
inte,7
inte,1
esta,0
esta,2
33
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, 5
b'10001111'
copub
b'11111010'
copua
opci
;iterrupcion por flanco
;desendente
opci,7
esta, 5
pua
ledr
pub
dsr
rxd
inte
aux
disp
h'ff'
disp
disp1
byte
cbyte
b'10010000'
inte
;habilita IR rcecptor
btfss
goto
bot
esper
movlw
movwf
d'33'
cont1
movlw
movwf
d'255'
cont2
decfsz
goto
decfsz
goto
btfss
goto
cont2,1
con2
cont1,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
ledv
retalar
ledv
tsp
esper
retalar
ledv
inicio
esper
con1
con2
;para retardo del pulsador
;la cantidad de pulsos de 1us
; para un reloj de 4 Mhz son:
;1
;1
;
;1*k
;1*k
;
;255*k+k=256*k
;2*255*k=510*k
;k+1
;2*k
;**************
;771*k+3=>si 771*k+3=20 ms/1
;us=25000=>k=32.42~33
34
Técnicas Digitales III – Problema de ingeniería
call
retalar
bcf
ledv
goto
esper
;******************************************************
ledat
bsf
esta,5
;con un reloj de 4 Mhz:
movlw
b'10000001'
;tb'=889 us
;->tb=2*tb'=1.778 ms
movwf
opci
;TOIF=
;div*(257 us-tin)+2=889
bcf
esta,5
;con div=4=>
;tin=257-887/4=35.25~35
;pero experimentalmente
;~36
entce
;voy a esperar
;que pase el primer
;bit de
;sincr
btfss
ir
goto
entce
movlw
d'147'
;pero la primer pregunta
;es a TOIF/2
movwf
coti
;=>con div=4,
;tin=146.125=>
;tin~146, pero
;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,1
movlw
d'24'
subwf
cnttrb,0
btfss
z
goto
etmr
comie
btfss
toif
goto
comie
movlw
d'36'
movwf
coti
bcf
toif
decf
cnttrb,1
movlw
d'12'
subwf
cnttrb,0
btfss
z
goto
dsipo
bcf
bit
incf
cnttrb,1
;para corregir tb el ultimo nibble
goto
cmnz
dsipo
movlw
b'01000000'
xorwf
aux,1
btfss
bit
35
Técnicas Digitales III – Problema de ingeniería
goto
btfsc
goto
bsf
sgdo
ir
cerx
disp1,0
goto
comie
bcf
goto
disp1,0
comie
btfss
goto
btfss
goto
bcf
rlf
goto
ir
ceroz
disp1,0
listim
car
disp1,1
comie
btfsc
goto
bcf
rlf
goto
disp1,0
listim
car
disp1,1
comie
btfss
goto
movlw
movwf
bcf
toif
cmnz
d'36'
coti
toif
movlw
xorwf
btfss
goto
btfsc
goto
bsf
goto
b'01000000'
aux,1
bit
sgdz
ir
crxz
byte,0
parch
bcf
byte,0
goto
parch
btfss
goto
btfss
goto
bcf
rlf
goto
ir
crz
byte,0
listim
car
byte,1
parch
btfsc
goto
bcf
rlf
byte,0
listim
car
byte,1
decfsz
goto
cnttrb,1
cmnz
;en disp1 esta guardando 1
;bit de
;"T" y los 5 de
;dispositivo
cerx
sgdo
ceroz
cmnz
comma
crxz
;en byte guarda los 6 bit del
comando
sgdz
crz
parch
acoreg
;pongo un cero en el bit 7
36
Técnicas Digitales III – Problema de ingeniería
;de byte si se da
;codigo de repeticion
bcf
rrf
comf
car
byte,1
byte,1
movlw
andwf
andwf
btfss
goto
btfss
goto
bcf
goto
b'00111111'
disp1,1
byte,1
disp1,5
not
disp,5
ciro
byte,6
listi
bsf
bsf
goto
disp,5
byte,6
listi
;los datos estan
;exactamente al reves,
;comprobado con
;sciloscopio
ciro
not
;pongo un uno en el bit 7
;de byte si no se da ;codigo de
repeticion
btfsc
goto
bcf
goto
disp,5
cir
byte,6
listi
bcf
bsf
goto
disp,5
byte,6
listi
bsf
terr
cir
listim
listi
return
;******************************************************
cmprb
movf
disp1,0
subwf
disp,0
btfsc
z
bsf
cop
finto
return
;******************************************************
intsub
bcf
todas
call
ledat
btfsc
terr
goto
finle
btfsc
prvz
goto
disp1,0
movwf
disp
bsf
prvz
bcf
ledr
bsf
ledv
call
retalar
bcf
ledv
fingdi
call
cmprb
btfss
cop
37
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
;******************************************************
datopcs
movf
byte,0
movwf
cbyte
movlw
d'09'
movwf
contr
bcf
dsr
;espero un rato lo que dura un
;mensaje (25ms) y si la pc no me
;contesta, fue...
bsf
esta,5
;para 25ms =>con div=128=>
;tin~61.7~62, pero ;experimentalmente ~61
movlw
b'10000110'
movwf
opci
movlw
b'10001111'
movwf
copub
bcf
esta,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,5
movlw
b'10000000'
movwf
opci
bcf
esta,5
;con un reloj de 4 Mhz, y
;para 9600 b/s:
bcf
toif
;tb=1/9600=104.16 us
bcf
rxd
;TOIF->104.16
;us=>TOIF=(257us*div)+2
;=>div=102.16
;us/257us=0.398
movlw
d'206'
;=>adopto div=2 y preseteo
;el TMRO:
movwf
coti
;=>(257-in)*2us+2us=
;104.16 us=>
;tin=257-102.16/2=
;205.92~206
;experimentalmente ~206
38
Técnicas Digitales III – Problema de ingeniería
bcf
goto
toif
sgteb
btfss
cbyte,0
goto
bsf
rrf
goto
escer
rxd
cbyte,1
sgteb
bcf
rrf
rxd
cbyte,1
btfss
goto
movlw
movwf
bcf
decfsz
goto
toif
sgteb
d'206'
coti
toif
contr,1
estmr
btfss
goto
bsf
toif
dtlst
rxd
estmr
;0 para empezar;
;transmitiendo el LSB. 7
;de lo contrario. Se
;modifica el sentido de
;rotacion tb
escer
sgteb
dtlst
fintr
bsf
dsr
bsf
rxd
return
;*************************************************
retalar
movlw
d'20'
movwf
cont1
bsf
esta,5
movlw
b'10000111'
movwf
opci
bcf
esta,5
aquie
clrf
coti
bcf
toif
pruev
btfss
toif
goto
pruev
decfsz
cont1,1
goto
aquie
return
;*******************************************************
datopcp
bsf
esta, 5
movlw
b'10000101'
movwf
copub
bcf
esta, 5
clrf
cbyte
btfsc
byte, 0
bsf
cbyte, 5
btfsc
byte, 1
bsf
cbyte, 6
btfsc
byte, 2
bsf
cbyte, 3
39
Técnicas Digitales III – Problema de ingeniería
btfsc
bsf
movf
movwf
byte, 3
cbyte, 1
cbyte, 0
pub
bsf
esta,5
movlw
movwf
bcf
movlw
movwf
bcf
b'10000110'
opci
esta,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, 4
cbyte, 5
byte, 5
cbyte, 6
byte, 6
cbyte, 3
byte, 7
cbyte, 1
cbyte, 0
pub
;espero un rato lo que dura un
;mensaje ;
;(25ms) y si la pc no me
;contesta, fue...
;para 25ms =>con div=128=>
;tin~61.7~62,
;pero experimentalmente ~61
agntep
acsegp
fintra
call
retalar
clrf
pub
return
;***************************************************
END
40
Técnicas Digitales III – Problema de ingeniería
Código fuente para la PC:
WinMain:
#include
#include
#include
#include
#include
#include
#include
#include
<windows.h>
<IDS3.h>
<iostream>
<string.h>
<assert.h>
<stdlib.h>
<windows.h>
<cstdlib>
using namespace std;
typedef struct
{
char Puerto[5];
int Baudios;
int BitsDatos;
int BitsStop;
char Paridad[25];
} tipoOpciones;
// Variables globales:
tipoOpciones Ops;
// Opciones
HGLOBAL hCadena, hSalida; // Buffers
int *sal, *cad;
DCB dcb;
// Puerto serie
HANDLE idComDev;
bool Comunicacion;
int aux2;
char dinum[20]="C:\\nume.txt";
char diide[20]="C:\\iden.txt";
FILE *numeros, *ide;
int num[50], con1, tec[50];
char idtf[22][80];
// Prototipos:
void IniciarBuffers();
void comenzar(void);
void actualizar();
void actualizaride();
void LiberarBuffers();
bool InicioComunicacion(void);
bool FinComunicacion(void);
int lee_el_puerto(void);
void LeeSerie();
void crear_la_tabla();
void crear_la_tablaide();
void cargar_archivo();
void cargar_archivoide();
/* Declaración del procedimiento de ventana */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProc2(HWND, UINT, WPARAM, LPARAM);
41
Técnicas Digitales III – Problema de ingeniería
/* Declaraciones de tipos */
typedef struct stDatos
{
int Teclas;
char identif1[80];
char identif2[80];
char identif3[80];
char identif4[80];
char identif5[80];
char identif6[80];
char identif7[80];
char identif8[80];
char identif9[80];
char identif10[80];
char identif11[80];
char identif12[80];
char identif13[80];
char identif14[80];
char identif15[80];
char identif16[80];
char identif17[80];
char identif18[80];
char identif19[80];
char identif20[80];
char identif21[80];
} DATOS;
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd;
/* Manipulador de ventana */
MSG mensaje;
/* Mensajes recibidos por la aplicación */
WNDCLASSEX wincl;
/* Estructura de datos para la clase de ventana */
num[0]=EOF;
idtf[21][0]=EOF;
tec[0]=EOF;
/* Estructura de la ventana */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = "NUESTRA_CLASE";
wincl.lpfnWndProc = WindowProcedure;
/* Esta función es invocada por
Windows */
wincl.style = CS_DBLCLKS;
/* Captura los doble-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Usar icono y puntero por defecto */
wincl.hIcon = LoadIcon (hThisInstance, "icono");
wincl.hIconSm = LoadIcon (hThisInstance, "icono");
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = "Menu";
wincl.cbClsExtra = 0;
/* Sin información adicional para
la */
wincl.cbWndExtra = 0;
/* clase o la ventana */
/* Usar el color de fondo por defecto para la ventana */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Registrar la clase de ventana, si falla, salir del programa */
if(!RegisterClassEx(&wincl)) return 0;
42
Técnicas Digitales III – Problema de ingeniería
/* La clase está registrada, crear la ventana */
hwnd = CreateWindowEx(
0,
/* Posibilidades de variación */
"NUESTRA_CLASE",
/* Nombre de la clase */
"Control Remoto",
/* Texto del título */
WS_OVERLAPPEDWINDOW, /* Tipo por defecto */
CW_USEDEFAULT,
/* Windows decide la posición */
CW_USEDEFAULT,
/* donde se coloca la ventana */
200,
/* Ancho */
100,
/* Alto en pixels */
HWND_DESKTOP,
/* La ventana es hija del escritorio */
NULL,
/* Sin menú */
hThisInstance,
/* Manipulador de instancia */
NULL
/* No hay datos de creación de ventana */
);
/* Mostrar la ventana */
ShowWindow(hwnd, SW_SHOWDEFAULT);
/* Bucle de mensajes, se ejecuta hasta que haya error o GetMessage devuelva
FALSE */
while(TRUE == GetMessage(&mensaje, NULL, 0, 0))
{
/* Traducir mensajes de teclas virtuales a mensajes de caracteres */
TranslateMessage(&mensaje);
/* Enviar mensaje al procedimiento de ventana */
DispatchMessage(&mensaje);
}
/* Salir con valor de retorno */
return mensaje.wParam;
}
/* Esta función es invocada por la función DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
lParam)
{
static HINSTANCE hInstance;
static DATOS Datos;
switch (msg)
/* manipulador del mensaje */
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
/* Inicialización de los datos de la aplicación */
Datos.Teclas = 1;
return 0;
break;
case WM_COMMAND:
if(LOWORD(wParam) == CM_DIALOGO)
DialogBoxParam(hInstance, "DialogoTeclas", hwnd, DlgProc,
(LPARAM)&Datos);
if(LOWORD(wParam) == CM_DIALOGO2)
DialogBoxParam(hInstance, "DialogoTeclasmos", hwnd, DlgProc2,
(LPARAM)&Datos);
if(LOWORD(wParam) == CM_DIALOGO3)
{
comenzar();
}
if(LOWORD(wParam) == CM_DIALOGO4)
crear_la_tabla();
43
Técnicas Digitales III – Problema de ingeniería
break;
case WM_DESTROY:
PostQuitMessage(0);
/* envía un mensaje WM_QUIT a la cola de
mensajes */
break;
default:
/* para los mensajes de los que no nos ocupamos
*/
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL NumeroOk;
static DATOS *datos;
int nume, auxi, auxi2;
if((numeros=fopen(dinum, "rb"))==NULL)
crear_la_tabla();
else
fclose(numeros);
cargar_archivo();
switch (msg)
/* manipulador del mensaje */
{
case WM_INITDIALOG:
datos = (DATOS *)lParam;
SetDlgItemInt(hDlg, ID_TECLAS, (UINT)datos->Teclas, FALSE);
SetFocus(GetDlgItem(hDlg, ID_TECLAS));
return FALSE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
nume = GetDlgItemInt(hDlg, ID_TECLAS, &NumeroOk, FALSE);
if(NumeroOk)
{
inv:
datos->Teclas = nume;
EndDialog(hDlg, FALSE);
if(nume>21 || nume<1)
{
MessageBox(hDlg, "Entrada Invalida", "Relacionando",
MB_OK);
return FALSE;
}
auxi=lee_el_puerto();
MessageBox(hDlg, "Codigo Guardado", "Relacionando", MB_OK);
auxi2=num[nume-1];
for(con1=0;con1<21;con1++)
if(num[con1]==auxi)
num[con1]=auxi2;
con1++;
num[nume-1]=auxi;
actualizar();
}
else
MessageBox(hDlg, "Número no válido", "Error",
MB_ICONEXCLAMATION | MB_OK);
break;
case IDCANCEL:
44
Técnicas Digitales III – Problema de ingeniería
EndDialog(hDlg, FALSE);
break;
}
return TRUE;
}
return FALSE;
}
BOOL CALLBACK DlgProc2(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static DATOS *datos;
if((ide=fopen(diide, "a"))==NULL)
crear_la_tablaide();
else
fclose(ide);
cargar_archivoide();
switch (msg)
/* manipulador del mensaje */
{
case WM_INITDIALOG:
datos = (DATOS *)lParam;
SetDlgItemText(hDlg, ID_IDENT1, idtf[0]);
SetDlgItemText(hDlg, ID_IDENT2, idtf[1]);
SetDlgItemText(hDlg, ID_IDENT3, idtf[2]);
SetDlgItemText(hDlg, ID_IDENT4, idtf[3]);
SetDlgItemText(hDlg, ID_IDENT5, idtf[4]);
SetDlgItemText(hDlg, ID_IDENT6, idtf[5]);
SetDlgItemText(hDlg, ID_IDENT7, idtf[6]);
SetDlgItemText(hDlg, ID_IDENT8, idtf[7]);
SetDlgItemText(hDlg, ID_IDENT9, idtf[8]);
SetDlgItemText(hDlg, ID_IDENT10, idtf[9]);
SetDlgItemText(hDlg, ID_IDENT11, idtf[10]);
SetDlgItemText(hDlg, ID_IDENT12, idtf[11]);
SetDlgItemText(hDlg, ID_IDENT13, idtf[12]);
SetDlgItemText(hDlg, ID_IDENT14, idtf[13]);
SetDlgItemText(hDlg, ID_IDENT15, idtf[14]);
SetDlgItemText(hDlg, ID_IDENT16, idtf[15]);
SetDlgItemText(hDlg, ID_IDENT17, idtf[16]);
SetDlgItemText(hDlg, ID_IDENT18, idtf[17]);
SetDlgItemText(hDlg, ID_IDENT19, idtf[18]);
SetDlgItemText(hDlg, ID_IDENT20, idtf[19]);
SetDlgItemText(hDlg, ID_IDENT21, idtf[20]);
SetFocus(GetDlgItem(hDlg, ID_IDENT1));
return FALSE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
GetDlgItemText(hDlg, ID_IDENT1, datos->identif1, 80);
strcpy(idtf[0], datos->identif1);
GetDlgItemText(hDlg, ID_IDENT2, datos->identif2, 80);
strcpy(idtf[1], datos->identif2);
GetDlgItemText(hDlg, ID_IDENT3, datos->identif3, 80);
strcpy(idtf[2], datos->identif3);
GetDlgItemText(hDlg, ID_IDENT4, datos->identif4, 80);
strcpy(idtf[3], datos->identif4);
GetDlgItemText(hDlg, ID_IDENT5, datos->identif5, 80);
strcpy(idtf[4], datos->identif5);
GetDlgItemText(hDlg, ID_IDENT6, datos->identif6, 80);
strcpy(idtf[5], datos->identif6);
GetDlgItemText(hDlg, ID_IDENT7, datos->identif7, 80);
strcpy(idtf[6], datos->identif7);
45
Técnicas Digitales III – Problema de ingeniería
GetDlgItemText(hDlg, ID_IDENT8, datos->identif8, 80);
strcpy(idtf[7], datos->identif8);
GetDlgItemText(hDlg, ID_IDENT9, datos->identif9, 80);
strcpy(idtf[8], datos->identif9);
GetDlgItemText(hDlg, ID_IDENT10, datos->identif10, 80);
strcpy(idtf[9], datos->identif10);
GetDlgItemText(hDlg, ID_IDENT11, datos->identif11, 80);
strcpy(idtf[10], datos->identif11);
GetDlgItemText(hDlg, ID_IDENT12, datos->identif12, 80);
strcpy(idtf[11], datos->identif12);
GetDlgItemText(hDlg, ID_IDENT13, datos->identif13, 80);
strcpy(idtf[12], datos->identif13);
GetDlgItemText(hDlg, ID_IDENT14, datos->identif14, 80);
strcpy(idtf[13], datos->identif14);
GetDlgItemText(hDlg, ID_IDENT15, datos->identif15, 80);
strcpy(idtf[14], datos->identif15);
GetDlgItemText(hDlg, ID_IDENT16, datos->identif16, 80);
strcpy(idtf[15], datos->identif16);
GetDlgItemText(hDlg, ID_IDENT17, datos->identif17, 80);
strcpy(idtf[16], datos->identif17);
GetDlgItemText(hDlg, ID_IDENT18, datos->identif18, 80);
strcpy(idtf[17], datos->identif18);
GetDlgItemText(hDlg, ID_IDENT19, datos->identif19, 80);
strcpy(idtf[18], datos->identif19);
GetDlgItemText(hDlg, ID_IDENT20, datos->identif20, 80);
strcpy(idtf[19], datos->identif20);
GetDlgItemText(hDlg, ID_IDENT21, datos->identif21, 80);
strcpy(idtf[20], datos->identif21);
actualizaride();
EndDialog(hDlg, FALSE);
break;
case IDCANCEL:
EndDialog(hDlg, FALSE);
break;
}
return TRUE;
}
return FALSE;
}
int lee_el_puerto(void)
{
int c;
DWORD dwEvtMask;
DWORD n, param, id;
// Inicializar opciones del puerto serie:
strcpy(Ops.Puerto, "COM1");
Ops.Baudios = 9600;
Ops.BitsDatos = 8;
Ops.BitsStop = 1;
strcpy(Ops.Paridad, "Sin paridad");
IniciarBuffers();
// No se ha establecido comunicación:
Comunicacion = false;
if(!InicioComunicacion())
{
LiberarBuffers();
return 1;
}
46
Técnicas Digitales III – Problema de ingeniería
do
{
}while(!((WaitCommEvent(idComDev, &dwEvtMask, NULL))&&(dwEvtMask &
EV_RXCHAR)));
LeeSerie();
c=*cad;
FinComunicacion();
LiberarBuffers();
aux2=c&127;
c=c&63;
aux2=aux2-c;
return(c);
}
// Reservar memoria global para buffers del puerto serie:
void IniciarBuffers()
{
hCadena = GlobalAlloc(GMEM_MOVEABLE, 4096);
hSalida = GlobalAlloc(GMEM_MOVEABLE, 4096);
cad = (int *)GlobalLock(hCadena);
sal = (int *)GlobalLock(hSalida);
}
// Liberar memoria global de buffers del puerto serie:
void LiberarBuffers()
{
GlobalUnlock(hCadena);
GlobalUnlock(hSalida);
GlobalFree(hCadena);
GlobalFree(hSalida);
}
// Iniciar el puerto serie:
bool InicioComunicacion(void)
{
bool fSuccess;
// Abrir el fichero asociado al puerto:
idComDev = CreateFile(Ops.Puerto, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if(idComDev ==INVALID_HANDLE_VALUE)
return false;
// Leer estructura de control del puerto serie, cdb:
fSuccess = GetCommState(idComDev, &dcb);
if(!fSuccess)
return false;
// Modificar el dcb según las opciones definidas:
dcb.BaudRate = Ops.Baudios;
dcb.ByteSize = Ops.BitsDatos;
if(!strcmp(Ops.Paridad, "Sin paridad")) dcb.Parity = NOPARITY;
if(!strcmp(Ops.Paridad, "Paridad par")) dcb.Parity = EVENPARITY;
if(!strcmp(Ops.Paridad, "Paridad impar")) dcb.Parity = ODDPARITY;
switch(Ops.BitsStop)
{
case 1:
dcb.StopBits = ONESTOPBIT;
break;
case 2:
dcb.StopBits = TWOSTOPBITS;
break;
47
Técnicas Digitales III – Problema de ingeniería
}
// Modificar la estructura de control del puerto serie:
fSuccess = SetCommState(idComDev, &dcb);
if(!fSuccess)
return false;
// Especifica que queremos monitorizar la recepción de datos:
if(!SetCommMask(idComDev, EV_RXCHAR))
return false;
// Comunicación establecida:
Comunicacion = true;
return true;
}
// Finalizar comunicación por puerto serie:
bool FinComunicacion(void)
{
// Liberar máscara de eventos del puerto serie:
SetCommMask(idComDev, 0);
// Cerrar el puerto serie:
CloseHandle(idComDev);
// Comunicación interrumpida:
Comunicacion = false;
return true;
}
// Leer datos del puerto serie:
void LeeSerie()
{
int i, j, k;
DWORD x;
COMSTAT cs;
// Actualizar COMSTAT, sirve para
// averiguar el número de bytes en el buffer de entrada:
ClearCommError(idComDev, &x, &cs);
// Leer cs.cbInQue caracteres:
ReadFile(idComDev, cad, cs.cbInQue, &x, NULL);
// Actualizar el fin de cadena:
cad[x]=0;
return;
}
void comenzar()
{
int delcontr, aux, i, k=0;
//inicio
if((numeros=fopen(dinum, "rb"))==NULL)
crear_la_tabla();
else
fclose(numeros);
cargar_archivo();
if((ide=fopen(diide, "r"))==NULL)
crear_la_tablaide();
else
fclose(ide);
cargar_archivoide();
for(i=0;i<21;i++)
tec[i]=i+1;
tec[21]=EOF;
otra:
48
Técnicas Digitales III – Problema de ingeniería
delcontr=lee_el_puerto();
con1=0;
while(num[con1]!=delcontr && (con1<100))
con1++;
if((num[con1]==EOF)||((aux!=9)&&(aux!=10)&&(aux2==0)))
goto otra;
aux=tec[con1];
switch(aux)
{
case 1: keybd_event(VK_RIGHT,0xcd,0 , 0);
// Periona Flecha
derecha
keybd_event(VK_RIGHT,0xcd,KEYEVENTF_KEYUP,0);
// Suelta Flecha
derecha
break;
case 2: if((k%2)==0)
keybd_event(VK_MENU,0xb8,0 , 0);
//Presiona Alt
else
keybd_event(VK_MENU,0xb8,KEYEVENTF_KEYUP,0);
// Suelta Alt
k++;
break;
case 3: keybd_event(VkKeyScan('B'),0xb0,0 , 0);
// Presiona 'B'
keybd_event(VkKeyScan('B'),0xb0, KEYEVENTF_KEYUP,0);
// Suelta 'B'
break;
case 4: keybd_event(VkKeyScan('Z'),0xac,0 , 0);
// Presiona 'Z'
keybd_event(VkKeyScan('Z'),0xac, KEYEVENTF_KEYUP,0);
// Suelta 'Z'
break;
case 5: keybd_event(VkKeyScan('X'),0xad,0 , 0);
// Presiona 'X'
keybd_event(VkKeyScan('X'),0xad, KEYEVENTF_KEYUP,0);
// Suelta 'X'
break;
case 6: keybd_event(VK_RETURN,0x9c,0 , 0);
// Periona Enter
keybd_event(VK_RETURN,0x9c,KEYEVENTF_KEYUP,0);
// Suelta Enter
break;
case 7: keybd_event(VkKeyScan('L'),0xa6,0 , 0);
// Presiona 'L'
keybd_event(VkKeyScan('L'),0xa6, KEYEVENTF_KEYUP,0);
// Suelta 'L'
break;
case 8: keybd_event(VK_RSHIFT,0xb6,0 , 0);
// Periona Shift
derecho
keybd_event(VkKeyScan('L'),0xa6,0 , 0);
// Presiona 'L'
keybd_event(VkKeyScan('L'),0xa6, KEYEVENTF_KEYUP,0);
// Suelta 'L'
keybd_event(VK_RSHIFT,0xb6,KEYEVENTF_KEYUP,0);
// Suelta Shift
derecho
break;
case 9: keybd_event(VK_UP,0xc8,0 , 0);
// Periona Flecha
arriba
keybd_event(VK_UP,0xc8,KEYEVENTF_KEYUP,0);
// Suelta Flecha
arriba
break;
case 10: keybd_event(VK_DOWN,0xd0,0 , 0);
//Presiona
Flecha abajo
keybd_event(VK_DOWN,0xd0,KEYEVENTF_KEYUP,0);
// Suelta
Flecha abajo
break;
case 11: keybd_event(VK_ESCAPE,0x81,0 , 0);
// Presiona Esape
keybd_event(VK_ESCAPE,0x81, KEYEVENTF_KEYUP,0);
// Suelta Esape
break;
case 12: keybd_event(VK_SPACE,0xb9,0 , 0);
// Presiona Barra
espaciadora
keybd_event(VK_SPACE,0xb9, KEYEVENTF_KEYUP,0);
// Suelta Barra
espaciadora
break;
case 13: keybd_event(VK_BACK,0x8e,0 , 0);
// Presiona Back Space
49
Técnicas Digitales III – Problema de ingeniería
keybd_event(VK_BACK,0x8e, KEYEVENTF_KEYUP,0);
// suelta Back Space
break;
case 14: keybd_event(VK_MENU,0xb8,0 , 0);
//Presiona Alt
keybd_event(VK_SPACE,0xb9,0 , 0);
// Presiona
Barra espaciadora
keybd_event(VK_SPACE,0xb9, KEYEVENTF_KEYUP,0);
// Suelta Barra
espaciadora
keybd_event(VK_MENU,0xb8,KEYEVENTF_KEYUP,0);
// Suelta Alt
break;
case 15: keybd_event(VK_MENU,0xb8,0 , 0);
//Presiona Alt
keybd_event(VK_F4,0xbe,0 , 0);
// Presiona Tecla
F4
keybd_event(VK_F4,0xbe, KEYEVENTF_KEYUP,0);
// Suelta Tecla F4
keybd_event(VK_MENU,0xb8,KEYEVENTF_KEYUP,0);
// Suelta Alt
break;
case 16: keybd_event(VK_CONTROL,0x9d,0 , 0);
// Periona Ctrl
keybd_event(VK_TAB,0x8f,0 , 0);
//Prtesiona tab
keybd_event(VK_TAB,0x8f, KEYEVENTF_KEYUP,0);
//suelta tab
keybd_event(VK_CONTROL,0x9d,KEYEVENTF_KEYUP,0);
// Suelta Ctrl
break;
case 17: keybd_event(VK_TAB,0x8f,0 , 0);
//Prtesiona tab
keybd_event(VK_TAB,0x8f, KEYEVENTF_KEYUP,0);
//suelta tab
break;
case 18: keybd_event(VK_LEFT,0xcb,0 , 0);
// Flecha izquierda
keybd_event(VK_LEFT,0xcb, KEYEVENTF_KEYUP,0);
// Flecha izquierda
break;
case 19: keybd_event(VK_LWIN,0x9b,0 , 0);
// Periona Windows
keybd_event(VK_LWIN,0x9b,KEYEVENTF_KEYUP,0);
// Suelta Windows
break;
case 20: keybd_event(VK_LWIN,0x9c,0 , 0);
// Periona Windows
keybd_event(VkKeyScan('M'),0xa6,0 , 0);
// Presiona 'M'
keybd_event(VkKeyScan('M'),0xa6, KEYEVENTF_KEYUP,0);
// Suelta 'M'
keybd_event(VK_LWIN,0x9c,KEYEVENTF_KEYUP,0);
// Suelta Windows
break;
case 21: keybd_event(VK_RSHIFT,0xb6,0 , 0);
// Periona Shift
derecho
keybd_event(VK_TAB,0x8f,0 , 0);
//Prtesiona tab
keybd_event(VK_TAB,0x8f, KEYEVENTF_KEYUP,0);
//suelta tab
keybd_event(VK_RSHIFT,0xb6,KEYEVENTF_KEYUP,0);
// Suelta Shift
derecho
break;
}
goto otra;
}
void crear_la_tabla()
{
num[0]=52;
num[1]=9;
num[2]=3;
num[3]=1;
num[4]=2;
num[5]=12;
num[6]=7;
num[7]=8;
num[8]=32;
num[9]=33;
num[10]=55;
num[11]=0;
num[12]=48;
num[13]=15;
50
Técnicas Digitales III – Problema de ingeniería
num[14]=56;
num[15]=5;
num[16]=4;
num[17]=50;
num[18]=54;
num[19]=53;
num[20]=6;
num[21]=EOF;
numeros=fopen(dinum, "wb");
for(con1=0;con1<21;con1++)
fprintf(numeros, "%d\n", num[con1]);
fclose(numeros);
fclose(numeros);
return;
}
void cargar_archivo()
{
numeros=fopen(dinum, "rb");
for(con1=0;con1<21;con1++)
fscanf(numeros, "%d", &num[con1]);
fclose(numeros);
return;
}
void actualizar()
{
numeros=fopen(dinum, "wb");
con1=0;
do
{
fprintf(numeros, "%d\n", num[con1]);
con1++;
}while(num[con1]!=EOF);
fclose(numeros);
return;
}
void actualizaride()
{
ide=fopen(diide, "w");
fprintf(ide, "p\n");
for(con1=0;con1<21;con1++)
fprintf(ide, "%s\n", idtf[con1]);
fprintf(ide, "%d\n", EOF);
fclose(ide);
return;
}
void cargar_archivoide()
{
char pru;
ide=fopen(diide, "r");
fscanf(ide, "%c\n", &pru);
for(con1=0;con1<21;con1++)
fscanf(ide, "%s\n", &idtf[con1][0]);
fclose(ide);
return;
}
void crear_la_tablaide()
{
for(con1=0;con1<21; con1++)
strcpy(idtf[con1], " ");
actualizaride();
return;
51
Técnicas Digitales III – Problema de ingeniería
}
Archivo de Recursos:
#include <windows.h>
#include <IDS3.H>
Menu MENU
BEGIN
POPUP "&Principal"
BEGIN
MENUITEM "&Reorganizar Botones", CM_DIALOGO
MENUITEM SEPARATOR
MENUITEM "&Recordatorios", CM_DIALOGO2
MENUITEM SEPARATOR
MENUITEM "&Comenzar", CM_DIALOGO3
MENUITEM SEPARATOR
MENUITEM "&Default Botones", CM_DIALOGO4
END
END
icono ICON "ICONGROUP_92.ico"
DialogoTeclas DIALOG 0, 0, 145, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Ingresar Tecla"
FONT 8, "Helv"
{
CONTROL "1) Flchder", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 5, 52, 34
CONTROL "2) Alt", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 20, 52, 34
CONTROL "3) B", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 35, 52, 34
CONTROL "4) Z", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 50, 52, 34
CONTROL "5) X", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 65, 52, 34
CONTROL "6) Enter", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 85, 52, 34
CONTROL "7) L", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 100, 52, 34
CONTROL "8) Shift+L", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 115, 52, 34
CONTROL "9) Flcharr", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 130, 52, 34
CONTROL "10) Flchaba", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 145, 52, 34
CONTROL "11) Esc", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 5, 52, 34
52
Técnicas Digitales III – Problema de ingeniería
CONTROL "12) BarEspc", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 20, 52, 34
CONTROL "13) BackSpc", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 35, 52, 34
CONTROL "14) Alt+Espc", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 50, 52, 34
CONTROL "15) Alt+F4", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 65, 52, 34
CONTROL "16) Ctrl+Tab", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 85, 52, 34
CONTROL "17) Tab", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 100, 52, 34
CONTROL "18) Flchizq", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 115, 52, 34
CONTROL "19) Inicio", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 130, 52, 34
CONTROL "20) Escritorio", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 145, 52, 34
CONTROL "21) Shift+Tab", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
88, 160, 52, 34
CONTROL "Eleccion:", -1, "static",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 160, 52, 34
CONTROL "", ID_TECLAS, "EDIT",
ES_NUMBER | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
46, 160, 36, 12
CONTROL "Aceptar", IDOK, "BUTTON",
BS_DEFPUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
75, 175, 45, 14
CONTROL "Cancelar", IDCANCEL, "BUTTON",
BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
15, 175, 45, 14
}
DialogoTeclasmos DIALOG 0, 0, 310, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Relaciones Disponibles"
FONT 8, "Helv"
{
CONTROL "<-Recordartorios->", -1, "static",
SS_LEFT | WS_CHILD | WS_VISIBLE,
121, 5, 60, 34
CONTROL "1) Flchder :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 5, 52, 34
CONTROL "", ID_IDENT1, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
55, 5, 66, 12
CONTROL "2) Alt :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 20, 52, 34
53
Técnicas Digitales III – Problema de ingeniería
CONTROL "", ID_IDENT2, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 20, 66, 12
CONTROL "3) B :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 35, 52, 34
CONTROL "", ID_IDENT3, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 35, 66, 12
CONTROL "4) Z :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 50, 52, 34
CONTROL "", ID_IDENT4, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 50, 66, 12
CONTROL "5) X :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 65, 52, 34
CONTROL "", ID_IDENT5, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 65, 66, 12
CONTROL "6) Enter :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 85, 52, 34
CONTROL "", ID_IDENT6, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 85, 66, 12
CONTROL "7) L :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 100, 52, 34
CONTROL "", ID_IDENT7, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 100, 66, 12
CONTROL "8) Shift+L :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 115, 60, 34
CONTROL "", ID_IDENT8, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 115, 66, 12
CONTROL "9) Flcharr :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 130, 60, 34
CONTROL "", ID_IDENT9, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 130, 66, 12
CONTROL "10) Flchaba :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 145, 60, 34
CONTROL "", ID_IDENT10, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
55, 145, 66, 12
CONTROL ":12) Esc", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 5, 52, 34
CONTROL "", ID_IDENT11, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
180, 5, 66, 12
CONTROL ":13) BarEsp", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 20, 52, 34
CONTROL "", ID_IDENT12, "EDIT",
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
| WS_TABSTOP,
54
Técnicas Digitales III – Problema de ingeniería
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 20, 66, 12
CONTROL ":14 BackSpa", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 35, 52, 34
CONTROL "", ID_IDENT13, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 35, 66, 12
CONTROL ":15) Alt+Spac", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 50, 52, 34
CONTROL "", ID_IDENT14, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 50, 66, 12
CONTROL ":16) Alt+F4", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 65, 52, 34
CONTROL "", ID_IDENT15, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 65, 66, 12
CONTROL ":17) Ctrl+Tab", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 85, 52, 34
CONTROL "", ID_IDENT16, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 85, 66, 12
CONTROL ":18) Tab", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 100, 52, 34
CONTROL "", ID_IDENT17, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 100, 66, 12
CONTROL ":19) Flchizq", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 115, 52, 34
CONTROL "", ID_IDENT18, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 115, 66, 12
CONTROL ":20) Inicio", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 130, 52, 34
CONTROL "", ID_IDENT19, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 130, 66, 12
CONTROL ":21) Escritorio", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
250, 145, 52, 34
CONTROL "", ID_IDENT20, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
180, 145, 66, 12
CONTROL "11) Shift+Tab :", -1, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 160, 70, 34
CONTROL "", ID_IDENT21, "EDIT",
ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
55, 160, 66, 12
CONTROL "Aceptar", IDOK, "BUTTON",
BS_DEFPUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
250, 175, 50, 14
CONTROL "Cancelar", IDCANCEL, "BUTTON",
BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
55
Técnicas Digitales III – Problema de ingeniería
160, 175, 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
Técnicas Digitales III – Problema de ingeniería
Anexo B: Sitios en la WEB

http://localhost/conclase/c/ficheros/para-pdf/curso.php

http://findquest.net /Davshomepage.htm

http://www-wjp.cs.uni-sb.de/~columbus/lirc/ article137.html#lfindex0

http://www.geocities.com/SiliconValley/Hardware/8000/index.htm/raton.htm

http://www.servisystem.com.ar/remoto.html

www.beyondlogic.org

http://todohard.awardspace.com/tutrs232

http://www.philips.com/global

https://www.glue.umd.edu/~nsw/ench250/scancode.htm#Key1

http://www.barcodeman.com/altek/mule/scandoc.php#Top

http://www.georgehernandez.com/h/ Scan Codes by George Hernandez.htm

http://www.quadibloc.com/main.htm

http://www.clubse.com.ar/DIEGO/NOTAS/3notas/nota02-1.htm

http://www.p4c.philips.com/files/s/sru4050_37/sru4050_37_dfu_aen.pdf.

http://informatica.uv.es/it3guia/FT/prac5-232.pdf

http://www.tscm.com/rs-232.pdf

www.pablin.com.ar/electron/circuito/mc/receprc5/index.htm

http://www.thescripts.com/forum/threadedpost2251579.html#post2251579

www.codeproyect.com/system/serial.asp

http://www.geocities.com/horacespider/Serial_IO/DEV-C/terminal.c

http://www.geekhideout.com/parmon.shtml

http://winapi.conclase.net/curso

http://gd.tuwien.ac.at/languages/c/programming-bbrown/advcw2.htm#graphics

http://www.modelo.edu.mx/univ/virtech/frontal/paralelo.htm

http://r-luis.xbot.es/puerto/index.html
Anexo C: GL3276A-datasheets (no incluído en este documento)
Anexo D: MAX232-datasheets (no incluído en este documento)
57
Descargar