Ing. Javier Barriga Hoyle i sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM INDICE: N Pagina
1. Introduccin. 6 2. Listado de componentes de la tarjeta LPT- BYM. 7 3. Equipo de Experimentos DISEN-EXP. 8 4. Puertos de E/S de la Tarjeta LPT- BYM. 9 5. Descripcin del PPI 82C55 de la Tarjeta LPT- BYM. 10 5.1 Modos de Operacin del PPI. 11 5.2 Programacin del PPI. 11 6. Descripcin del TIMER 82C54 de la Tarjeta LPT- BYM 13 6.1 Modos de Operacin del TIMER 14 6.2 Programacin del TIMER 15 7. Descripcin del Conversor Anlogo Digital ADC0804 de la Tarjeta LPT- BYM 19 8. Descripcin del Conversor Digital Anlogo DAC0830 de la Tarjeta LPT- BYM 22 8.1 Estructura interna del ADC030 22 9. Sistema Operativo y uso de la Tarjeta LPT ByM 24 9.1 Uso del UserPort (Win2000 o WinXP) 24 9.2 Estructura de un programa en Lenguaje C 25 10. Aplicaciones del PPI 82C55 26 10.1 LEDS y DIPSWITCH 26 Programa 10.1: Lectura del dato de un dipswitch de 8 bits conectado al PORTB y lo enva por el PORTA para ser visualizado en 8 leds. 26 Programa 10.2: Prende y apaga (intermitencia) 8 leds conectados al PORTA. 27 Programa 10.3: Produce prendido secuencial a la izquierda y se apaga secuencialmente a la derecha. 27 Programa 10.4: Prende secuencialmente los leds desde los extremos hacia el centro y luego se apaga hacia los extremos. 28 10.2 DISPLAY DE CRISTAL LQUIDO (LCD) 29 Programa 10.5: Programa que enva 2 mensajes al LCD (manejo bsico). 29 10.3 TECLADO HEXADECIMAL 4x4 33 Programa 10.6: Lectura del teclado hexadecimal conectado al PORTC del PPI mediante exploracin de teclas. El valor ledo lo enva al PORTA. 34 Programa 10.7: Manejo del Teclado hexadecimal conectado al PORTC del PPI usando el decodificador 74C922. El valor ledo lo enva al PORTA. 37 10.4 DISPLAY 7 SEGMENTOS 38 Programa 10.8: Manejo de 4 displays multiplexados en el tiempo, conectados al PPI. 39 Programa 10.9: Manejo de 8 displays multiplexados en el tiempo, conectados al PPI. 40 10.5 MOTOR DE PASO A PASO 42 Programa 10.10: Control de un motor de paso en modo paso completo. 42 Programa 10.11: Control de un motor de paso en modo medio paso. 44 Programa 10.12: Control de un motor de paso en modo una sola bobina. 45 Programa 10.13: (PPI_13.CPP) Control de la velocidad de un motor de paso (paso completo). 46
Ing. Javier Barriga Hoyle ii sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 11. Aplicaciones del TIMER 82C54 48 11.1 GENERACION DE SEALES A DIFERENTES FRECUENCIAS (MODO 2 y 3) 48 Programa 11.1: (TIMER_1.CPP) Uso del TIMER en modo 2 y 3. 48 Programa 11.2: (TIMER_2.CPP) Uso del TIMER en modo 3, cascada. 49 Programa 11.3: (TIMER_3.CPP) Uso del comando de enclavamiento. 50 Programa 11.4: (TIMER_4.CPP) Uso del comando Read-Back. 52 11.2 PROGRAMAS QUE GENERA SONIDO y PWM 53 Programa 11.5: (TIMER_5.CPP) Genera sonido en el parlante de la PC: Usar Turbo C++ 3.0. 53 Programa 11.6: (TIMER_6.CPP) Genera sonido en el parlante conectado al TIMER de la tarjeta LPT. 54 Programa 11.7: (TIMER_7.CPP) Control de la velocidad de un motor DC usando PWM a travs del teclado de la computadora. 56 Programa 11.8: (TIMER_8.CPP) Control de la velocidad de un motor DC usando PWM a travs de un teclado 4x4 hexadecimal. 59 12. Aplicaciones del ADC 0804 (Sin interrupciones) 63 Programa 12.1: (ADC_1.CPP) Leer el voltaje de un potencimetro (Tcnica de espera). 63 Programa 12.2: (ADC_2.CPP) Leer el voltaje de un potencimetro (Tcnica de polling). 65 Programa 12.3: (ADC_3.CPP) Leer el voltaje de un potencimetro y mostrarlo en un LCD (Tcnica de polling). 66 Programa 12.4: (ADC_4.CPP) Control de la velocidad de un motor DC usando PWM y un potencimetro conectado al ADC. 70 13. Aplicaciones con interrupciones: Pulsadores, ADC0804, TIMER, etc. 73 13.1 Aplicaciones con interrupciones: Sistema Operativo Win2000 o WinXP. 73 Programa 13.1: (IRQ0_1.CPP) Cuenta las interrupciones producidas por la IRQ0. 73 Programa 13.2: (IRQ0_2.CPP) Utiliza las interrupciones generadas por la IRQ0 para producir retardos. 74 Programa 13.3: (IRQ0_3.CPP) Utiliza las interrupciones generadas por la IRQ0 para producir retardos en el desplazamiento de bits y tambin capturar datos analgicos. 76 13.2 Aplicaciones con interrupciones: Sistema Operativo Win98. 79 Programa 13.4: (IRQ7_1.CPP) Cuenta las interrupciones producidas por un pulsador sin rebotes conectado a la lnea IRQ7. 79 Programa 13.5: (IRQ7_2.CPP) Utiliza la IRQ7 para leer el dato del dipswitch conectado al PortB del PPI y lo muestra en PortA del PPI. 81 Programa 13.6: (IRQ7_3.CPP) Muestra en el LCD el nmero de interrupciones generadas por la IRQ7, mientras la CPU desplaza bits por los LEDS del PortC. 83 Programa 13.7: (IRQ7_4.CPP) Usa la tcnica de interrupciones para leer el voltaje analgico del ADC (la lnea IRQ7 se conecta al pin INTR del ADC). 88 Programa 13.8: (IRQ7_5.CPP) Uso de las interrupciones IRQ7 (ADC) e IRQ0 (TIMER de la PC) para muestrear datos analgicos. Muestra en pantalla los datos ledos. 91 Programa 13.9: (IRQ7_6.CPP) Uso de las interrupciones IRQ7 (ADC) e IRQ0 (TIMER de la PC) para muestrear datos analgicos. Almacena en un archivo de texto los datos ledos. 93 14. Aplicaciones del DAC 0830 96 Programa 14.1: (DAC_1.CPP) Programa de prueba del DAC. 96 Programa 14.2: (DAC_2.CPP) Programa que lee un voltaje del ADC0804, lo convierte a digital y luego lo enva al DAC0830 para que lo muestre el voltaje en un multmetro. 97
Apendices: A. Driver L293D. 99 B. Temporizador 8253 de la PC. 100 C. Modulacin por Ancho de Pulsos (PWM). 101 C.1 Generacin de PWM con TIMER 101 C.2 Driver L293D 103
Ing. Javier Barriga Hoyle iii sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM D. Interrupciones. 104 D.1 Conceptos. 104 D.2 Interrupciones en la PC 104 D.3 Controlador de interrupciones programable PIC 8259 106 D.4 Vectores de interrupcin 107 D.5 Instalacin de vectores de interrupcin 107 D.6 Mscara de interrupcin (IMR): 108 D.7 Instalacin de rutinas de servicio de interrupcin (RSI) 109 E. Esquematicos de algunos circuitos 110 E.1 Salida de datos por LEDS 110 E.2 Entrada de datos de 8 bits usando un dipswitch 110 E.3 Displays (cuatro) multiplexados en BCD 110 E.4 Displays (cuatro) multiplexados en HEXADECIMAL 111 E.5 Displays (ocho) multiplexados en salida binaria codificada en software 111 E.6 Control de un motor de pasos con el PORTA del PPI 111 E.7 Control de un motor DC usando el TIMER (PWM) y el PPI 112
Bibliografa 112
Ing. Javier Barriga Hoyle 1 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 1. Introduccion Tarjeta de desarrollo para puerto paralelo LPT- BYM V2.0 Se trata de una tarjeta de circuito impreso metalizado de dimensiones 110x120 mm, provista de un conector DB25H para comunicarse con el puerto paralelo de la computadora. Contiene los siguientes Circuitos Integrados: (1) Interfase de puertos programables PPI 82C55, (1) Temporizador Programable TIMER 82C54, (1) Convertidor Anlogo/Digital ADC0804 de 8 bits de resolucin, (1) Convertidor Digital/Anlogo de 8 bits de resolucin, (1) Lnea de conexin para generar interrupciones a travs de la IRQ7 del computador. Todos los Circuitos Integrados que contiene la tarjeta sirven de soporte al microprocesador y microcontrolador, por lo tanto su estudio y el manejo prctico de estos, servirn para una buena formacin del profesional, permitindole afrontar con xito en el futuro cualquier diseo basado en microprocesadores o microcontroladores. La tarjeta se puede programar en Lenguaje Ensamblador o Lenguaje C (DOS o Windows), para ello se ha diseado unas libreras de Macros y Funciones para cada uno de los lenguajes mencionados que permitirn manejar la tarjeta y cualquier aplicacin que se desee realizar. La siguiente fotografa muestra la tarjeta LPT-BYM V2.0. El manual contiene el manejo y algunas aplicaciones que se le puede dar, as como la descripcin de sus chips.
Fotografa 1. Tarjeta LPT-BYM V2.0
OBS: La tarjeta est diseada para que pueda ser utilizada con el mdulo de experimentos DISEN- EXP (fotografa 2), o desarrollar sus propias aplicaciones.
Ing. Javier Barriga Hoyle 2 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 2. Lista de componentes de la tarjeta LPT- BYM V2.0 Circuitos Integrados: Se emplea Chips con tecnologa CMOS. (U1) 74HC245 (U2) 74HC373 (U3) 74LS257 (U4) Interfase Perifrica Programable PPI 82C55 (U5) Temporizador / Contador Programable TIMER 82C54 (U6) Convertidor Anlogo Digital de 8 bits ADC0804 (U7) Convertidor de Digital a Analgico de 8 bits DAC0830
Componentes discretos. (OSC1) Oscilador de 8 MHz. (D1) Diodo 1N4007 (R2) Potencimetro de 10 K. (R1,R3,R4) Resistencias de 10 K / de Vatio (C1) Condensador electroltico de 10 F / 25V (C2) Condensador cermico monoltico de 150 pF / 50V (*) (C3,C4,C5,C6,C7) Condensadores cermicos monolticos de 1 nF / 25V (*) (C8) Condensador de Tantalum de 10 F / 25V (*) (C9,C10,C11) Condensadores electrolticos de 100 F / 25V
Conectores. (1) Conector DB 25 pines hembra / 90 (PUERTO PARALELO) (3) Molex de 10 pines. (PORT_A, PORT_B, PORT_C)) (1) Molex de 4 pines. (IN_ADC) (1) Dipswitch de 4 bits. (SW TIMER) (1) Bornera de dos pines. (POWER) (1) Bornera de 4 pines. (IN_ADC) (1) Bornera de 5 pines. (DAC_OUT) (1) Bornera de 6 pines. (TIMER)
(*) Estos condensadores pueden ser tambin de otra calidad.
Ing. Javier Barriga Hoyle 3 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 3. Equipo de Experimentos DISEN-EXP Permite la experimentacin prctica con elementos reales de carcter analgico o digital. El equipo se describe completamente en el captulo 10 del manual Aplicaciones prcticas con el C 8051. Va montado en una caja de plstico de dimensiones: 260x185x75 mm, vase fotografa nmero 2. La caja incluye la fuente de alimentacin. Los mdulos de prcticas que incorpora son:
Puerto de salida digital con 8 indicadores LED. Puerto de entrada digital con 8 interruptores con supresor de rebotes. Cuatro pulsadores (dos con rebotes y dos sin rebotes). Cuatro rels de doble contacto conmutado. Dos potencimetros lineales (Valor analgico entre 0 y 5 V) Indicador analgico (vmetro) con 10 diodos LED. Teclado matricial de 12 teclas. Display de cuatro dgitos de 7 segmentos. Display de cristal lquido (LCD) de 2 lneas de 16 caracteres. Generador de onda cuadrada con ajuste de los tiempos Ton y Toff. Emisor y Receptor de infrarrojos. Amplificador de audio y altavoz. Control de temperatura de un conjunto calefactor-termistor. Conjunto Motor DC, excitador para motor, y encoder ptico incremental. Regulacin de luminosidad de una lmpara de 12 V por control de fase mediante triac.
Fotografa 2. Equipo de experimentos DISEN - EXP.
Nota: Mdulo desarrollado por el Ing. Javier Martnez Prez, autor del libro Prcticas con Microcontroladores de 8 bits: Aplicaciones industriales
Ing. Javier Barriga Hoyle 4 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 4. Puertos de E/S de la Tarjeta LPT- BYM V2.0 La tarjeta ha sido diseada de tal manera que todos los circuitos integrados principales operen como si estuvieran trabajando con el puerto ISA. Es decir, todos tienen una direccin de acceso independiente del puerto paralelo, que tiene su direccin base 378h. El siguiente cuadro muestra los puertos de E/S del PPI, TIMER, ADC y DAC.
Circuitos Integrados Direcciones DAC 0830 ADC 0804 Puerto nico = 5C h Puerto nico = 6C h PPI 82C55 Puerto A (PA) = 78 h Puerto B (PB) = 79 h Puerto C (PC) = 7A h Registro de Control (RC) = 7B h TIMER 82C54 Canal 0 (CH0) = 74 h Canal 1 (CH1) = 75 h Canal 2 (CH2) = 76 h Registro de Control (RC) = 77 h
Cuadro 1. Mapeo de los Circuitos Integrados dentro del puerto paralelo.
Las instrucciones diseadas para el manejo de los puertos de E/S de la tarjeta son las siguientes:
Lenguaje Ensamblador Para salida de datos por el puerto:
XOUT PUERTO, AL
Para entrada de datos por el puerto:
XIN AL, PUERTO
Donde: PUERTO: Es la direccin de E/S de cada circuito integrado (ver cuadro 1). AL: Es el registro que el Microprocesador emplea para enviar datos al exterior o para almacenar el dato ledo desde el exterior.
Lenguaje C Para salida de datos por el puerto:
xout (puerto, dato);
Para entrada de datos por el puerto:
y = xin (puerto);
Donde: puerto: Es la direccin de E/S de cada circuito integrado (ver cuadro 1). dato: Es el valor (constante tipo unsigned char) que el Microprocesador enviar hacia el exterior. y: Es una variable declarada como unsigned char, almacenar dato ledo del puerto.
Ing. Javier Barriga Hoyle 5 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 5. Descripcin del PPI 82C55 de la Tarjeta LPT- BYM V2.0 El Interfaz Perifrico Programable PPI 82C55, es un dispositivo de E/S general, programable, capaz de controlar 3 puertos de 8 bits cada uno (24 lneas en total) con diferentes configuraciones de entrada/salida y en hasta 3 modos de operacin.
Figura 5.1. Diagramas del PPI 82C55 y funcin de los pines de control.
Ing. Javier Barriga Hoyle 6 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Los puertos del PPI se llaman normalmente: Puerto A (PA), Puerto B (PB), Puerto C (PC) y Puerto de configuracin interno (RC).
5.1 Modos de Operacin del PPI El PPI presenta tres modos de operacin: Modo 0, Modo 1 y Modo 2. Modo 0: (Entrada/Salida bsica) En este modo, los puertos A, B y C pueden ser individualmente programados como puertos de entrada o salida. El puerto C es dividido en dos grupos de 4 bits, direccionables cada uno en forma independiente. Modo 1: (Comunicacin paralela unidireccional) En este modo el puerto A o el B funcionan como registros de entrada. Esto permite que los datos externos enviados se almacenen en el puerto hasta que el Procesador est listo para leerlos. En cambio el puerto C se utiliza para gestionar las seales de reconocimiento o control que hacen funcionar al puerto A o al puerto B como puertos de entrada mediante una seal de habilitacin estroboscpica. Modo 2: (Comunicacin paralela bidireccional) Este modo slo es vlido para el grupo A, donde el puerto A se vuelve bidireccional permitiendo transmitir y recibir datos en los 8 bits del bus. Los bits PC 3 , PC 4 , PC 5 , PC 6 y PC 7 son usadas como lneas de control en el protocolo de comunicacin. Las 3 lneas restantes del puerto C, pueden estar como E/S convencionales. El puerto B, puede hacerlo en modo 0 o modo 1 simultneamente al puerto A. En este manual slo vamos a utilizar el Modo 0, por ser el ms empleado. Sin embargo, puede tambin usarse en los otros modos, para lo cual recomiendo leer bien la hoja de datos del fabricante.
5.2 Programacin del PPI Para utilizar el PPI en cualquier aplicacin, lo primero que se tiene que hacer es configurarlo. Es decir, enviarle al puerto de configuracin un valor (constante) obtenido de la figura 5.3a, donde se le indica la forma como va a operar cada puerto. Para programarlo slo se emplea dos comandos bsicos. Donde el bit 7 del registro de control selecciona los comandos A o B. Si el bit 7 = 1, el comando A es seleccionado, y sirve para programar la funcin del grupo A y B en modo 0, 1 o 2.
Figura 5.3a. Byte de comando A. Puerto C (PC3 a PC0) 1 = entrada 0 = salida Puerto B 1 = entrada 0 = salida Modo 00 = modo 0 01 = modo 1 Grupo B Puerto C (PC7 - PC4) 1 = entrada 0 = salida Puerto A 1 = entrada 0 = salida Modo 00 = modo 0 01 = modo 1 1X = modo 2 Grupo A 1 7 6 5 4 3 2 1 0
Ing. Javier Barriga Hoyle 7 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Si el bit 7 = 0, el comando B es seleccionado, y permite que cualquier bit del PC se active (1) o se desactive (0) si el 8255 se programa en el modo 1 o 2.
Figura 5.3b. Byte de comando B.
a) CONFIGURACIN.- Para configurar el PPI se emplear la figura 3a. La instruccin a emplear sera: xout (0x7B, constante);
Donde: constante; es el obtenido de la palabra de control. 0x7B; es la direccin del puerto de configuracin.
Ejemplo 5.1: Configurar el PPI como: PA = entrada, PB = salida, y PC = entrada; MODO 0 Palabra de control: 1 0 0 1 1 0 0 1 = 99h La instruccin sera: xout (0x7B, 0x99);
Ejemplo 5.2: Configurar el PPI como: PA = salida, PB = entrada; MODO 1 (PC es no importa) Palabra de control: 1 0 1 0 X 1 1 X = A6h La instruccin sera: xout (0x7B, 0xA6);
Ejemplo 5.3: Configurar el PPI como: PA = salida; MODO 2 (PC es no importa) Palabra de control: 1 1 0 0 X 0 0 X = C0h La instruccin sera: xout (0x7B, 0xC0); b) ESCRITURA: Para enviar cualquier dato de 8 bits en sus puertos, se puede hacer de 2 formas; (1) a travs de una variable tipo char, y (2) enviar directamente el valor. Escribir en el PA: xout (0x78, var); o xout (0x78, 0x00); Escribir en el PB: xout (0x79, var); o xout (0x79, 57); Escribir en el PC: xout (0x7A, var); o xout (0x7A, 0xFF); c) LECTURA.- Para leer cualquier dato de 8 bits colocados en sus puertos es necesario designar una variable tipo unsigned char para almacenar el dato ledo. Leer del PA: y = xin (0x78); // y, almacena dato ledo del puerto. Leer del PB: z = xin (0x79); // z, almacena dato ledo del puerto. Leer del PC: p = xin (0x7A); // p, almacena dato ledo del puerto.
0 7 6 5 4 3 2 1 0 X X X Activar y desactivar bit 1 = activar 0 = desactivar Selecciona un bit
Ing. Javier Barriga Hoyle 8 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 6. Descripcin del TIMER 82C54 de la Tarjeta LPT- BYM V2.0 El Temporizador Programable TIMER 82C54, es un dispositivo de E/S que contiene tres contadores (temporizadores) de 16 bits independientes. Cada contador es capaz de contar en binario o decimal codificado en binario (BCD). La frecuencia mxima de entrada permitida para cualquier contador es de 10 MHz. Este dispositivo es til siempre que el microprocesador deba controlar eventos en tiempo real. Tambin se lo emplea para el control de velocidad y direccin de un motor de corriente continua (pwm). El TIMER puede programarse para trabajar con los tres contadores simultneamente y bajo 6 modos de operacin cualesquiera cada uno. Por ejemplo, se puede tener el contador 0 (CH0) operando a la frecuencia de 1 MHz - Modo 2, al contador 1 (CH1) operando a la frecuencia de 5 KHz Modo 3 y al contador 2 (CH2) operando a la frecuencia de 200 Hz Modo 4.
Figura 6.2. Esquemtico del TIMER 82C54 dentro de la Tarjeta.
El 82C54 se selecciona con su terminal CS para programarla (leer o escribir) en cada contador. La seleccin de sus contadores se logra mediante los terminales A1 y A0.
Ing. Javier Barriga Hoyle 9 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM A1 A0 FUNCION 0 0 0 1 1 0 1 1 Canal 0 (CH0) Canal 1 (CH1) Canal 2 (CH2) Registro de control
El TIMER de la tarjeta de interfase, tiene tres canales o contadores independientes CANAL 0 (CH0), CANAL 1 (CH1) y CANAL 2 (CH2). De los cuales:
CANAL 0: Opera con una frecuencia de entrada de 8 MHz (fija) proporcionada por un oscilador y es usado para generar retardos de precisin, por lo que su salida OUT 0, no est disponible para el usuario.
CANAL 1: Est disponible y puede operar a la frecuencia de 8 MHz colocando G1 (Gate) y CLK1 en el SW TIMER en ON. Pero, si desea usar distintas frecuencias de entrada, se tiene que colocar CLK1 en OFF, para impedir que ingrese los 8 MHz.
CANAL 2: Opera similar al canal 1, slo que se controla con G2 y CLK2.
6.1 Modos de Operacin del TIMER El TIMER presenta seis modos de operacin para cada uno de los contadores: Modo 0 a Modo 5. Modo 0: Permite usarlo como un contador de eventos. Por ejemplo, si es programada una cuenta de 7, la salida toma el valor 0 lgico por 7 cuentas iniciando en N.
OUT CLK N 1 2 3 4 5 6 7 Cuenta de 7 cargada
Modo 1: Funciona como un multivibrador monoestable redisparable. Por ejemplo, si la cuenta es 5, la salida toma el valor 0 lgico durante 5 periodos de reloj.
OUT CLK 1 2 3 4 5 Disparo con cuenta de 5 G
Modo 2: Permite que el contador genere una serie continua de pulsos (duty cycle aproximado de 90%). Se utiliza bastante para generar interrupciones. Por ejemplo, para una cuenta de 5, la salida toma el valor 1 lgico durante 4 periodos de reloj y el valor 0 lgico durante un periodo.
OUT CLK 1 2 3 4 5 1 2 3 Cuenta de 5 cargada 4 5 1 2 3 4 5 1 2 3 4
Ing. Javier Barriga Hoyle 10 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Modo 3: Permite generar una onda cuadrada en su salida (duty cycle aproximado de 50%). Si la cuenta es par, la salida permanece en 1 durante la mitad de la cuenta y en 0 durante la otra mitad. Si la cuenta es impar, la salida permanece en 1 por un periodo de reloj ms del tiempo que est en estado 0. Por ejemplo, para una cuenta de 5, la salida es 1 durante tres periodos de reloj y en 0 durante dos periodos.
OUT CLK 1 2 3 4 5 6 1 2 Cuenta de 5 cargada 3 4 5 6 1 2 3 4 5 6 1
Modo 4: Permite que el contador genere un solo pulso en su salida. Por ejemplo, si la cuenta es programada con un 8, la salida permanece en alto durante 8 periodos de reloj y en estado bajo durante un periodo.
OUT CLK 1 2 3 4 5 6 7 8 Disparo con cuenta de 8
Modo 5: Un circuito monoestable disparado por hardware que funciona como el modo 4, excepto que es iniciado por un pulso de disparo en la terminal G, en vez de por software. Este modo tambin es parecido al modo 1 porque es redisparable.
OUT CLK 1 2 3 4 5 Disparo con cuenta de 5 G
NOTA: Para mayor informacin sobre estos modos, puede consultar el datasheet del 82C54. 6.2 Programacin del TIMER Cada contador es programado individualmente escribiendo una palabra de control, seguida por la cuenta inicial. La figura 6, muestra la estructura de la palabra de control, que permite al programador seleccionar al contador, el modo y el tipo de operacin (lectura o escritura).
SC1 SC0 RW1 RW0 M2 M1 M0 BCD D7 0 0 1 1 0 1 0 1 Elegir contador Contador 0 Contador1 Contador 2 Comando Read Back 0 0 1 1 0 1 0 1 Operacin: Comando de enclavamiento Leer/escribir byte bajo Leer/escribir byte alto Leer/escribir byte bajo y despus el alto 0 0 x x 1 1 0 0 1 1 0 0 0 1 0 1 0 1 Modo: Modo 0 Modo 1 Modo 2 Modo 3 Modo 4 Modo 5 0 1 Contador: Binario 16 bits BCD de 4 dcadas D6 D5 D4 D3 D2 D1 D1
Figura 6.3. Palabra de control del TIMER.
Ing. Javier Barriga Hoyle 11 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM La palabra de control selecciona tambin una cuenta binaria o BCD. Cada contador puede programarse con una cuenta de 1 a FFFFh. Una cuenta de 0 es igual a FFFFh + 1 (65536) o 10000 en BCD. La cuenta mnima de 1 es aplicable a todos los modos de operacin excepto los modos 2 y 3, las cuales tienen una cuenta mnima de 2. a) CONFIGURACION: Ejemplo 6.1: Configurar el CH0 del TIMER en modo 2, cuenta binaria, operacin leer y escribir byte bajo y luego el byte alto. Palabra de control: 00110100 = 34h La instruccin sera: xout (0x77, 0x34);
Ejemplo 6.2: Configurar el CH1 del TIMER en modo 3, cuenta binaria, operacin leer y escribir byte bajo y luego el byte alto. Palabra de control: 01110110 = 76h La instruccin sera: xout (0x77, 0x76);
Ejemplo 6.3: Configurar el CH2 del TIMER en modo 4, cuenta binaria, operacin leer y escribir byte bajo y luego el byte alto. Palabra de control: 10111000 = 0B8h La instruccin sera: xout (0x77, 0xB8);
b) OPERACIONES DE ESCRITURA: El 82C54 es muy flexible a la hora de ser programado. Basta con tener en cuenta dos cosas: Primero, escribir siempre la palabra de control, antes de enviar la cuenta inicial al contador. Segundo, dicha cuenta inicial debe seguir exactamente el formato seleccionado en la palabra de control (enviar slo Byte bajo, enviar slo Byte alto, o bien enviar ambos consecutivamente). Teniendo en cuenta que cada contador tiene su propio puerto y que la palabra de control indica el contador al que est asociada, no hay que seguir un orden especial a la hora de programar los contadores. Esto significa que, por ejemplo, se puede enviar la palabra de control de cada contador seguida de su cuenta inicial, o bien enviar todas las palabras de control para los 3 contadores y despus las 3 cuentas iniciales.
Ejemplo 6.4: Programe el CH0 del TIMER para obtener una seal cuadrada con frecuencia de 200 Hz, sabiendo que la frecuencia de entrada es de 8 MHz.
void main () { // Configura el canal 0 (CH0) xout(0x77, 0x36); // CH0, Modo 3, cuenta binario
// Frecuencia de entrada al CH0 = 8 MHz. Para obtener una frecuencia de 200 Hz // (T=5 ms), se tiene que dividir (8 MHz/200 Hz)= 40000; ==> el factor N = 9C40h
xout (0x74, 0x40); // Se enva Byte LSB al CH0 xout (0x74, 0x9C); // Se enva Byte MSB al CH0 }
Ing. Javier Barriga Hoyle 12 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Ejemplo 6.5: Programe el CH1 y CH2 del TIMER para obtener una seal cuadrada con frecuencia de 1 KHz en el CH1 y una seal para generar interrupciones de 250 Hz en el CH2. La frecuencia de entrada es de 8 MHz.
void main () { /* Configura el canal 0 (CH0) y el canal 1 (CH1) */ xout(0x77, 0x76); // CH1, Modo 3, cuenta binario xout(0x77, 0xB4); // CH2, Modo 2, cuenta binario
/* Frecuencia de entrada al CH1=CH2= 8 MHz. Para obtener una frecuencia de 1 KHz en CH1, se tiene que dividir (8 MHz/1 KHz)= 8000; ==> el factor N1 = 1F40h. Para obtener una frecuencia de 250 Hz en CH2, se tiene que dividir (8 MHz/250 Hz)= 32000; ==> el factor N2 = 7D00h. */
xout (0x75, 0x40); // Se enva Byte LSB al CH1 xout (0x75, 0x1F); // Se enva Byte MSB al CH1 xout (0x76, 0x00); // Se enva Byte LSB al CH2 xout (0x76, 0x7D); // Se enva Byte MSB al CH2 }
c) OPERACIONES DE LECTURA: Existen tres posibles mtodos para leer el valor de un contador en el 8254. El primero es el comando de enclavamiento, el segundo consiste en el comando Read-Back, slo disponible en el 8254 (y no en el 8253), y el tercer mtodo consiste en leer simplemente el contador accediendo al puerto correspondiente (este mtodo requiere inhibir la entrada CLK al contador) con objeto de evitar leer la cuenta en medio de un proceso de actualizacin de la misma, lo que dara un resultado incorrecto. Comando de enclavamiento
SC1 SC0 0 0 X X X X D7 D6 D5 D4 D3 D2 D1 D0 Selecciona contador 00 - Contador 0 01 - Contador 1 10 - Contador 2
Figura 6.4. Comando de enclavamiento.
Comando Read-back:
1 1 COUNT STATUS CNT 2 CNT 1 CNT 0 0 D7 D6 D5 D4 D3 D2 D1 D0 Selecciona bits del contador Estado del registro de los contadores seleccionados Cuenta del registro de los contadores seleccionados
Figura 6.5. Comando Read-Back.
Cuando se hace uso de este comando enviando 11010010, el TIMER devuelve solo la cuenta actual del contador 0; pero si se enva 11000010, el TIMER devuelve la cuenta en el contador 0 y su registro de estado con la informacin de la figura 6.6.
Ing. Javier Barriga Hoyle 13 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM OUTPUT NULL COUNT RW1 RW0 M2 M1 M0 BCD D7 D6 D5 D4 D3 D2 D1 D0 valor de la patilla OUT 1 0 "Null Count" Cuenta disponible para ser ledo Modo del contador Contador: 0 - Binario 16 bit 1 - BCD 4 dcadas Operacin de lectura/escritura
Figura 6.6. Registro de estado (status).
Ejemplo 6.6: Leer la cuenta del canal 1 (CH1) y canal 2 (CH2) usando el comando de enclavamiento (slo se muestra las instrucciones principales).
void main () { unsigned char X1, X2, Y1, Y2;
xout(0x77, 0x40); // Se enva palabra de enclavamiento del CH1 X1 = xin(0x75); // Lee Byte LSB X2 = xin(0x75); // Lee Byte MSB
xout(0x77, 0x80); // Se enva palabra de enclavamiento del CH2 Y1 = xin(0x76); // Lee Byte LSB Y2 = xin(0x76); // Lee Byte MSB }
Ejemplo 6.7: Leer las cuentas del canal 0 (CH0), canal 1 (CH1) y canal 2 (CH2) usando el comando Read-Back (slo se muestra las instrucciones principales)..
void main() { unsigned char X1,X2,Y1,Y2,Z1,Z2;
xout(0x77, 0xDE); // Se enva comando Read-back
X1 = xin(0x74); // Lee Byte LSB del CH0 X2 = xin(0x74); // Lee Byte MSB del CH0
Y1 = xin(0x75); // Lee Byte LSB del CH1 Y2 = xin(0x75); // Lee Byte MSB del CH1
Z1 = xin(0x76); // Lee Byte LSB del CH2 Z2 = xin(0x76); // Lee Byte MSB del CH2 }
Ejemplo 6.8: Usando el comando Read-Back, leer la cuenta y estado del canal 1 (CH1). Almacenar en estado el Byte de estado y en data la cuenta (slo se muestra las instrucciones principales).
xout(0x77, 0xC4); // Enva comando Read-back para CH1 estado = xin(0x75); // Lee Byte de estado del CH1 data_low = xin(0x75); // Lee el valor de cuenta (LOW) del CH1 data_high = xin(0x75); // Lee el valor de cuenta (HIGH) del CH1 data = data_high<<8 | data_low; // Se unen para formar un word }
Ing. Javier Barriga Hoyle 14 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 7. Descripcin del Conversor Anlogo Digital ADC0804 de la Tarjeta LPT- BYM V2.0 Este convertidor anlogo digital de 8 bits es un ADC comn de bajo costo y se utiliza en aplicaciones que no requieren un alto grado de exactitud. Por ejemplo, requiere hasta 100 S para convertir una entrada analgica de voltaje a una salida en cdigo digital. El reloj se genera con un circuito RC y se conectan a las entradas CLK IN y CLKR. Para una frecuencia de 640 KHz, el tiempo de conversin es aproximadamente 100 S y se calcula con la siguiente ecuacin: Fclk = 1 / (1.1 R*C). El reloj del ADC en esta tarjeta est controlado por un potencimetro de 10K y un condensador de 150 pF. El valor de R debe estar cerca de los 10K para conseguir una frecuencia entre <600-640> KHz.
Figura 7.2. Esquemtico del ADC0804 dentro de la Tarjeta.
Para trabajar con un convertidor analgico digital (ADC), se debe preferiblemente leer la hoja de datos del fabricante. Pero, todos por lo general siguen estos pasos: a) Para capturar el dato analgico y empezar la conversin se debe activar la seal WR. Es decir, enviar un pulso bajo (WR = 0), por un tiempo pequeo (aproximado 300 ns). Esto se consigue enviando cualquier valor (por ejemplo: 00h) por el puerto donde est mapeado el ADC.
Ing. Javier Barriga Hoyle 15 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM En nuestro caso, para el puerto paralelo, las macros diseadas para el uso con la tarjeta permiten generar las seales RD, WR y operarla como si se estuviera trabajando con el BUS ISA.
Assembler:
MOV AL, 00h ; Cargo cualquier dato en AL XOUT 6CH, AL ; Se enva el dato 0 (WR = 0)
Lenguaje C:
xout(0x6C, 0x00); // Se enva el dato 0 (WR = 0)
Si se est trabajando con el BUS ISA y el ADC est mapeado en el puerto de E/S 0300h, entonces las instrucciones a usar seran:
Assembler:
MOV AL, 00h ; Cargo cualquier dato en AL MOV DX, 300h ; Carga direccin del puerto OUT DX, AL ; Se enva el dato 0 (WR = 0)
Lenguaje C:
outportb(0x300,0x00); // Se enva el dato 0 (WR = 0)
b) El ADC toma un tiempo para realizar la conversin (aproximadamente 100 s), luego del cual pone en CERO el pin INTR para avisar que el dato (digital) est listo para ser ledo. Para realizar la lectura por el puerto existen tres formas:
Tcnicas para la lectura del dato digital en el ADC Espera: Consiste en que una vez activada la seal WR (paso (a)), generar un retardo que sea mayor que el tiempo de conversin del ADC (Por ejemplo, 1 ms), y luego proceder a leer el dato digital. Ver diagrama de flujo.
Activar la seal WR Retardo de 1 mseg Leer dato digital del ADC
Programa: xout(0x6C,0x00); // Empieza conversin (WR = 0) delay(1); // Espero 1 ms para que convierta dato_adc = xin(0x6C); // Lee el dato digital
Ing. Javier Barriga Hoyle 16 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Polling (encuesta): Consiste en que una vez activada la seal WR (paso (a)), empezar a testear si la seal INTR del ADC est en cero. Si es cero, leer el dato, caso contrario seguir testeando. Este modo es mucho mejor que el anterior y es el adecuado cuando no se usa interrupciones. Ver diagrama de flujo.
Activar la seal WR Leer dato digital del ADC INTR = 0? NO SI
Programa: xout(0x6C,0x00); // Inicio conversin while(flag_int != 0x40) // testeo si INTR=0? (pin 10, puerto 379h) { flag_int = inportb(0x379)&0x40; // Lee para ver si INTR = 0 (bit 6) } dato_adc = xin(0x6C); // Lee dato del ADC
Interrupciones Para emplear esta tcnica se tiene que hacer uso de la lnea de interrupcin IRQ7 y del vector 15. En este caso el programa es ms complicado y se requiere conocer muy bien los conceptos de interrupciones, vectores de interrupcin y mscara de interrupcin (ver Apndice D). Al final de este manual se tendr varios programas ejemplos que hacen uso de las interrupciones.
PUERTO 6Ch IRQ7 PROGRAMA RTI del ADC DIR. BASE 378H ADC0804 CPU
Ing. Javier Barriga Hoyle 17 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 8. Descripcin del Conversor Digital Anlogo DAC0830 de la Tarjeta LPT- BYM V2.0 Este dispositivo es un convertidor digital anlogo que transforma un nmero binario de 8 bits en un voltaje analgico. El nmero de niveles de voltaje que genera el convertidor es igual al nmero de combinaciones de entradas binarias. Es decir, un convertidor de 8 bits genera (2 8 ) 256 niveles de voltaje distintos, un convertidor de 10 bits genera (2 10 ) 1024 niveles y as sucesivamente. El DAC0830 es un convertidor de velocidad media que transforma una entrada digital en una salida analgica en aproximadamente 1.0 s.
Figura 8.2. Esquemtico del DAC0830 dentro de la Tarjeta.
Este convertidor tiene un bus de datos de 8 bits para la conexin del cdigo digital de entrada y un par de salidas analgicas llamadas Iout1 e Iout2, las cuales estn diseadas como entradas para un amplificador operacional externo. Como es un conversor de 8 bits, la amplitud de paso del voltaje de salida est definida como -Vref (voltaje de referencia) dividido entre 255. Por ejemplo, si el voltaje de referencia es -5.0 V, la amplitud del paso de voltaje ser de +0.0196 V. Observe que el voltaje de salida es de polaridad opuesta al de referencia. La amplitud del paso de voltaje tambin se conoce como resolucin del convertidor.
8.1 Estructura interna del DAC0830 La figura 8.3, muestra la estructura interna del DAC, el cual contiene dos registros internos. El primero es un registro de retencin, mientras que el segundo est conectado al convertidor de escalera interno R-2R. Los dos registros permiten retener un byte mientras otro es convertido. En
Ing. Javier Barriga Hoyle 18 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM muchos casos, deshabilitamos el primer registro y utilizamos solamente el segundo para aplicar datos al convertidor, esto puede lograrse conectando un 1 lgico a ILE y un 0 lgico a CS.
Figura 8.3. Estructura interna del DAC0830.
Ambos registros son transparentes. Es decir, cuando la entrada LE tiene un nivel 1 lgico, el dato atraviesa el registro, pero cuando la entrada LE asume el estado lgico 0, el dato es retenido. El convertidor tiene una terminal de entrada de referencia (Vref) que establece la amplitud del voltaje de salida de escala completa. Si -10 V son aplicados a Vref, el voltaje de salida a escala completa (11111111 2 ) es +10 V. La salida del convertidor R-2R aparece en Iout1 e Iout2. Estas salidas estn diseadas para aplicarse a un amplificador operacional como el 741 o equivalente.
Ing. Javier Barriga Hoyle 19 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 9. Sistema Operativo y uso de la Tarjeta LPT ByM V2.0 Para utilizar esta Tarjeta de una manera correcta, depender del Sistema Operativo y del Lenguaje C empleado. La siguiente tabla muestra el archivo de cabecera o librera adecuada a usar.
Lenguaje Window98 Windows 2000 o XP Borland C++ 3.0
Visual C++ 6.0 #include <BymDos.h>
#include <BymWin.h> #include <BymDos.h>
#include <BymWin.h>
Por las caractersticas del Sistema Operativo que est usando se tiene que tener en cuenta lo siguiente: Windows 98: El acceso al puerto paralelo es libre (no protegido), as que no hay problema de correr los programas propuestos incluso los de interrupciones. Windows 2000 o XP: El acceso al puerto paralelo est protegido, por lo que es necesario desprotegerlo antes de ejecutar cualquier programa. Para ello se utiliza el UserPort 1.0, el cual desprotege el puerto paralelo, pero no se puede ejecutar programas con interrupciones (IRQ7). Adems, dentro del programa principal se debe colocar la instruccin: inicio_tarjeta(), que se encarga de poner todas las seales de control de los circuitos integrados en un valor que evite conflictos, tales como RD = 1, WR =1 y los CS = 1. 9.1 Uso del UserPort (Win2000 o WinXP) Para utilizar este programa que permite desproteger y emplear el puerto paralelo, primero tiene que copiarse el archivo UserPort.sys en la carpeta:
C:\WINNT\system32\drivers\UserPort.sys
Luego, deber dar doble clic en el siguiente icono.
Aparecer el siguiente cuadro:
NOTA: Como el puerto paralelo est en la direccin 378h, y est comprendido en los rangos mostrados por defecto. Entonces: Para empezar a trabajar pulse el botn de Start. Para terminar pulse el botn de Stop. Para salir del UserPort pulse Exit.
Ing. Javier Barriga Hoyle 20 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 9.2 Estructura de un programa en Lenguaje C A continuacin se muestra un formato de cmo se debe escribir los programas escritos en Lenguaje C para WINDOWS (Visual C++) o DOS (Turbo C++), empleando los archivos de cabecera mnimos que requiere la tarjeta para operar. Depender del programa escrito para agregar ms archivos de cabecera. La librera BymWin.h deber copiarse dentro de:
C:\Archivos de programa\Microsoft Visual Studio\VC98\Include\BymWin.h
La librera BymDos.h deber copiarse dentro de:
C:\TC\Include\BymDos.h
VISUAL C++ (Sistema Operativo Win98, Win2000, WinXP):
#include <windows.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
void main (void) // Inicializa Tarjeta de interfase LPT V2.0 { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
Ing. Javier Barriga Hoyle 21 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 10. Aplicaciones del PPI 82C55 Los siguientes programas escritos en Lenguaje C, muestran como utilizar el PPI en algunas aplicaciones bsicas. 10.1 LEDS y DIPSWITCH Implemente el circuito mostrado (vlido para los programas PPI_1, PPI_2, PPI_3 y PPI_4). Cargue el Visual C++ 6.0 en modo consola. Puede usar Win98, Win2000 o WinXP. Escriba los siguientes programas y luego para ejecutarlos deber tener en cuenta el sistema operativo que est usando (captulo 9). Los esquemticos de salida a 8 leds y entrada digital de 8 bits, estn en el Apndice E1 y E2.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ 0s 1s Entrada digital (8 bits) Salida digital (8 leds)
Figura 10.1. Conexin Tarjeta Leds Dipswitch (programas 10.1, 10.2, 10.3 y 10.4).
Programa 10.1: (PPI_1.CPP) /******************************************************************************** PPI_1.CPP Este programa lee un dato digital de 8 bits por el PORTB del PPI y lo enva por el PORTA para ser visualizado en 8 Leds.
Descripcin: a) Conecte con un cable flat el PB del PPI con un dipswitch de 8 bits que permita ingresar datos digitales a la tarjeta. b) Conecte con un cable flat el PA del PPI con 8 Leds que permita visualizar los datos digitales enviados por el microprocesador. c) Escriba el programa en Visual C++ (modo consola). d) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5) e) Ejecute su programa dndole diferentes valores al dipswitch y observar que el valor colocado se visualizar en los leds. f) Repita el paso (e) cuantas veces crea necesario.
Autor: Ing. Javier Barriga Hoyle *******************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
Ing. Javier Barriga Hoyle 22 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM unsigned char data;
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
xout(0x7B, 0x82); // Configura PPI -> PA=out, PB=in, PC=out data = xin(0x79); // Se lee dato del PB del PPI xout(0x78, data); // Se enva por PA del PPI }
Programa 10.2: (PPI_2.CPP) /******************************************************************************** PPI_2.CPP Este programa emplea el PA del PPI para generar intermitencia en los 8 leds. Es decir, enva el dato 0xFF (leds ON) luego de 1/2 Seg. se enva 0x00 (leds OFF). La operacin se realiza 10 veces.
Descripcin: a) Conecte con un cable flat el PA del PPI con 8 leds que permita ver los datos digitales enviados por el Computador. b) Escriba el programa en Visual C++ (modo consola) c) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
int i;
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
xout(0x7B, 0x82); // Configura PPI -> PA=out, PB=in, PC=out for(i=0; i<10; i++) // Bucle de 10 veces de repeticin { xout(0x78, 0xFF); // Leds ON Sleep(200); // Retardo de 200 ms xout(0x78, 0x00); // Leds OFF Sleep(200); } }
Programa 10.3: (PPI_3.CPP) /******************************************************************************** PPI_3.CPP Este programa a travs del PA del PPI genera prendido secuencial a la izquierda y luego se apaga secuencialmente a la derecha. La operacin se realiza 10 veces a intervalos de 150 ms.
Descripcin: a) Conecte con un cable flat el PA del PPI con 8 leds que permita visualizar los datos digitales enviados por el microprocesador a travs del PPI. b) Escriba el programa en Visual C++ (modo consola) c) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5) Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h>
Ing. Javier Barriga Hoyle 23 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
/* Variables globales */ int i; unsigned char p;
/* Inicia programa principal */ void main () { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x82); // Configura PPI -> PA=out, PB=in, PC=out
/* Prendido secuencial a la izquierda */ p = 0x01; // p = 0000 0001b for(i=0; i<10; i++) { while(p != 255) { xout(0x78, p); // Se enva al PA del PPI Sleep(150); // Retardo de 150 ms p = p << 1; // Desplaza un bit a la izquierda p = p | 0x01; // OR lgica }
// Apagado secuencial a la derecha while(p != 0) { xout(0x78, p); // Se enva al PA del PPI Sleep(150); // Retardo de 150 ms p = p >> 1; // Desplaza un bit a la derecha } } xout(0x78, 0x00); // Se apaga los leds }
Programa 10.4: (PPI_4.CPP) /******************************************************************************** PPI_4.CPP Este programa prende secuencialmente los bits desde los extremos al centro y luego se apaga hacia los extremos (muy vistoso).
Descripcin: a) Conecte con un cable flat el PA del PPI con 8 leds que permita ver los datos digitales enviados por el Computador. b) Escriba el programa en Visual C++ (modo consola) c) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
/* Variables globales */ unsigned char x, y, z; int i, j;
void main(void) // Inicia programa principal
Ing. Javier Barriga Hoyle 24 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x82); // Configura PPI -> PA=out, PB=in, PC=out x = 0; for(i=1 ;i<=5; i++) // Bucle de 5 veces de repeticion { y = 0x01; // Inicializa variables z = 0x80; for(j=1;j<=8;j++) // Bucle de 8 veces { xout(0x78,x); // Se enva por el PORTA Sleep(150); // Retardo de 150 ms x = x^y; // OR-exclusiva x = x^z; y = y<<1; // Desplaza un bit a la izquierda z = z>>1; // Desplaza un bit a la derecha } } xout(0x78,0x00); // Apaga los leds }
10.2 DISPLAY DE CRISTAL LQUIDO (LCD) Implemente el circuito mostrado y siga las recomendaciones dados en el captulo 9. La informacin sobre el LCD como es ms extensa se encuentra en un archivo LCD.pdf
Programa 10.5: (PPI_5.CPP) Programa que enva mensaje al LCD
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ LCD 2x16 HD 44780 G N D V C C V L C R s R
/
W E n D 0 D 1 D 2 D 3 D 4 D 5 D 6 D 7 LEYENDA: D[7..0] Bus de datos En Seal de habilitacin R/W Seleccin de lectura (0) o escritura (1) Rs Selector de registro (0 = Reg. Inst, 1 = Reg. Datos) VCC Tensin de alimentacin, 5 V. GND Entrada de alimentacin, 0 V. VLC Entrada de control de constraste (unir al potenciometro)
Figura 10.2. Conexin Tarjeta - LCD.
/******************************************************************************** PPI_5.CPP (Modo a 4 bits) Este programa enva 2 mensajes a un LCD de 2x16, usando el PortA del PPI de la Tarjeta LPT V2.0
Descripcin: a) Las conexiones PPI - LCD es: PORTA del PPI: PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 LCD: D7 D6 D5 D4 EN RS X X (La seal WR se conecta a tierra, porque en este programa solo se escribe en el LCD). b) Cree un proyecto en Visual C++ (modo consola) y escriba el programa.
Ing. Javier Barriga Hoyle 25 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM c) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). d) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
#define CONTROL 0 // Constante para el display LCD #define DATO 1 // Constante para el display LCD #define DISPLAY_ON 0x0E // Display ON, cursor ON, blink OFF #define BORRAR_LCD 0x01 #define UCHAR unsigned char
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA = PB = PC = outs InitLCD(); // Inicializa LCD
Ing. Javier Barriga Hoyle 26 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Funcin: void InitLcd(void) Inicializa el display LCD. -------------------------------------------------------------------------------*/ void InitLCD(void) { xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 /* RS debe ser estable antes del flanco de subida de EN */ xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(5); // Demora superior a 4,1 ms
xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(1); // Demora superior a 100 s
xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(1); // Demora superior a 100 s /* Selecciona interface de 4 bits */ xout(0x78, 0x28); // DB[7..4] EN RS X X // 0010 1 0 0 0 xout(0x78, 0x20); // DB[7..4] EN RS X X // 0010 0 0 0 0
/* Tras esta inicializacin el display queda en modo 4 bits */ Sleep(1); // Demora superior a 100 s BorraLCD(); // Borra el LCD y lleva cursor al origen } // FIN DE InitLcd
/*------------------------------------------------------------------------------- Funcin: void PutcharLcd(UCHAR direc, UCHAR dato) Envia al display LCD un "dato". Si: direc = 0, se accede al registro de instrucciones direc = 1, se accede al registro de datos -------------------------------------------------------------------------------*/ void PutcharLCD(UCHAR direc, UCHAR dato) { UCHAR temp, temp2; temp2 = 0x08; // Para activar EN if (direc == DATO) // Es instruccin o dato? { temp2 |= 0x04; // Selecciona Dato/Control con RS xout(0x78, 0x04); // DB[7..4] EN RS X X } // 0000 0 1 0 0 else xout(0x78, 0x00); // DB[7..4] EN RS X X // 0000 0 0 0 0 /* RS debe ser estable antes del flanco de subida de EN */
/* Primero se enva el nibble alto */ temp = (dato & 0xf0) | temp2; xout(0x78, temp); // Manda nibble alto con EN = 1 temp &= 0xf5; xout(0x78, temp); // Desactiva EN
/* Despus se manda el nibble bajo */ temp = (dato << 4) | temp2; xout(0x78, temp); // Manda nibble bajo con EN = 1 temp &= 0xf5; xout(0x78, temp); // Desactiva EN
Ing. Javier Barriga Hoyle 27 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Sleep(1); } // FIN DE PutcharLcd
/*------------------------------------------------------------------------------- Funcin: void BorraLCD(void) Establece control del LCD, Borra el LCD, establece Modo de entrada, y pone el cursor en el origen. -------------------------------------------------------------------------------*/ void BorraLCD(void) { PutcharLCD(CONTROL, DISPLAY_ON); // Display on, cursor ON, blink off PutcharLCD(CONTROL, BORRAR_LCD); // Borrar el Display PutcharLCD(CONTROL, 0x06); // Incremento automtico de AC al escribir PutcharLCD(CONTROL, 0x02); // Cursor en la esquina izquierda } // FIN DE BorraLCD
/*------------------------------------------------------------------------------- Funcin: void GotoxyLCD(UCHAR fila, UCHAR columna) Posiciona el cursor en la posicin especificada por fila, columna. Si alguna de las coordenadas es invalida no se hace nada. Coordenadas validas: fila = 1..2, columna = 1..16 -------------------------------------------------------------------------------*/ void GotoxyLCD(UCHAR fila, UCHAR columna) { UCHAR pos_fila, cursor; if((fila<1 || fila>2) || (columna<1 || columna>16)) return; switch(fila) { case 1: pos_fila = 0x80; // Posicin de memoria 00h ---> 27h cursor = pos_fila + columna; PutcharLCD(CONTROL, cursor); // Posiciona cursor break;
Ing. Javier Barriga Hoyle 28 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 10.3 TECLADO HEXADECIMAL 4x4 El teclado matricial mostrado en la figura es uno de los ms comunes que existen en el mercado, por ello, saber usarlo es indispensable para cualquier proyecto que se tenga que ingresar datos como: claves, parmetros de temperatura, etc. El teclado tiene 9 pines, de los cuales, 4 corresponden a las filas, 4 corresponden a las columnas y un pin que no se usa. Para utilizarlo en un circuito con Microprocesador o Microcontrolador, es necesario conectarle 4 resistencias de 10K a +5V en las columnas (pull up).
1 2 3 F 4 5 6 E 7 8 9 D A 0 B C F 0 F 1 F 2 F 3 C 1 C 2 C 3 X 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C + 5V 10 K Fila 0 Fila 1 Fila 2 Fila 3 C o l u m n a
0 C o l u m n a
1 C o l u m n a
2 C o l u m n a
3 D0 D1 D2 D3 D4 D5 D6 D7 Pines del teclado C 0
(a) (b)
Figura 10.3. (a) Diagrama del teclado, (b) Forma de utilizarlo.
Para programar al teclado se puede hacer de dos maneras: Explorar directamente el teclado a travs de filas y columnas, o usando un decodificador de teclado.
Explorar filas y columnas:
1 2 3 F 4 5 6 E 7 8 9 D A 0 B C + 5V 10 K 0 1 1 1 1 1 0 1 Tecla pulsada Fila 0, activa
Filas Columnas Mtodo: Se enva por las filas el nibble 1110, en ese instante se activa toda la fila 0, y las dems filas estarn inactivas. Se pulsa el nmero 3, entonces al leerse las columnas se tendr el nibble 1011. Con ambos nibbles (1011 1110), se puede determinar el cdigo correspondiente de la tecla pulsada.
Figura 10.4. Exploracin de teclado.
Para explorar el teclado y averiguar en cada instante cul es la tecla pulsada, se sigue el siguiente mtodo. Se trabaja con el nivel lgico HIGH (1) actuando como inactivo y el nivel lgico LOW (0) como activo. Por los terminales de las filas del teclado se introducen cuatro niveles lgicos, uno
Ing. Javier Barriga Hoyle 29 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM activo (0) y los otro tres inactivos (1). Si existe alguna tecla pulsada en la fila por la que tiene el nivel LOW, dicho nivel saldr por la columna correspondiente con la que se haga contacto. En consecuencia, leyendo los estados lgicos de los terminales de las columnas (C3,C2,C1,C0) averiguaremos si hay alguna tecla pulsada en la fila por la que se ha introducido el nivel LOW, ya que si no hay ninguna en todas las columnas se leer nivel HIGH inactivo. Procediendo secuencialmente a introducir el nivel LOW por cada una de las cuatro filas y a leer los niveles de salida de las columnas, se podr determinar la tecla pulsada en cada momento.
Programa 10.6: (PPI_6.CPP) Lectura del teclado hexadecimal mediante exploracin de teclas. Implemente el circuito mostrado y siga las recomendaciones dados en el captulo 9. No olvide que la forma de conectar un teclado es como en la figura 10.3(b).
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C Salida digital (8 leds) Columnas Filas
Figura 10.5. Conexin Tarjeta - PPI - Teclado.
/******************************************************************************** PPI_6.CPP (MODO 0) Este programa explora las filas y columnas del teclado para determinar en cualquier instante el cdigo de la tecla pulsada. Para ello se conecta el PortC del PPI al teclado. El valor ledo se muestra en pantalla y en los LEDS conectados al PortA del PPI. Se sale del programa cuando se pulsa ESC.
Descripcin: a) Las conexiones PPI - TECLADO es: PORTC del PPI: PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0 TECLADO: C3 C2 C1 C0 F3 F2 F1 F0
b) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. c) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). d) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo /* Prototipos */
Ing. Javier Barriga Hoyle 30 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM unsigned char keyNumber(unsigned char dato); unsigned char kbRead(unsigned char tec);
/* Variables globales */ unsigned char tecla,ncol,scan,car; int Fin;
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
xout(0x7B, 0x88); /* Configura PPI con PA=PB=OUTs (modo 0) PC[7..4]=IN, PC[3..0]=OUT (modo 0) */ Fin = 0; while(!Fin) // Espera ESC para terminar { scan = 0xfe; // Byte de inicio de scan de teclado ncol = 4; // Nmero de columnas a explorar for(ncol; ncol>0; ncol--) { xout(0x7A, scan); // Enva dato al PortC Sleep(10); // Retardo de 10 ms car = xin(0x7a); // Lee el teclado (columna, fila) if((scan-car) != 0) // Se ha pulsado tecla? { tecla = kbRead(car); // Devuelve cdigo tecla vlido printf("Tecla pulsada = %c \n",tecla); Sleep(200); // Retardo para eliminar rebote xout(0x78, tecla); // Se enva a los leds } scan = (scan<<1) | 1; // Selecciona siguiente fila } if(kbhit()) // Se puls tecla de la PC? { car = getch(); // SI, Lee del teclado if(car == 0x1B) Fin = 1; // Si es ESC, sale del programa } } } /* Fin de main */
/*---------------------------------------------------------------------------- Determina el nmero de la tecla pulsada. Realiza la operacin: "nmero = fila * 2 + columna". -----------------------------------------------------------------------------*/ unsigned char keyNumber(unsigned char dato) { unsigned char fila,col; fila = dato & 0x0f; switch(fila) { case 0x0e: fila=0; break; /* 0000.111_ */ case 0x0d: fila=1; break; /* 0000.11_1 */ case 0x0b: fila=2; break; /* 0000.1_11 */ case 0x07: fila=3; break; /* 0000._111 */ default: fila=0xff; break; } col = dato & 0xf0; // Lee para determinar la columna switch(col) { case 0xe0: col=0; break; /* 111_.0000 */ case 0xd0: col=1; break; /* 11_1.0000 */ case 0xb0: col=2; break; /* 1_11.0000 */ case 0x70: col=3; break; /* _111.0000 */ default: col=0xff; break; } if((fila == 0xff)||(col == 0xff))
Ing. Javier Barriga Hoyle 31 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM col = 0xff; // Retorna tecla pulsada invlida else col = (fila<<2) + col; /* Determina el nmero de la tecla pulsada */ return(col); } /* fin de keyNumber */
/*---------------------------------------------------------------------------- Determina el cdigo de la tecla pulsada y devuelve el cdigo ASCII. -----------------------------------------------------------------------------*/ unsigned char kbRead(unsigned char tec) { /* La siguiente tabla se usa para hallar el cdigo de cada tecla */ unsigned char kbTable[16]={'1', '2', '3', 'F', /* fila 0 */ '4', '5', '6', 'E', /* fila 1 */ '7', '8', '9', 'D', /* fila 2 */ 'A, '0', 'B', 'C'}; /* fila 3 */
tecla = keyNumber(tec); // Codifica tecla en fila, columna if(tecla != 0xff) // Si solo se ha pulsado una tecla, traduce tecla = kbTable[tecla]; // desde kbTable el cdigo de tecla return(tecla); // Retorna tecla pulsada } /* fin de kbRead */
Usando decodificador de teclado 74C922 Se encarga de realizar la exploracin de filas y columnas, nuestro programa es ms sencillo ya que slo se testea la lnea de control (data available) y cuando la lnea est activa, se lee los 4 bits de datos correspondientes a la tecla pulsada. La lnea output enable lo podemos conectar a tierra.
1 74C922 2 3 4 5 6 7 8 9 18 17 16 15 14 13 12 11 10 COLUMN X3 GND VCC DATA OUT A DATA OUT B DATA OUT C OUTPUT ENABLE DATA AVAILABLE COLUMN X1 COLUMN X2 ROW Y1 ROW Y2 ROW Y3 ROW Y4 OSCILADOR KEYBOUNCE MASK COLUMN X4 DATA OUT D X4 Data D 74C922 X3 X2 X1 Y4 Y3 Y2 Y1 Data Available Data C Data B Data A DA D C B A Output Enable OE OSC Oscilador Keybounce Mask KBM Row Y1 Row Y2 Row Y3 Row Y4 Column X1 Column X2 Column X3 Column X4
(a) (b)
Figura 10.6. (a) Circuito Integrado 74C922, (b) Diagrama simplificado del decodificador.
X4 74C922 X3 X2 X1 Y4 Y3 Y2 Y1 DA D C B A OE O S C K B M 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C + 5V 10 K PC7 PC3 PC2 PC1 PC0 22 uF 2.2 uF
P P I
Figura 10.7. Diagrama de conexin: Decodificador y Teclado.
Ing. Javier Barriga Hoyle 32 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 10.7: (PPI_7.CPP) Manejo del Teclado hexadecimal a travs de un decodificador. Implemente el circuito mostrado y siga las recomendaciones dados en el captulo 9. No olvide que la forma de conectar un teclado es como en la figura 10.3(b).
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C Salida digital (8 leds) Filas Columnas Y[4..1] X[4..1] Data out 74C922
Figura 10.8. Conexin Tarjeta - Decodificador - Teclado - LEDS.
/******************************************************************************** PPI_7.CPP (PPI en Modo 0) Este programa lee el cdigo de la tecla presionada de un teclado 4x4, lo muestra en la pantalla y en 8 leds conectados al PortA del PPI. Sale del programa cuando se pulsa ESC. La decodificacin se lleva a cabo a travs del Circuito Integrado 74C922.
Descripcin: a) Las conexiones PPI - 74C922 es: PORTB del PPI: PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0 74C922: Data_En X X X D C B A
(La seal OE se conecta a tierra, para que est siempre disponible). b) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. c) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). d) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
/* Prototipos */ unsigned char kbRead(void);
/* Variables globales */ unsigned char tecla, car; int Fin;
void main(void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x82); // Configura PPI como PA=PC=OUTs, PB=IN Fin = 0;
Ing. Javier Barriga Hoyle 33 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM while(!Fin) // Espera ESC para terminar { while(!(xin(0x79)&0x80)); // Espera que se pulse tecla while( (xin(0x79)&0x80)); // Espera que se suelte tecla car = ReadTecla(); // Lee tecla pulsada printf("Valor leido %c \n", car); // Imprime en pantalla xout (0x78, car); // Enva al PortA del PPI
if(kbhit()) // Se puls tecla de la PC? { car = getch(); // SI, lee del teclado if(car == 0x1B) Fin = 1; // Si es ESC, sale del programa } } } /*Fin de main */
/*---------------------------------------------------------------------------- Funcin que determina el cdigo de la tecla pulsada y devuelve ASCII. ----------------------------------------------------------------------------*/ unsigned char ReadTecla(void) { /* La siguiente tabla se usa para hallar el cdigo de cada tecla */ unsigned char kbTable[16]={'1', '2', '3', 'F', /* fila 0 */ '4', '5', '6', 'E', /* fila 1 */ '7', '8', '9', 'D', /* fila 2 */ 'A, '0', 'B', 'C'}; /* fila 3 */
tecla = xin(0x79)&0x0f; /* Lee del PortB del PPI y habilita los 4 bits menos significativos */ tecla = kbTable[tecla]; /* devuelve desde kbTable el cdigo asignado a la tecla presionada*/ return(tecla); } /* fin de ReadTecla */
10.4 DISPLAY 7 SEGMENTOS El DISPLAY de 7 segmentos es un dispositivo de salida que permite visualizar nmeros en formato BCD. La forma de uso que se le da es diversa y depende bsicamente del proyecto a realizar, puede usarse con un decodificador 7447/7448 o la decodificacin se realiza por software, en algunos casos se utiliza un PLD para decodificar en cdigo hexadecimal. Cuando se tiene que usar varios displays lo ms recomendable es conectarlos en un bus comn y el programa ejecuta la multiplexacin en el tiempo para mostrar los dgitos (Ej. Programa 10.8). Tambin se puede usar para desplazar mensajes en forma de caracteres, en este caso la decodificacin para generar las letras se hace por software (Ej. Programa 10.9).
a b c d e f g a b c d e f g Anodo / Ctodo comn
Figura 10.9. Display de 7 segmentos.
Los displays pueden se de nodo comn o ctodo comn, los primeros se alimentan con VCC y sus segmentos se activan con cero, y los segundos se alimentan con Tierra (GND) y sus segmentos se activan con uno.
Ing. Javier Barriga Hoyle 34 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 10.8: (PPI_8.CPP) Manejo de 4 displays multiplexados. Implemente el circuito mostrado y siga las recomendaciones dados en el captulo 9. Las entradas del decodificador 7448 (A, B, C, D) y las bases de los 4 transistores PNP se conectan al PortA del PPI de la Tarjeta LPT BYM V2.0 (figura 10.10). Ver apndice E.3 (Esquemtico de los 4 displays).
PA3 PA2 PA1 PA0 PA7 PA6 PA5 PA4 D7..D0 RD WR A0 A1 RESET CS PPI 82C55 D E C O D E R D C B A +5v +5v +5v +5v a b c d e f g 7448 Displays Anodo comn Q3 Q2 Q1 Q0 D R I V E R a b c d e f g ULN2003A
Figura 10.10. Conexin del PPI y 4 displays multiplexados.
/******************************************************************************** PPI_8.CPP (PPI en Modo 0) Este programa visualiza un nmero de 4 dgitos en BCD, almacenados en un arreglo donde el nibble alto controla el transistor y el nibble bajo los nmeros a ser mostrados en los 4 displays multiplexados. Se emplea el PortA del PPI.
Descripcin: a) Las conexiones PPI - DISPLAY es: PORTA del PPI: PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 TRANSISTORES: Q3 Q2 Q1 Q0 7447: D C B A
b) Los transistores se activan con CEROS (Q3=0111, Q2=1011, Q1=1101, Q0=1110) y los segmentos de los displays se activan con UNOS. c) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. d) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). e) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
void retardo(void); // Prototipo de funcin retardo
/* Variables globales */ unsigned char tabla[4]={0x75,0xB7,0xD9,0xE3}; // Defino el arreglo tabla int i,j;
void main(void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA=PB=PC=OUTs (modo 0)
for(i=0; i<=10000; i++) // Tiempo de visualizacin del nmero { for(j=0; j<=3; j++) // Se multiplexa los datos en el tiempo { xout(0x78,tabla[j]); // Se enva al puerto valor de tabla
Ing. Javier Barriga Hoyle 35 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM retardo(); // Se genera un retardo menor de 1 ms } } xout(0x78,0xFF); // Se apaga los displays } /* Fin de main */
/* Retardo aproximado de 0.5 ms para una computadora PIII de 450 MHz */ void retardo(void) { for(double n=0; n<65535; n++); } /* Fin de retardo */
Programa 10.9: (PPI_9.CPP) Manejo de 8 displays multiplexados. Implemente el circuito mostrado y siga las recomendaciones dados en el captulo 9. Los displays se conectan al PortA del PPI y los transistores al PortB del PPI para enviar una cadena de caracteres debidamente codificados por software. Ver esquemtico en el apndice E.5.
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 D7 - D0 RD WR A0 A1 RESET CS g f e d c b a PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0 +5v +5v +5v Se activan con ceros Displays nodo comn PPI 82C55 Driver U L N 2 8 0 3 Q7 Q4 Q0
Figura 10.11. Conexin PPI - ULN2803 - 8 displays multiplexados.
/****************************************************************************** PPI_9.CPP (PPI en modo 0) Este programa desplaza un mensaje en 8 displays multiplexados en el tiempo.
DESCRIPCION: a) Conecte con un cable el PortA del PPI a las entradas de los displays Las conexiones PPI - DISPLAY son: PORTA del PPI: PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 DISPLAYS: X g f e d c b a b) Las conexiones PPI - TRANSISTORES son: PORTB del PPI: PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0 TRANSISTORES: Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 c) Los datos que se envan al display salen por el PortA (78h) y tienen que ser previamente codificados a siete segmentos. Los segmentos se activan con UNO. (Ej. letra H = 01110110b = 0x76) d) Los transistores se controlan por el PortB del PPI (79h) usando los 8 bits. se activan con CEROS. (Ej. activar Q7=01111111 = 0x7f)
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo /* Prototipos */
Ing. Javier Barriga Hoyle 36 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM void retardo(void);
void main(void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA=PB=PC=OUTs (modo 0)
/* Visualiza mensaje1 en forma intermitente */ for(h=0; h<5; h++) // Numero de veces de intermitencia { for(i=0; i<=50; i++) // Tiempo de visualizacin del numero { for(j=0; j<=7; j++) // Se multiplexa los datos en el tiempo { xout(0x78,mensaje1[j]); // Se enva dato de tabla xout(0x79,transistor[j]); // Se activa posicin de transistor retardo(); // Se genera un retardo de 1/2 ms } } xout(0x78,0x00); // Se apaga los displays Sleep(250); // Se genera retardo de 250 ms }
/* Desplaza mensaje2 de derecha a izquierda */ for(h=0; h<3; h++) // Nmero de veces a desplazar el mensaje { p = &mensaje2[0]; // Asigna direccin de mensaje a p q = &transistor[0]; // Asigna direccin de transistor a q for(i=0; i<=26; i++) // Nmero de caracteres a desplazar { for(j=0; j<=15; j++) // Tiempo de visualizacin del mensaje { for(k=0; k<=7; k++) // Se multiplexa los datos en el tiempo { xout(0x78, *(p+k)); // Se enva el carcter xout(0x79, *(q+k)); // Se enva la posicin del transistor retardo(); // Se genera un retardo de 1/2 ms } } p++; // Incrementa puntero } } }
/* Retardo aproximado de 0.5 ms para una computadora PIII de 450 MHz */ void retardo(void) } for(double n=0; n<65535; n++); }
Ing. Javier Barriga Hoyle 37 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 10.5 MOTOR DE PASO A PASO Los 4 programas que se muestran a continuacin controlan un motor de pasos de 6 hilos (4 bobinas). Para ello se emplea el PPI 82C55 contenido en la tarjeta de interfase LPT V2.0 (puede tambin controlarse directamente desde el puerto paralelo). Para mayor informacin sobre motores paso a paso pueden leer el archivo MOTORES PAP.pdf
Figura 10.12. Fotografa de tres modelos de motores de paso.
Como se sabe para controlar estos motores, se hace necesario usar un driver por cada bobina implementado a base de transistores de potencia junto con opto acopladores. Tambin de una manera sencilla en ciertas aplicaciones se emplea al CI L293D (Apndice A), que es un driver de 4 canales capaz de proporcionar una corriente de salida de hasta 1A por canal. Cada canal es controlado por seales de entrada compatibles TTL y cada pareja de canales dispone de una seal de habilitacin que desconecta las salidas de los mismos. Para controlar el motor se dispone de dos modos bsicos y un tercer modo poco empleado: Accionamiento Paso Completo: Siempre hay 2 bobinas activadas, consiguindose un par motor ms elevado a costa de un mayor consumo de potencia. Accionamiento por Medios Pasos: Unas veces se encuentra activada una bobina y otras veces se activan dos bobinas, consiguindose mayor resolucin en el posicionamiento del motor. Accionamiento Onda o Una sola bobina: En cada instante de tiempo se encuentra activada una bobina del motor. Es poco empleado.
Programa 10.10: (PPI_10.CPP) Control de un motor de paso en modo paso completo. Implemente el circuito mostrado y siga las recomendaciones dados en el captulo 9. El motor se controla con los 4 bits menos significativos del PortA del PPI. Ver esquemtico en el apndice E.6.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ E1 IN1 IN2 IN3 IN4 E2 OUT1 OUT2 OUT3 OUT4 L293D
PA[3..0] Vs Vs Yellow Blue White Red Motor PAP (6 hilos) Vs = Vss = 5V hasta 36V
Figura 10.13. Conexin Tarjeta - L293D - Motor DC.
Ing. Javier Barriga Hoyle 38 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /******************************************************************************** PPI_10.CPP: (motor paso a paso de 6 hilos - control paso completo) El programa permite controlar a travs de un PPI el avance en sentido horario o antihorario pulsando las teclas (D)erecha e (I)zquierda. Los valores digitales a enviarse al motor son 10, 9, 5 y 6 para giro horario y 6, 5, 9 y 10 para giro antihorario. Se sale del programa cuando se pulsa ESC.
Descripcin: a) Conecte con un cable flat los 4 bits menos significativos del PA del PPI con las entradas al driver L293D. b) Las salidas del driver irn a las bobinas del motor de paso. c) Escriba el programa en Visual C++ (modo consola) d) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Variables globales */ unsigned char Giro[4]={10,9,5,6}; // Valores de activacin de las bobinas unsigned char car; int i, fin, sentido;
/* Inicia programa principal */ void main (void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
i = 0; // Inicializa variables fin = 0; sentido = 1;
printf ("\n********* CONTROL DE UN MOTOR PAP *********\n"); printf (" (Modo: paso completo)\n"); printf ("\nGIRO A LA DERECHA ............ : pulse (D)\n"); printf ("\nGIRO A LA IZQUIERDA .......... : pulse (I)\n"); printf ("\nPARA SALIR DEL PROGRAMA ...... : pulse (ESC)\n\n");
while(!fin) { car = getch(); if(car == 27) fin = 1; // Si es ESC, sale del programa if(car == 'D') sentido = 1; // Gira a la derecha if(car == 'd') sentido = 1; if(car == 'I') sentido = 0; // Gira a la izquierda if(car == 'i') sentido = 0; if(sentido) { xout(0x78, Giro[i]); // Enva dato al PA del PPI, derecha i++; if(i>3) i=0; } else { i--; if(i<0) i=3; xout(0x78, Giro[i]); // Enva dato al PA del PPI, izquierda } } }
Ing. Javier Barriga Hoyle 39 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 10.11: (PPI_11.CPP) Control de un motor de paso en modo medio paso (figura 10.13).
/******************************************************************************** PPI_11.CPP: (motor paso a paso de 6 hilos - control medio paso) El programa permite controlar a travs de un PPI el avance en sentido horario o antihorario pulsando las teclas (D)erecha e (I)zquierda. Los valores digitales a enviarse al motor son 10,8,9,1,5,4,6,2 para giro horario y 2,6,4,5,1,9,8,10 para giro antihorario. Se sale del programa cuando se pulsa ESC.
Descripcin: a) Conecte con un cable flat los 4 bits menos significativos del PA del PPI con las entradas al driver L293D. b) Las salidas del driver irn a las bobinas del motor de paso. c) Escriba el programa en Visual C++ (modo consola) d) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Variables globales */ unsigned char Giro[8]={10,8,9,1,5,4,6,2}; // Valores para las bobinas unsigned char car; int i, fin, sentido;
/* Inicia programa principal */ void main (void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B,0x80); // Configura PPI, PA=PB=PC=salidas
i = 0; // Inicializa variables fin = 0; sentido = 1;
printf ("\n********* CONTROL DE UN MOTOR PAP *********\n"); printf (" (Modo: medios pasos)\n"); printf ("\nGIRO A LA DERECHA ............ : pulse (D)\n"); printf ("\nGIRO A LA IZQUIERDA .......... : pulse (I)\n"); printf ("\nPARA SALIR DEL PROGRAMA ...... : pulse (ESC)\n\n");
while(!fin){ car = getch(); if(car == 27) fin = 1; // Si es ESC, sale del programa if(car == 'D') sentido = 1; // Gira a la derecha if(car == 'd') sentido = 1; if(car == 'I') sentido = 0; // Gira a la izquierda if(car == 'i') sentido = 0; if(sentido){ xout(0x78, Giro[i]); // Enva dato al PA del PPI, derecha i++; if(i>7) i=0; } else{ i--; if(i<0) i=7; xout(0x78, Giro[i]); // Enva dato al PA del PPI, izquierda } } }
Ing. Javier Barriga Hoyle 40 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 10.12: (PPI_12.CPP) Control de un motor de paso en modo una sola bobina (figura 10.13).
/******************************************************************************** PPI_12.CPP: (motor paso a paso de 6 hilos - control una sola bobina) El programa permite controlar a travs de un PPI el avance en sentido horario o antihorario pulsando las teclas (D)erecha e (I)zquierda. Los valores digitales a enviarse al motor son 8,1,4,2 para giro horario y 2,4,1,8 para giro antihorario. Se sale del programa cuando se pulsa ESC.
Descripcin: a) Conecte con un cable flat los 4 bits menos significativos del PA del PPI con las entradas al driver L293D. b) Las salidas del driver irn a las bobinas del motor de paso. c) Escriba el programa en Visual C++ (modo consola) d) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Variables globales */ unsigned char Giro[4]={8,1,4,2}; unsigned char car; int i, fin, sentido;
/* Inicia programa principal */ void main (void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B,0x80); // Configura PPI, PA=PB=PC=salidas
i = 0; // Inicializa variables fin = 0; sentido = 1;
printf ("\n********* CONTROL DE UN MOTOR PAP *********\n"); printf (" (Modo: una sola bobina por vez)\n"); printf ("\nGIRO A LA DERECHA ............ : pulse (D)\n"); printf ("\nGIRO A LA IZQUIERDA .......... : pulse (I)\n"); printf ("\nPARA SALIR DEL PROGRAMA ...... : pulse (ESC)\n\n");
while(!fin){ car = getch(); if(car == 27) fin = 1; // Si es ESC, sale del programa if(car == 'D') sentido = 1; // Gira a la derecha if(car == 'd') sentido = 1; if(car == 'I') sentido = 0; // Gira a la izquierda if(car == 'i') sentido = 0; if(sentido){ xout(0x78, Giro[i]); // Enva dato al PA del PPI, derecha i++; if(i>3) i=0; } else { i--; if(i<0) i=3; xout(0x78, Giro[i]); // Enva dato al PA del PPI } } }
Ing. Javier Barriga Hoyle 41 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 10.13: (PPI_13.CPP) Control de la velocidad de un motor de paso en modo paso completo (figura 10.13).
/******************************************************************************** PPI_13.CPP:(motor paso a paso de 6 hilos - control de velocidad en paso completo) El programa permite controlar a travs de un PPI el avance en sentido horario o antihorario pulsando las teclas (D)erecha e (I)zquierda. Tambin podemos aumentar o disminuir la velocidad en cualquier sentido. Los valores digitales a enviarse al motor son 8,1,4,2 para giro horario y 2,4,1,8 para giro antihorario. Se sale del programa cuando se pulsa ESC.
Descripcin: a) Conecte con un cable flat los 4 bits menos significativos del PA del PPI con las entradas al driver L293D. b) Las salidas del driver irn a las bobinas del motor de paso. c) Escriba el programa en Visual C++ (modo consola) d) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Prototipos */ void velocidad (int x); // Controla velocidad del motor
i = 0; // Inicializa variables fin = 0; v = 0; // Variable para la velocidad sentido = 1;
printf ("\n****** CONTROL DE VELOCIDAD DE UN MOTOR PAP ******\n"); printf (" (Modo: paso completo)\n"); printf ("\nGIRO A LA DERECHA ............ : pulse (D)\n"); printf ("\nGIRO A LA IZQUIERDA .......... : pulse (I)\n"); printf ("\nAUMENTO DE VELOCIDAD ......... : pulse (A)\n"); printf ("\nDISMINUYE VELOCIDAD .......... : pulse (Z)\n"); printf ("\nPARA SALIR DEL PROGRAMA ...... : pulse (ESC)\n\n");
while(!fin) { tecla = 0; car = getch(); car = toupper(car); // Convierte a mayscula if(car == 27) { fin = 1; // Si es ESC, sale del programa
Ing. Javier Barriga Hoyle 42 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM tecla = 1; } if(car == 'D') sentido = 1; // Gira a la derecha if(car == 'I') sentido = 0; // Gira a la izquierda if(car == 'A') { v++; // Aumenta velocidad if(v>7) v=7; } if(car == 'Z') { v--; // Disminuye velocidad if(v<0) v=0; } vel = Veloci[v]; // Retorna factor de velocidad
while(!tecla) { if(sentido) { xout(0x78, GiroCo[i]); // Enva dato al PA del PPI velocidad(vel); // Llama a retardo de velocidad i++; if(i>7) i=0; } else { i--; if(i<0) i=7; xout(0x78, GiroCo[i]); // Enva dato al PA del PPI velocidad(vel); // Llama a retardo de velocidad } if (kbhit()) tecla=1; } } } /* Fin de main */
void velocidad(int x) { int m, n, p; p = x;
for(m=0; m<=p; m++) { for(n=0; n<=20000; n++); // Bucle de retardo } } /* Fin de velocidad */
Ing. Javier Barriga Hoyle 43 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 11. Aplicaciones del TIMER 82C54 Para hacer uso del TIMER de la Tarjeta LPT ByM V2.0, tiene que entender en primer lugar como se programa, configura y opera. Luego puede implementar y ejecutar los siguientes programas bsicos hasta llegar al control de un motor de corriente continua usando PWM. En la siguiente figura se observa la Tarjeta LPT y las salidas del TIMER y SWITCH a usar. Por razones de espacio y comodidad en los programas se mostrar slo las conexiones a realizar mediante un diagrama pequeo y claro. Los esquemticos los puede encontrar en el apndice E. Recuerde que el Canal 0 no est disponible externamente, ya que este se puede utilizar para generar retardos de precisin, quedando su uso interno. En consecuencia, slo estn disponibles externamente los Canales 1 y 2 (OUT1 y OUT2). La frecuencia que alimenta al TIMER es un oscilador de 8 MHz.
G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S TIMER SW TIMER + 5 V G N D ON 4 3 2 1 ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 P B P C V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 TIMER 82C54 P A G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 + 5 V G N D 8 MHZ POWER E/S TIMER SW TIMER
Figura 11.1. Diagrama que muestra la ubicacin del SW y E/S del TIMER en la Tarjeta.
11.1 GENERACION DE SEALES A DIFERENTES FRECUENCIAS (MODO 2 y 3) Se recomienda observar la posicin y significado que tiene cada bit del Dipswitch (SW), as mismo con las conexiones en la bornera azul de entrada y salida (E/S).
Programa 11.1: (TIMER_1.CPP) Uso del TIMER en modo 2 y 3. Realice las conexiones mostradas y siga las instrucciones dadas en el programa. Como la frecuencia de salida es alta, es necesario disponer de un osciloscopio para observar las seales.
G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S TIMER SW TIMER + 5 V G N D ON 4 3 2 1 OSCILOSCOPIO
Figura 11.2. Conexin del TIMER para el programa 11.1, 11.3 y 11.4
Ing. Javier Barriga Hoyle 44 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /******************************************************************************** TIMER_1.CPP: Este programa muestra como programar el TIMER 82C54 de la Tarjeta y obtener una frecuencia de 1 MHz en el CH1 (modo 2) y en el CH2 (modo 3).
Descripcin: a) Coloque los 4 bits del SW TIMER (S1) en ON, para que la frecuencia de 8 MHz le llegue al CH1 y CH2. As mismo, los GATE de ambos estn habilitados. b) Programe al CH1 en modo 2 a una frecuencia de 1MHz, y observe su salida OUT1 en el osciloscopio. c) Programe al CH2 en modo 3 a una frecuencia de 1MHz, y observe su salida OUT2 en el osciloscopio. d) Escriba el programa en Visual C++ (modo consola) e) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
/* Configura los canales 1 y 2 */ xout(0x77, 0x74); // CH1, Modo 2, binario xout(0x77, 0XB6); // CH2, Modo 3, binario
/* Frecuencia de entrada al CH1 = 8 MHz. Para obtener una frecuencia de 1 MHz (T =1 s), se tiene que dividir (8 MHz/1 MHz)= 8; ==> el factor N1=0008 */ xout(0x75, 0x08); // Se enva Byte LSB al CH1 xout(0x75, 0x00); // Se enva Byte MSB al CH1
/* Frecuencia de entrada al CH2 = 8 MHz. Para obtener una frecuencia de 1 MHz (T =1 s), se tiene que dividir (8 MHz/1 MHz)= 8; ==> el factor N1=0008 */ xout(0x76, 0x08); // Se enva Byte LSB al CH2 xout(0x76, 0x00); // Se enva Byte MSB al CH2 } /* FIN de main */
Programa 11.2: (TIMER_2.CPP) Uso del TIMER en modo 3, cascada. Realice las conexiones mostradas y siga las instrucciones dadas en el programa.
G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S TIMER SW TIMER + 5 V G N D ON 4 3 2 1 LED
Figura 11.3. Conexin del TIMER para el programa 11.2.
/******************************************************************************** TIMER_2.CPP: Este programa muestra como conectar en cascada el CH1 y CH2 del TIMER 82C54 para obtener una frecuencia de 1Hz en la salida del CH2.
Ing. Javier Barriga Hoyle 45 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Descripcin:
Realice las siguientes conexiones sobre los canales 1 y 2 del TIMER. a) Coloque los bits 1 y 2 del SW TIMER (S1) en ON, para que los GATES de los 2 canales estn habilitados. b) Coloque el bit 3 del SW TIMER (S1) en ON, para que el CH1 tenga una frecuencia de entrada de 8 MHz. c) Coloque el bit 4 del SW TIMER (S1) en OFF, para que la entrada CLK2 dependa de la conexin externa (bornera azul). d) En la bornera del TIMER unir con un cable la salida OUT1 del CH1 a la entrada CLK2 del CH2. e) Programe al CH1 en modo 3 a una frecuencia de 160 Hz (N1 = C350h). f) Programe al CH2 en modo 3 a una frecuencia de 1 Hz (N2 = 00A0h), y observe la salida OUT2 en un LED. g) Escriba el programa en Visual C++ (modo consola) h) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
// Configura los canales 1 y 2 xout(0x77, 0x76); // CH1, Modo 3, binario xout(0x77, 0XB6); // CH2, Modo 3, binario
/* Frecuencia de entrada al CH1 = 8 MHz. Para obtener una frecuencia de 160 Hz. (T = 6.25 ms), se tiene que dividir (8 MHz/160 Hz) = 50000 = C350h; ==> el factor N1 = C350h */ xout(0x75, 0x50); // Se enva Byte LSB al CH1 xout(0x75, 0xC3); // Se enva Byte MSB al CH1
/* Frecuencia de entrada al CH2 = 160 Hz. Para obtener una frecuencia de 1 Hz (T = 1 Seg), se tiene que dividir (160 Hz/1 Hz) = 160 = 00A0h; ==> el factor N2 = 00A0h. */ xout(0x76, 0xA0); // Se enva Byte LSB al CH2 xout(0x76, 0x00); // Se enva Byte MSB al CH2
} /* FIN de main */
Programa 11.3: (TIMER_3.CPP) Uso del comando de enclavamiento. Realice las conexiones mostradas en la figura 11.2 y siga las instrucciones dadas en el programa. Este programa usa el comando de enclavamiento para leer el registro contador.
/******************************************************************************** TIMER_3.CPP: Este programa muestra como usar el comando de enclavamiento para leer la cuenta actual del registro interno de 16 bits del contador CH1.
Descripcin: Realice las siguientes conexiones sobre el canal 1 del TIMER. a) Coloque los bits 1 y 2 del SW TIMER en ON, para que los GATES de los 2 canales estn habilitados. b) Coloque los bits 3 y 4 del SW TIMER en ON, para que ambos canales reciban los 8 MHz como frecuencia de entrada.
Ing. Javier Barriga Hoyle 46 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM c) Programe al CH1 en modo 3 a una frecuencia de 5 KHz (N1 = 640h). d) Conecte la salida del canal 1 (out1) al osciloscopio y observe la seal de salida. e) Escriba el programa en Visual C++ (modo consola) f) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Variables globales */ unsigned char CuentaLow, CuentaHigh, Ch; unsigned int Cuenta; const int ESC = 0x1B;
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
printf("\n******* LECTURA DEL REGISTRO CONTADOR DEL TIMER *******\n\n"); printf("\t ***** (Metodo de enclavamiento) *****\n\n"); printf("\nPara salir del programa pulse ...: (ESC)ape\n"); printf("\nPara leer la cuenta pulse .......: (L)eer\n\n\n");
/* Configura al canal 1 */ xout(0x77, 0x76); // CH1, Modo 3, binario
/* Frecuencia de entrada al CH1 = 8 MHz. Para obtener una frecuencia de 5 KHz (T = 200 s), se tiene que dividir (8 MHz/5 KHz) = 1600 = 0640h; ==> el factor N1 = 0640h. Envo la cuenta al contador 1 */ xout(0x75, 0x40); // Se enva Byte LSB al CH1 xout(0x75, 0x06); // Se enva Byte MSB al CH1
/* Enva el comando de enclavamiento y luego lee la cuenta del contador 1 */ while(Ch != ESC) { Ch = getch(); Ch = toupper(Ch); // Convierte a mayscula if(Ch == 'L') { xout(0x77, 0x40); // Se enva 01000000 (enclava) CuentaLow = xin(0x75); // Lee Byte LSB CuentaHigh = xin(0x75); // Lee Byte MSB Cuenta = (CuentaHigh << 8) | CuentaLow; // Se forma un word printf("Valor actual del registro contador = %d \r",Cuenta); } } printf("\n\nSaliendo del programa\n\n");
} /* FIN de main */
Ing. Javier Barriga Hoyle 47 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 11.4: (TIMER_4.CPP) Uso del comando Read-Back. Realice las conexiones mostradas en la figura 11.2 y siga las instrucciones dadas en este programa. El comando Read-Back sirve para leer el registro contador y su estado.
/******************************************************************************* TIMER_4.CPP: Este programa muestra como usar el comando Read Back para leer la cuenta actual del registro interno de 16 bits del contador CH1.
Descripcin: Realice las siguientes conexiones sobre el canal 1 del TIMER. a) Coloque los bits 1 y 2 del SW TIMER en ON, para que los GATES de los 2 canales estn habilitados. b) Coloque los bits 3 y 4 del SW TIMER en ON, para que ambos canales reciban los 8 MHz como frecuencia de entrada. c) Programe al CH1 en modo 3 a una frecuencia de 5 KHz (N1 = 640h). d) Conecte la salida del canal 1 (out1) al osciloscopio y observe la seal de salida. e) Escriba el programa en Visual C++ (modo consola) f) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0 int Base = 0x378; // Direccin base del puerto paralelo
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
printf("\n******* LECTURA DEL REGISTRO CONTADOR DEL TIMER *******\n\n"); printf("\t ***** (Metodo de Read-Back) *****\n\n"); printf("\nPara salir del programa pulse ...: (ESC)ape\n"); printf("\nPara leer la cuenta pulse .......: (L)eer\n\n\n");
/* Configura al canal 1 */ xout(0x77, 0x76); // CH1, Modo 3, binario
/* Frecuencia de entrada al CH1 = 8 MHz. Para obtener una frecuencia de 5 KHz (T = 200 s), se tiene que dividir (8 MHz/5 KHz) = 1600 = 0640h; ==> el factor N1 = 0640h. Envo la cuenta al contador 1 */ xout(0x75, 0x40); // Se enva Byte LSB al CH1 xout(0x75, 0x06); // Se enva Byte MSB al CH1
/* Enva el comando Read-Back y luego lee el estado y la cuenta del CH1 */ while(Ch != ESC){ Ch = getch(); Ch = toupper(Ch); // Convierte a mayscula if(Ch == 'L') { xout(0x77, 0xC4); // Se enva 11000100 (Read-Back) Estado = xin(0x75); // Lee Byte de estado CuentaLow = xin(0x75); // Lee Byte LSB CuentaHigh = xin(0x75); // Lee Byte MSB Cuenta = (CuentaHigh << 8) | CuentaLow; // Se forma un word printf("Estado (hex)= %x - Cuenta contador 1 (hex)= %x \r",Estado,Cuenta); }
Ing. Javier Barriga Hoyle 48 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM } printf("\n\nSaliendo del programa\n\n"); } // Fin de main
11.2 PROGRAMAS QUE GENERA SONIDO y PWM Programa 11.5: (TIMER_5.CPP) Simulacin de un rgano electrnico usando el teclado, parlante interno de la PC y programando el canal 2 de su TIMER interno (Apndice B). Debe ejecutarse en Windows 98, 2000 o XP, pero deber usar el Turbo C++ 3.0 (Borland C++ 3.0).
CLK GATE OUT CANAL 0 CLK GATE OUT CANAL 1 CLK GATE OUT CANAL 2 VCC R PB0 PB1 PPI VCC IRQ0 - Vector 8 Refresco de Memoria DRAM 1193180 Hz 40h - 43h 60h - 63h
Figura 11.4 Conexin del TIMER parlante en la PC.
/******************************************************************************** TIMER_5.CPP: Este programa muestra como programar el TIMER de la PC (puerto 40h - 43h) para generar sonido con el teclado de la computadora y simular un rgano electrnico. Las letras vlidas son desde la "A", "B", "C", hasta la letra "G".
Descripcin: Para programarlo se tiene que observar el circuito que controla el parlante de la PC (figura 5.1), en la cual se aprecia que el bit 0 y bit 1 del puerto B del PPI (direccin 60h - 63h) controlan el Gate y la habilitacin del parlante. Las frecuencias (factores de divisin) o notas musicales son: 2080, 1881, 1648, 1560, 1390, 1212 y 1105. El programa termina cuando se pulsa ESC.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <stdio.h> #include <conio.h> #include <ctype.h>
#define RC_TIM 0x43 // Direccin de configuracin del TIMER #define CH2 0x42 // Direccin del canal 2 #define PORTB 0x61 // Direccin base del PPI #define ESC 0x1B
Ing. Javier Barriga Hoyle 49 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM void main (void) // Inicia programa principal { outportb(RC_TIM,0xB6); // Configura CH2 del TIMER PPI = inportb(PORTB); // Lee el estado del PortB del PPI PPI = PPI|0x03; // Se hace PB0 = PB1 = 1 outportb(PORTB,PPI); // Parlante habilitado
printf("\n****** GENERACION DE SONIDO POR EL PARLANTE DE LA PC ******\n\n"); printf("\nPara salir del programa pulse ...: (ESC)ape\n"); printf("\nPara generar sonido pulse las letras desde la A hasta G:);
while(!fin){ car = getch(); car = toupper(car); // Convierte a mayscula if (car=='A') musica(nota_musical[0]); if (car=='B') musica(nota_musical[1]); if (car=='C') musica(nota_musical[2]); if (car=='D') musica(nota_musical[3]); if (car=='E') musica(nota_musical[4]); if (car=='F') musica(nota_musical[5]); if (car=='G') musica(nota_musical[6]); if (car==27) fin=1; // Es ESC? } PPI = inportb(PORTB); // Lee estado del PPI PPI = PPI & 0xFC; // Se hace PB0 = PB1 = 0 outportb(PORTB,PPI); // Parlante deshabilitado } // Fin de main
void musica (int frecuencia) // Funcin que cambia frecuencia { int byte_low, byte_high; byte_low = frecuencia %100; // Se toma el resto de la divisin byte_high = frecuencia /100; // Se toma el cociente de la divisin outportb(CH2, byte_low); // Se enva byte_LSB al CANAL2 del Timer outportb(CH2, byte_high); // Se enva byte_MSB al CANAL2 del Timer }
Programa que genera sonido en el parlante conectado al TIMER de la tarjeta LPT:
Programa 11.6: (TIMER_6.CPP) Simulacin de un rgano electrnico usando las teclas de la PC y generando el sonido en el parlante conectado al CH2 del TIMER de la tarjeta LPT BYM. Sistema Operativo Win2000 o WinXP.
1 2 3 4 ON + 5V GND OUT2 OUT1 G2 G1 CLK2 CLK1 CLK2 CLK1 G2 G1 V C C G N D P A 7 P A 6 P A 5 P A 4 P A 3 P A 2 P A 1 P A 0 VCC 4K7 NPN 2N3904
Figura 11.5 Conexin del TIMER parlante externo en la Tarjeta LPT BYM.
Ing. Javier Barriga Hoyle 50 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /******************************************************************************** TIMER_6.CPP: Este programa muestra como generar sonido usando el TIMER de la tarjeta LPT y un parlante. Para ello, conecte en cascada el CH1 y CH2 del TIMER para obtener una frecuencia de 1MHz en la salida del CH2. Con la frecuencia de 1 MHz en el CH2 y el parlante conectado a la salida de este canal, se programa para generar sonido con el teclado de la computadora y simular un rgano electrnico. Las letras vlidas son desde la "A", "B", "C", hasta la letra "G". Las frecuencias (factores de divisin) o notas musicales son: 2080, 1881, 1648, 1560, 1390, 1212 y 1105. El programa termina cuando se pulsa ESC.
Descripcin:
Realice las siguientes conexiones sobre los canales 1 y 2 del TIMER. a) Coloque el bit 1 del SW TIMER (S1) en ON, para que el GATE1 habilite al CH1. b) Coloque el bit 2 del SW TIMER (S1) en OFF, para que el GATE2 se controle por software (bit0 del PORTA del PPI). c) Coloque el bit 3 del SW TIMER (S1) en ON, para que el CH1 tenga una frecuencia de entrada de 8 MHz. d) Coloque el bit 4 del SW TIMER (S1) en OFF, para que la entrada CLK2 dependa de la conexin externa (bornera azul). e) En la bornera del TIMER unir con un cable la salida OUT1 del CH1 a la entrada CLK2 del CH2. f) Con un cable unir el bit0 del PORTA del PPI con la entrada GATE2 del TIMER (bornera azul). g) Programe al CH1 en modo 3 a una frecuencia de 1 MHz (N1 = 0008h). h) Al CH2 se le enviar una FRECUENCIA de acuerdo a la tecla pulsada. i) Escriba el programa en Visual C++ (modo consola). j) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5).
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Configura los canales 1 y 2 */ xout(0x77, 0x76); // CH1, Modo 3, binario xout(0x77, 0XB6); // CH2, Modo 3, binario
/* Frecuencia de entrada al CH1 = 8 MHz. Para obtener una frecuencia de 160 Hz. (T = 6.25 ms), se tiene que dividir (8 MHz/1 MHz) = 8 ==> el factor N1 = 0008h */ xout(0x75, 0x08); // se enva Byte LSB al CH1 xout(0x75, 0x00); // se enva Byte MSB al CH1
Ing. Javier Barriga Hoyle 51 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /* Cdigo que genera el sonido */ printf("\n**** GENERACION DE SONIDO POR EL PARLANTE DE LA TARJETA ****\n\n"); printf("\nPara salir del programa pulse ...: (ESC)ape\n"); printf("\nPara generar sonido pulse las letras desde la A hasta G:\n\n");
fin=0; while(!fin){ car = getch(); car = toupper(car); // Convierte a mayscula if (car=='A') musica(nota_musical[0]); if (car=='B') musica(nota_musical[1]); if (car=='C') musica(nota_musical[2]); if (car=='D') musica(nota_musical[3]); if (car=='E') musica(nota_musical[4]); if (car=='F') musica(nota_musical[5]); if (car=='G') musica(nota_musical[6]); if (car==27) fin=1; // Es ESC? }
void musica (int frecuencia) // Funcin que cambia frecuencia { int byte_low, byte_high; byte_low = frecuencia %100; // Se toma el resto de la divisin byte_high = frecuencia /100; // Se toma el cociente de la divisin xout(0x76, byte_low); // Se enva byte LSB al CH2 del Timer xout(0x76, byte_high); // Se enva byte MSB al CH2 del Timer }
Programa 11.7: (TIMER_7.CPP) Control de la velocidad de un motor DC usando PWM a travs del teclado de la computadora. Este programa muestra como emplear el TIMER 82C54 para generar la modulacin por ancho de pulsos (PWM). Implemente el siguiente circuito (Ver Apndice C para cualquier consulta adicional sobre estos CI y el Apndice E.7 para ver el esquemtico). PWM 1 2 3 4 ON 5 6 7 2 3 11 1,9 +5V OUT1 OUT2 10 Sentido de giro + 5V GND OUT2 OUT1 G2 G1 CLK2 CLK1 CLK2 CLK1 G2 G1 74LS279 L293D Motor DC
S W
T I M E R E / S
T I M E R P O W E R +
1 = Horario 0 = Antihorario
Figura 11.6. Conexin para control de velocidad de un motor DC usando PWM.
/******************************************************************************** TIMER_7.CPP (Control de velocidad de un Motor DC con PWM) Este programa emplea los contadores 1 y 2 (CH1 y CH2) del TIMER 82C54 para generar PWM (Pulse Width Modulation). Se controla la velocidad con las teclas A (aumenta) y D (disminuye) del teclado de la computadora. Termina el programa cuando se pulsa la tecla ESC.
Ing. Javier Barriga Hoyle 52 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Descripcin: a) En el SW TIMER, coloque los bits de la siguiente manera: G1(Gate 1)=ON, G2(Gate 2)=OFF, CLK1=ON (8MHz) y CLK2=ON (8 MHz). b) Configure al CH1 en modo 2 a una frecuencia aproximada de 122 Hz. c) Configure al CH2 en modo 5, este opera a una frecuencia variable ingresada por teclado. d) En la bornera azul TIMER, conecte las salidas del CH1 (OUT1) y CH2 (OUT2) al pin5 y pin6 del 74LS279 respectivamente. e) La salida PWM que se obtiene en el pin7 del 74LS279, conctela al pin 2 del DRIVER L293D y de los pines 3 y 11 de ste al motor. f) Se recomienda ver en un osciloscopio las formas de onda que se generan al variar la velocidad en las salidas del CH1, CH2 y PWM. g) El sentido de giro lo controlamos con el bit0 del PortB del PPI (horario = 1, antihorario = 0). g) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. h) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). i) Ejecute su programa y siga las instrucciones de la pantalla.
Autor: Ing. Javier Barriga Hoyle *******************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI con todos los puertos outs
printf("\n\t********* CONTROL DE UN MOTOR DC USANDO PWM *********\n"); printf("\t\t***** Contadores 1 y 2 para PWM *****\n\n"); printf("Para salir del programa pulse ...: (ESC)\n\n"); printf("Para variar la velocidad del motor, pulse:\n"); printf("(1) Aumento de velocidad ........: (A)\n"); printf("(2) Disminuye velocidad .........: (D)\n\n"); printf("Para cambiar sentido de giro (motor parado), pulse :\n"); printf("(3) Sentido horario .............: (H)\n"); printf("(4) Sentido antihorario .........: (J)\n"); printf("Nota: En giro antihorario, las teclas de (A)umento y (D)isminuye se invierten\n"); printf("\nVariando frecuencia de contador 2 (Contador 1 = 122 Hz)\n\n");
/* Configura CH1 en modo 2 (Rate Generator) y CH2 en modo 5 (Hardware Triggered Strobe - monoestable) */ xout(0x77, 0x74); // CH1 = 0111 0100 (palabra de control) xout(0x77, 0xBA); // CH2 = 1011 1010 (palabra de control)
/* Inicializa Canal 1 */ DataWord = 0xFFFF; // Fijo CH1 a frec = (8MHz/65535) = 122 Hz FrecCanal(1); // Arranca Canal 1, para disparar al Canal 2
/* Inicializa Canal 2, para motor apagado */
Ing. Javier Barriga Hoyle 53 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM DataWord = 0x100E; FrecCanal(2);
/* Espera que se pulse teclado para variar velocidad */ Fin = 0; xout(0x79,1); // Giro horario (bit0_PortB = 1)
while(!Fin) { car = getch(); // Lee del teclado car = toupper(car); // Convierte a mayscula if(car == ESC) Fin = 1; // Si es ESC, sale del programa if(car == 'H') xout(0x79,1); // Sentido horario if(car == 'J') xout(0x79,0); // Sentido antihorario AjusteFrecuenciaCanal2(car); // Ajusta frecuencia de canal 2 } } // Fin de main
/*---------------------------------------------------------------------------- Funciones que trabajan con el TIMER. -----------------------------------------------------------------------------*/ void FrecCanal(unsigned char NumCanal) // Enva 2 BYTES al canal { EnvioDato(NumCanal, DataWord & 0xff); EnvioDato(NumCanal, DataWord >> 8); }
void AjusteFrecuenciaCanal2(unsigned char car) // Calcula nueva frecuencia { switch(car) { case 'A': if(DataWord < 0xF000) DataWord = DataWord + 0x0FFF; // Incrementos cada 4095 break; case 'D': if(DataWord > 0x100F) DataWord = DataWord - 0x0FFF; // Decrementos de 4095 break; case 27: printf("\n\nSaliendo del programa\n\n"); }
printf("\tDATA WORD = %u \r",DataWord); FrecCanal(2); // Enva DataWord } // Fin de AjusteFrecuenciaCanal2
void EnvioDato(unsigned char NumCanal, unsigned char Data) // Enva al puerto { switch(NumCanal) { case 1: xout(0x75, Data); // Enva dato al CH1 break; case 2: xout(0x76, Data); // Enva dato al CH2 } } // Fin de EnvioDato
Ing. Javier Barriga Hoyle 54 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 11.8: (TIMER_8.CPP) Control de la velocidad de un motor DC usando PWM a travs de un teclado 4x4 hexadecimal. Implemente el siguiente circuito, para la conexin de TIMER MOTOR revise la figura 11.4 y para la conexin de PPI TECLADO revise las figuras 10.3 y 10.4. (Para cualquier consulta adicional puede revisar el Apndice A, C y E.7).
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C Columnas Filas Teclado 4x4 74LS279 L293D PWM O N O N O N O F F Motor DC
Figura 11.7. Conexin para control de la velocidad un motor DC usando PWM y un teclado 4x4.
/******************************************************************************** TIMER_8.CPP (Control de velocidad de un Motor DC con PWM) Este programa emplea los contadores 1 y 2 (CH1 y CH2) del TIMER 82C54 para generar PWM (modulacin por ancho de pulsos). Se controla la velocidad con las teclas 1 (aumenta) y 3 (disminuye) del teclado 4x4 conectado al PortC del PPI. Termina el programa cuando pulsa la tecla 0.
Descripcin: a) En el SW TIMER, coloque los bits de la siguiente manera: G1(Gate 1)=ON, G2(Gate 2)=OFF, CLK1=ON (8MHz) y CLK2=ON (8 MHz). b) Configure al CH1 en modo 2 a una frecuencia aproximada de 122 Hz. c) Configure al CH2 en modo 5, este opera a una frecuencia variable ingresada por teclado. d) En la bornera azul TIMER, conecte las salidas del CH1 (OUT1) y CH2 (OUT2) al pin5 y pin6 del 74LS279 respectivamente. e) La salida PWM que se obtiene en el pin7 del 74LS279, conctela al pin 2 del DRIVER L293D y de los pines 3 y 11 de ste al motor. f) Recomiendo ver en un osciloscopio las formas de onda que se generan al variar la velocidad en las salidas del CH1, CH2 y PWM. g) El sentido de giro lo controlamos con el bit0 del PortB del PPI (horario = 1, antihorario = 0). h) Conecte el PortC del PPI al teclado 4x4 hexadecimal (similar programa 6). i) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. j) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). k) Ejecute su programa y siga las instrucciones de la pantalla.
Autor: Ing. Javier Barriga Hoyle *******************************************************************************/ #include <windows.h> #include <stdio.h>
Ing. Javier Barriga Hoyle 55 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM #include <conio.h> #include <stdlib.h> #include <string.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
xout(0x7B, 0x88); /* Configura PPI con PA=PB=OUTs (modo 0) PC[7..4]=IN, PC[3..0]=OUT (modo 0) */
printf("\n\t********* CONTROL DE UN MOTOR DC USANDO PWM *********\n"); printf("\t\t***** Contadores 1 y 2 para PWM *****\n\n"); printf("Para salir del programa pulse ...: (ESC)\n\n"); printf("\n\nPara variar la velocidad del motor pulse en el teclado 4x4:\n"); printf("(a) Aumento de velocidad ........: (1)\n"); printf("(b) Disminuye velocidad .........: (3)\n\n"); printf("Para cambiar sentido de giro (motor parado), pulse :\n"); printf("(c) Sentido horario .............: (7)\n"); printf("(d) Sentido antihorario .........: (9)\n"); printf("Nota: En giro antihorario, las teclas de (A)umento y (D)isminuye se invierten\n"); printf("\nVariando frecuencia de contador 2 (Contador 1 = 122 Hz)\n\n");
/* Configura CH1 en modo 2 (Rate Generator) y CH2 en modo 5 (Hardware Triggered Strobe - monoestable) */ xout(0x77, 0x74); // CH1 = 0111 0100 (palabra de control) xout(0x77, 0xBA); // CH2 = 1011 1010 (palabra de control)
/* Inicializa Canal 1 */ DataWord = 0xFFFF; // Fija CH1 a frec = (8MHz/65535) = 122 Hz FrecCanal(1); // Arranca Canal 1, para disparar al Canal 2
/* Inicializa Canal 2, para motor apagado */ DataWord = 0x100E; FrecCanal(2);
/* Espera que se pulse teclado para variar velocidad */ Fin = 0; xout(0x79,1); // Giro horario (bit0_PortB = 1)
while(!Fin) // Espera nmero "0" para terminar { scan = 0xfe; // Byte de inicio de scan de teclado ncol = 4; // Nmero de columnas a explorar for(ncol; ncol>0; ncol--) { xout(0x7A, scan); // Enva dato al PortC Sleep(10); // Retardo de 10 ms car2 = xin(0x7a); // Lee el teclado (columna, fila) if((scan-car2) != 0) // Se ha pulsado tecla? {
Ing. Javier Barriga Hoyle 56 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM tecla = kbRead(car2); // Devuelve cdigo tecla vlido if(tecla == 0) Fin = 1; // Si es 0, sale del programa if(tecla == '7') xout(0x79,1); // Sentido horario if(tecla == '9') xout(0x79,0); // Sentido antihorario
AjusteFrecuenciaCanal2(tecla); // Ajusta frecuencia de canal 2 Sleep(200); // Retardo para eliminar rebote } scan = (scan<<1) | 1; // Selecciona siguiente fila } } } // Fin de main
/*---------------------------------------------------------------------------- Determina el nmero de la tecla pulsada. Realiza la operacin: "nmero = fila * 2 + columna". -----------------------------------------------------------------------------*/ unsigned char keyNumber(unsigned char dato) { unsigned char fila,col; fila = dato & 0x0f; switch(fila) { case 0x0e: fila=0; break; /* 0000.111_ */ case 0x0d: fila=1; break; /* 0000.11_1 */ case 0x0b: fila=2; break; /* 0000.1_11 */ case 0x07: fila=3; break; /* 0000._111 */ default: fila=0xff; break; } col = dato & 0xf0; // Lee para determinar la columna switch(col) { case 0xe0: col=0; break; /* 111_.0000 */ case 0xd0: col=1; break; /* 11_1.0000 */ case 0xb0: col=2; break; /* 1_11.0000 */ case 0x70: col=3; break; /* _111.0000 */ default: col=0xff; break; } if((fila == 0xff)||(col == 0xff)) col = 0xff; // Retorna tecla pulsada invlida else col = (fila<<2) + col; /* Determina el nmero de la tecla pulsada */ return(col); } // fin de keyNumber
/*---------------------------------------------------------------------------- Determina el cdigo de la tecla pulsada y devuelve el cdigo ASCII. -----------------------------------------------------------------------------*/ unsigned char kbRead(unsigned char tec) { /* La siguiente tabla se usa para hallar el cdigo de cada tecla */ unsigned char kbTable[16]={'1', '2', '3', 'F', /* fila 0 */ '4', '5', '6', 'E', /* fila 1 */ '7', '8', '9', 'D', /* fila 2 */ 'A', '0', 'B', 'C'}; /* fila 3 */
tecla = keyNumber(tec); // Codifica tecla en fila, columna if(tecla != 0xff) // Si solo se ha pulsado una tecla vlida, tecla = kbTable[tecla]; // traduce desde kbTable el cdigo de tecla return(tecla); // Retorna tecla pulsada } /* fin de kbRead */
/*---------------------------------------------------------------------------- Funciones que trabajan con el TIMER. -----------------------------------------------------------------------------*/ void FrecCanal(unsigned char NumCanal) // Enva 2 BYTES al canal
Ing. Javier Barriga Hoyle 57 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM { EnvioDato(NumCanal, DataWord & 0xff); EnvioDato(NumCanal, DataWord >> 8); }
void AjusteFrecuenciaCanal2(unsigned char car) // Calcula nueva frecuencia { switch(car) { case '1': if(DataWord < 0xF000) DataWord = DataWord + 0x0FFF; // Incrementos cada 4095 break; case '3': if(DataWord > 0x100F) DataWord = DataWord - 0x0FFF; // Decrementos de 4095 break; case '0': printf("\n\nSaliendo del programa\n\n"); } printf("\tDATA WORD = %u \r",DataWord); FrecCanal(2); // Enva DataWord } // Fin de AjusteFrecuenciaCanal2
void EnvioDato(unsigned char NumCanal, unsigned char Data) // Enva al puerto { switch(NumCanal) { case 1: xout(0x75, Data); // Enva dato al CH1 break; case 2: xout(0x76, Data); // Enva dato al CH2 } } // Fin de EnvioDato
Ing. Javier Barriga Hoyle 58 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 12. Aplicaciones del ADC 0804 (Sin interrupciones) Para usar este Circuito Integrado dentro de la Tarjeta se tiene que incluir en cada programa como cabecera la librera de funciones indicado en el captulo 9 (pgina 24). Como sistema operativo no hay restricciones, puede ser Win98, Win2000 o XP. Las seales analgicas a convertir pueden provenir de diversas fuentes tales como censores de temperatura, posicin, velocidad, presin, flujo, etc. Los siguientes programas en Lenguaje C, muestran como utilizar el ADC en algunas aplicaciones bsicas, para ello hemos empleado un potencimetro de 10K que genere voltajes entre 0 y 5 voltios. El objetivo de estos programas es que se familiaricen con las diversas formas de trabajar con el ADC, luego del cual podrn usarlo en cualquier aplicacin real. Para obtener lecturas ms precisas, es necesario que Vref (voltaje de referencia) del ADC, se ponga en la mitad del voltaje VCC (Vref = 2.5 voltios).
Programa 12.1: (ADC_1.CPP) Tcnica de espera para leer el voltaje de un potencimetro. Realice la siguiente conexin y siga las instrucciones dadas en este programa.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ +5V Salida digital (8 leds) Power E/S Timer SW Timer Unir con el jumper el pin3 y el pin2 de J10, para que la lnea INTR del ADC se conecte con el pin 10 del conector DB25 (bit 6 del puerto 379h). 5 K +5V 1 K 1 K
Figura 12.1. Conexin Tarjeta - ADC - Potencimetro - PPI - Leds.
/******************************************************************************* ADC_1.CPP: (Tcnica de espera) Este programa muestrea un voltaje analgico (0 V - 5 V) en un potencimetro y lo muestra en pantalla, adems lo enva al PortA (puede ser B o C) del PPI el dato en binario para ser visualizado en 8 leds. Toma 10 muestras a intervalos de 2 seg
Descripcin: a) Conecte 8 leds al PortA del PPI. b) Implemente un circuito con un potencimetro entre 0 y 5V. El punto central de ste conctelo al terminal (VI+) de la bornera azul o al molex. c) El terminal VI-, conctelo a tierra; d) El terminal AGND conctelo a tierra. e) El terminal VREF puede conectarse a otro potencimetro con un voltaje de
Ing. Javier Barriga Hoyle 59 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM salida aproximado de 2.5 voltios. Con esto se consigue mayor exactitud en la toma de muestras. f) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. g) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). h) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <windows.h> #include <conio.h> #include <stdio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
xout(0x7B, 0x80); // Configura PPI con PA=PB=PC= OUTs (modo 0)
printf("\t****************************************************\n"); printf("\t* LECTURA DE UNA SENAL ANALOGICA USANDO EL ADC0804 *\n"); printf("\t* (Tecnica de espera) *\n"); printf("\t* *\n"); printf("\t* Captura 10 muestras a intervalos de 2 segundos, *\n"); printf("\t* lo imprime en pantalla y lo muestra en 8 leds. *\n"); printf("\t* Vare el potencimetro para muestras diferentes. *\n"); printf("\t****************************************************\n\n");
/* Proceso de lectura de 10 muestras del ADC a intervalos de 2 seg. */ for(i=0; i<10; i++) { xout(0x6C, 0x00); // Inicia conversin Sleep(1); // Espera 1 ms para que termine conversin dato_adc = xin(0x6C); // Lee dato del ADC xout(0x78, dato_adc); // Enva al PortA del PPI voltios = ((float)dato_adc*5)/255; // Convierte a flotante
/* Muestra en pantalla en formato decimal y binario el dato convertido */ printf("Valor ADC = %0.4f voltios\n", voltios); // 4 decimales print_binario(dato_adc); Sleep(2000); // Espera 2 seg para tomar nueva muestra } } // Fin de main
Ing. Javier Barriga Hoyle 60 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 12.2: (ADC_2.CPP) Tcnica de polling para leer el voltaje de un potencimetro. Utilice la conexin del programa 12.1 (figura 12.1) y siga las instrucciones dadas en este programa.
/******************************************************************************* ADC_2.CPP: (Tcnica de polling o encuesta) Este programa muestrea un voltaje analgico (0 V - 5 V) en un potencimetro y lo muestra en pantalla, adems lo enva al PortA (puede ser B o C) del PPI el dato en binario para ser visualizado en 8 leds. Toma 10 muestras a intervalos de 2 seg
Descripcin: a) Conecte 8 leds al PortA del PPI. b) Implemente un circuito con un potencimetro entre 0 y 5V. El punto central de ste conctelo al terminal (VI+) de la bornera azul o al molex. c) El terminal VI-, conctelo a tierra; d) El terminal AGND conctelo a tierra. e) El terminal VREF puede conectarse a otro potencimetro con un voltaje de salida aproximado de 2.5 voltios. Con esto se consigue mayor exactitud en la toma de muestras. f) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. g) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). h) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <windows.h> #include <conio.h> #include <stdio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
/* Variables globales */ unsigned char dato_adc; int i, flag_int; float voltios;
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
xout(0x7B, 0x80); // Configura PPI con PA=PB=PC= OUTs (modo 0)
printf("\t****************************************************\n"); printf("\t* LECTURA DE UNA SENAL ANALOGICA USANDO EL ADC0804 *\n"); printf("\t* (Tecnica de polling) *\n"); printf("\t* *\n"); printf("\t* Captura 10 muestras a intervalos de 2 segundos, *\n"); printf("\t* lo imprime en pantalla y lo muestra en 8 leds. *\n"); printf("\t* Vare el potencimetro para muestras diferentes. *\n"); printf("\t****************************************************\n\n");
/* Proceso de lectura de 10 muestras del ADC a intervalos de 2 seg. */ for(i=0; i<10; i++) { xout(0x6C, 0x00); // Inicia conversin
while (flag_int != 0x40) // INTR = 0? o termin conversin? flag_int = _inp(Base+1)&0x40; /* Aqu no se usa xin, porque la lnea IRQ7 va directamente al puerto 379h */ dato_adc = xin(0x6C); // Termin conversin, lee dato del ADC xout(0x78, dato_adc); // Enva al PortA del PPI voltios = ((float)dato_adc*5)/255; // Convierte a flotante
/* Muestra en pantalla en formato decimal y binario el dato convertido */ printf("Valor ADC (%d) = %0.4f voltios\n",i,voltios); // 4 decimales
Ing. Javier Barriga Hoyle 61 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM print_binario(dato_adc); printf("\n); // Cambia lnea Sleep(2000); // Espera 2 seg para tomar nueva muestra } } // Fin de main
Programa 12.3: (ADC_3.CPP) Tcnica de polling para leer el voltaje de un potencimetro y mostrarlo en un LCD. Implemente el circuito mostrado y luego siga las instrucciones dadas en este programa.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Power E/S Timer SW Timer LCD 2x16 HD 44780 G N D V C C V L C R s R
/
W E n D 0 D 1 D 2 D 3 D 4 D 5 D 6 D 7 LEYENDA: D[7..0] Bus de datos En Seal de habilitacin R/W Seleccin de lectura (0) o escritura (1) Rs Selector de registro (0 = Reg. Inst, 1 = Reg. Datos) VCC Tensin de alimentacin, 5 V. GND Entrada de alimentacin, 0 V. VLC Entrada de control de constraste (unir al potenciometro) +5V 5 K +5V 1 K 1 K
Figura 12.2. Conexin Tarjeta - ADC - Potencimetro - PPI - LCD.
/******************************************************************************* ADC_3.CPP: (Tcnica del Polling, LCD 2x16: Modo a 4 bits) Este programa muestrea un voltaje analgico (0 V - 5 V) en un potencimetro y lo muestra en un LCD conectado al PortA del PPI. El programa captura 20 muestras a intervalos de 2 segundos.
Descripcin: a) Las conexiones PPI - LCD es: PORTA del PPI: PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 LCD: D7 D6 D5 D4 EN RS X X (La seal WR se conecta a tierra; este programa solo escribe en el LCD). b) Implemente un circuito con un potencimetro entre 0 y 5V. El punto central de ste conctelo al terminal (VI+) de la bornera azul o al molex. c) El terminal VI-, conctelo a tierra; d) El terminal AGND conctelo a tierra. e) El terminal VREF puede conectarse a otro potencimetro con un voltaje de salida aproximado de 2.5 voltios. Con esto se consigue mayor exactitud en la toma de muestras. f) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. g) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). h) Ejecute su programa.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <windows.h>
Ing. Javier Barriga Hoyle 62 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM #include <conio.h> #include <stdio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
#define CONTROL 0 // Constante para el display LCD #define DATO 1 // Constante para el display LCD #define DISPLAY_ON 0x0E // Display ON, cursor ON, blink OFF #define BORRAR_LCD 0x01 #define UCHAR unsigned char
/* Variables globales */ unsigned char dato_adc; int i, j, m, flag_int, num, divisor, cociente, residuo; float voltios;
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI con PA=PB=PC= OUTs (modo 0) InitLCD(); // Inicializa LCD
printf("\t****************************************************\n"); printf("\t* LECTURA DE UNA SENAL ANALOGICA USANDO EL ADC0804 *\n"); printf("\t* *\n"); printf("\t* Captura 20 muestras a intervalos de 2 segundos, *\n"); printf("\t* lo imprime en pantalla y en el LCD de 2x16. *\n"); printf("\t* Varie el potenciometro para muestras diferentes. *\n"); printf("\t****************************************************\n\n");
/* Enva mensaje2 a la fila 1 del LCD */ for(j=0; j<16; j++){ PutcharLCD(DATO, Mensaje2[j]); // Enva mensaje LCD Sleep(200); }
Ing. Javier Barriga Hoyle 63 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /* Enva mensaje3 a la fila 2 del LCD */ GotoxyLCD(2,1); // Posiciona cursor al inicio de la fila 2 for(j=0; j<7; j++){ PutcharLCD(DATO, Mensaje3[j]); // Enva mensaje LCD Sleep(200); } /* Proceso de lectura de 20 muestras del ADC a intervalos de 2 seg */ for(m=0; m<20; m++) { xout(0x6C, 0x00); // Inicia conversin
while (flag_int != 0x40) // INTR = 0? o termin conversin? flag_int = _inp(Base+1)&0x40; /* Aqu no se usa xin, porque la lnea IRQ7 va directamente al puerto 379h */
dato_adc = xin(0x6C); // Termin conversin, lee dato del ADC voltios = ((float)dato_adc*5)/255; // Convierte a flotante
/* Muestra en pantalla y LCD en formato decimal el dato convertido */ printf("Valor ADC (%d) = %0.4f voltios\n",m,voltios); // 4 decimales PrintNumLCD(voltios,2,9); // Imprime voltaje en LCD Sleep(2000); // Espera 2 seg para tomar nueva muestra } } // Fin de main
/*------------------------------------------------------------------------------- Funcin: void InitLcd(void) Inicializa el display LCD. -------------------------------------------------------------------------------*/ void InitLCD(void) { xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 /* RS debe ser estable antes del flanco de subida de EN */ xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(5); // Demora superior a 4,1 ms
xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(1); // Demora superior a 100 s
xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(1); // Demora superior a 100 s /* Selecciona interface de 4 bits */ xout(0x78, 0x28); // DB[7..4] EN RS X X // 0010 1 0 0 0 xout(0x78, 0x20); // DB[7..4] EN RS X X // 0010 0 0 0 0 /* Tras esta inicializacin el display queda en modo 4 bits */ Sleep(1); // Demora superior a 100 s BorraLCD(); // Borra el LCD y lleva cursor al origen } // FIN DE InitLcd
/*------------------------------------------------------------------------------- Funcin: void PutcharLcd(UCHAR direc, UCHAR dato) Envia al display LCD un "dato". Si: direc = 0, se accede al registro de instrucciones direc = 1, se accede al registro de datos -------------------------------------------------------------------------------*/
Ing. Javier Barriga Hoyle 64 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM void PutcharLCD(UCHAR direc, UCHAR dato) { UCHAR temp, temp2; temp2 = 0x08; // Para activar EN if (direc == DATO){ // Es instruccin o dato? temp2 |= 0x04; // Selecciona Dato/Control con RS xout(0x78, 0x04); // DB[7..4] EN RS X X } // 0000 0 1 0 0 else xout(0x78, 0x00); // DB[7..4] EN RS X X // 0000 0 0 0 0 /* RS debe ser estable antes del flanco de subida de EN */
/* Primero se enva el nibble alto */ temp = (dato & 0xf0) | temp2; xout(0x78, temp); // Manda nibble alto con EN = 1 temp &= 0xf5; xout(0x78, temp); // Desactiva EN
/* Despus se manda el nibble bajo */ temp = (dato << 4) | temp2; xout(0x78, temp); // Manda nibble bajo con EN = 1 temp &= 0xf5; xout(0x78, temp); // Desactiva EN Sleep(1); } // FIN DE PutcharLcd
/*------------------------------------------------------------------------------- Funcin: void BorraLCD(void) Establece control del LCD, Borra el LCD, establece Modo de entrada, y coloca el cursor en el origen. -------------------------------------------------------------------------------*/ void BorraLCD(void) { PutcharLCD(CONTROL, DISPLAY_ON); // Display on, cursor ON, blink off PutcharLCD(CONTROL, BORRAR_LCD); // Borra el Display PutcharLCD(CONTROL, 0x06); // Incremento automtico de AC al escribir PutcharLCD(CONTROL, 0x02); // Cursor en la esquina izquierda } // FIN DE BorraLCD
/*------------------------------------------------------------------------------- Funcin: void GotoxyLCD(UCHAR fila, UCHAR columna) Posiciona el cursor en la posicin especificada por fila, columna. Si alguna de las coordenadas es invalida no se hace nada. Coordenadas validas: fila = 1..2, columna = 1..16 -------------------------------------------------------------------------------*/ void GotoxyLCD(UCHAR fila, UCHAR columna) { UCHAR pos_fila, cursor; if((fila<1 || fila>2) || (columna<1 || columna>16)) return;
Ing. Javier Barriga Hoyle 65 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /******************************************************************************** Funcion: void PrintNumLCD(float numero, UCHAR fila, UCHAR columna) Imprime en el LCD un nmero en punto flotante con el formato (x.xxxx), en la posicin especificada por fila y columna. ********************************************************************************/ void PrintNumLCD(float numero, UCHAR fila, UCHAR columna) { unsigned int cuenta; GotoxyLCD(fila, columna); // Posiciona cursor al inicio de la fila 2
/* Se imprime en el LCD */ num = (int)( voltios * 10000 / 1); cociente = num / 10000; // Divide y toma la parte entera residuo = num % 10000; // Divide y toma el residuo PutcharLCD(DATO, cociente + 0x30); // Convierte a ASCII e imprime en LCD PutcharLCD(DATO, '.'); // Imprime punto decimal divisor = 1000; for(cuenta=2; cuenta<6; cuenta++){ cociente = (char)(residuo / divisor); // Divide y toma la parte entera residuo = residuo % divisor; // Divide y toma el residuo PutcharLCD(DATO, cociente + 0x30); // Convierte a ASCII e imprime en LCD divisor = divisor /10; } }
Programa 12.4: (ADC_4.CPP) Control de la velocidad de un motor DC usando un potencimetro y PWM. Para la conexin TIMER Motor ver Apndice E.7.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 Power E/S Timer SW Timer V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ 74LS279 L293D PWM O N O N O N O F F Motor DC +5V 5 K +5V 1 K 1 K
Figura 12.3. Conexin Tarjeta - ADC - Potencimetro - TIMER - Motor DC.
Ing. Javier Barriga Hoyle 66 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM El programa lee a travs del ADC el valor dado por un potencimetro y lo enva al TIMER para generar la seal PWM, cuando el valor sea 0 el motor est parado y a medida que se aumenta ese valor, el motor empezar a girar en sentido horario alcanzando la mxima velocidad cuando sea 255 o FFh. Siga las instrucciones dadas en este programa.
/******************************************************************************** ADC_4.CPP: (Tcnica del Polling y PWM) Este programa controla la velocidad de un motor DC a travs de un potencimetro conectado al ADC0804. El valor obtenido se enva al TIMER para generar la seal PWM, que es la que regula la velocidad del motor.
Descripcin: a) En el SW TIMER, coloque los bits de la siguiente manera: G1(Gate 1)=ON, G2(Gate 2)=OFF, CLK1=ON (8MHz) y CLK2=ON (8 MHz). b) Configure al CH1 en modo 2 a una frecuencia aproximada de 122 Hz. c) Configure al CH2 en modo 5, este opera a una frecuencia variable ingresada por el potencimetro conectado al ADC. d) En la bornera azul TIMER, conecte las salidas del CH1 (OUT1) y CH2 (OUT2) al pin5 y pin6 del 74LS279 respectivamente. e) La salida PWM que se obtiene en el pin7 del 74LS279, conctela al pin 2 del DRIVER L293D y de los pines 3 y 11 de ste al motor. f) Recomiendo ver en un osciloscopio las formas de onda que se generan al variar la velocidad en las salidas del CH1, CH2 y PWM. g) Cree un proyecto en Visual C++ (modo consola) y escriba el programa. h) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5). i) Ejecute su programa y siga las instrucciones de la pantalla.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
/* Inicia programa principal */ void main(void) { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0
printf("\n\t********* CONTROL DE UN MOTOR DC USANDO PWM *********\n\n"); printf("\t\t***** Contadores 1 y 2 para PWM *****\n\n"); printf("\nPara salir del programa pulse ...: (ESC)\n"); printf("\n\nPara variar la velocidad del motor mueva el potenciometro\n"); printf("\n(1) Posicion inicial (0): Motor parado\n"); printf("\n(2) Posicion final (255): Motor velocidad maxima\n\n"); printf("\nVariando frecuencia de contador 2 (Contador 1 = 122 Hz)\n\n");
/* Configura CH1 en modo 2 (Rate Generator) y CH2 en modo 5 (Hardware Triggered Strobe - monoestable) */ xout(0x77, 0x74); // CH1 = 0111 0100 (palabra de control) xout(0x77, 0xBA); // CH2 = 1011 1010 (palabra de control)
/* Inicializa Canal 1 */ DataWord = 0xFFFF; // Fija CH1 a frec = (8MHz/65535) = 122 Hz FrecCanal(1); // Arranca Canal 1, para disparar al Canal 2
Ing. Javier Barriga Hoyle 67 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /* Espera que se vare el potencimetro para variar velocidad */ Fin = 0; while(!Fin) // Espera ESC para terminar { /* Proceso de lectura de muestras del ADC a intervalos de 250 ms */ xout(0x6C, 0x00); // Inicia conversin while (Flag != 0x40) // INTR = 0? o termin conversin? Flag = _inp(Base+1)&0x40; /* Aqu no se usa xin, porque la lnea IRQ7 va directamente al puerto 379h */
DatoADC = xin(0x6C); // Termin conversin, lee dato del ADC AjusteFrecuenciaCanal2(DatoADC); // Ajusta frecuencia de canal 2 Sleep(250); // Retardo de 250 ms
if(kbhit()) // Se puls tecla? { car = getch(); // SI, entonces lee el teclado if(car == 0x1B) Fin = 1; // Si es ESC, sale del programa } } } // Fin de main
/*---------------------------------------------------------------------------- Funciones que trabajan con el TIMER. -----------------------------------------------------------------------------*/ void FrecCanal(unsigned char NumCanal) // Enva 2 BYTES al canal { EnvioDato(NumCanal, DataWord & 0xff); EnvioDato(NumCanal, DataWord >> 8); }
void AjusteFrecuenciaCanal2(unsigned char muestra) // Calcula nueva frecuencia { DataWord = 1000 + muestra*250; // Incrementos cada 250*DatoAdc printf("\tDATA WORD = %u \r",DataWord); FrecCanal(2); // Enva DataWord } // Fin de AjusteFrecuenciaCanal2
void EnvioDato(unsigned char NumCanal, unsigned char Data) // Enva al puerto { switch(NumCanal) { case 1: xout(0x75, Data); // Enva dato al CH1 break; case 2: xout(0x76, Data); // Enva dato al CH2 } } // Fin de EnvioDato
Ing. Javier Barriga Hoyle 68 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 13. Aplicaciones con interrupciones: Pulsadores, ADC0804, TIMER, etc. Para poder entender los programas que usan interrupciones, si UD no tiene conocimientos previos es necesario que se revise el Apndice D.
13.1 Aplicaciones con interrupciones: Sistema Operativo Win2000 o WinXP. Con estos Sistemas Operativos (SO), slo podemos hacer uso de la lnea de interrupcin IRQ0, la IRQ7 del puerto paralelo est bloqueada por restriccin del SO. Adems es imprescindible tener instalado el Borland C++ 3.0 para poder ejecutar los siguientes programas.
Programa 13.1: (IRQO_1.CPP) /******************************************************************************** IRQ0_1.CPP Este programa muestra como contar las interrupciones generadas por la IRQ0 conectada al canal 0 del TIMER de la PC. La frecuencia de entrada al CH0 del TIMER de la PC es de 1.193.180 Hz, el cual es dividida entre 65,535 para producir 18.2 Hz (interrupciones/seg). Se saldr del programa cuando se halla transcurrido 5 segundos.
Descripcin: a) Para producir 5 seg, se deber contar aproximadamente 91 interrupciones. b) Cargue el programa con el TURBO C++ 3.0. c) Compile con ALT + F9. d) Ejecute con CRTL + F9.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h>
/* Declaracin de variables globales */ unsigned char oldimr, newimr; int num_int;
void main(void) // Inicia programa principal { clrscr(); // Borra pantalla instala_imr_vector(); // Modifica IMR e instala vector num_int = 0; // Contador de interrupciones = 0 while(num_int <= 91) // Cuenta 5 segundos (91 interrupciones) { gotoxy(25,5); // (Columna, fila) printf("Interrupciones IRQ0: %d\r", num_int); } restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
Ing. Javier Barriga Hoyle 69 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM void interrupt new_timer(...) // Rutina de servicio de interrupcin { old_timer(); // Llama a la rutina antigua num_int++; // Incrementa cada vez que ocurre una INTR outportb(0x20,0x20); // Enva el EOI }
void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = oldimr & 0xFE; // Activa IRQ0 = 1111 1110 outportb(0x21,newimr); old_timer = getvect(0x08); // Lee vector original setvect(0x08, new_timer); // Instala nuevo vector enable(); // Habilita interrupciones }
void restaura_imr_vector(void) { disable(); setvect(0x08, old_timer); // Restaura vector original outportb(0x21,oldimr); // Restaura IMR original enable(); }
Programa 13.2: (IRQO_2.CPP) /******************************************************************************** IRQ0_2.CPP Este programa muestra como utilizar las interrupciones generadas por la IRQ0 para producir retardos. En este caso, se har desplazar un bit de derecha a izquierda y viceversa a intervalos de 200 ms. Los LEDS se conectan al PortA del PPI. El programa termina cuando se pulse ESC.
Descripcin: a) Con un cable flat, conecte 8 LEDS al PortA del PPI. b) Para producir 200 ms, se deber contar aproximadamente 4 interrupciones. c) Cargue el programa con el TURBO C++ 3.0. d) Compile con ALT + F9. e) Ejecute con CRTL + F9.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
Ing. Javier Barriga Hoyle 70 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM void main(void) // Inicia programa principal { clrscr(); // Borra pantalla inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA = PB = PC = outs
printf("\t***********************************************************\n"); printf("\t* PROGRAMA QUE DESPLAZA UN BIT DE DERECHA A IZQUIERDA Y *\n"); printf("\t* VICEVERSA A INTERVALOS DE 200 ms POR EL PORTA DEL PPI *\n"); printf("\t* *\n"); printf("\t* El retardo de 200 ms se realiza usando la interrupcion *\n"); printf("\t* IRQ0 (4 interrupciones = 200 ms) *\n"); printf("\t***********************************************************\n\n");
printf("Por favor, espere mientras se ejecuta el programa\n\n"); printf("Para salir, pulse ESC(ape)");
instala_imr_vector(); // Modifica el IMR e instala la RSI num_int = 0; // Inicializa contador de interrupciones mseg200 = 0; // Contador de cada 200 ms Fin = 0; dato = 0x01; sentido = 0; // Sentido: (0, izquierda) o (1, derecha) xout(0x78, dato); // Inicializa desplazamiento
/* Espera que se genere las interrupciones */ while(!Fin) // Espera ESC para terminar { if(mseg200==1) { if(sentido==0) { // Desplaza a la izquierda mseg200 = 0; dato = dato << 1; xout(0x78, dato); // Enva a los 8 leds del PortA del PPI if(dato==0x80) sentido=1; // Cambia de sentido (derecha) } else { mseg200 = 0; dato = dato >> 1; xout(0x78, dato); // Enva a los 8 leds del PortA del PPI if(dato==0x01) sentido=0; // Cambia de sentido (izquierda) } }
if(kbhit()) // Se puls tecla? { car = getch(); // SI, entonces lee el teclado if(car == 0x1B) Fin = 1; // Si es ESC, sale del programa } } restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_timer(...) // Rutina de servicio de interrupcin { old_timer(); // Llama a la rutina antigua num_int++; // Incrementa cada vez que ocurre una INTR if(num_int == 4) { // Cuatro interrupciones? mseg200 = 1; num_int = 0; } outportb(0x20,0x20); // Enva el EOI }
void instala_imr_vector(void) {
Ing. Javier Barriga Hoyle 71 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = oldimr & 0xFE; // Activa IRQ0 = 1111 1110 outportb(0x21,newimr); old_timer = getvect(0x08); // Lee vector original setvect(0x08, new_timer); // Instala nuevo vector enable(); // Habilita interrupciones }
void restaura_imr_vector(void) { disable(); setvect(0x08, old_timer); // Restaura vector original outportb(0x21,oldimr); // Restaura IMR original enable(); }
Programa 13.3: (IRQO_3.CPP) /******************************************************************************** IRQ0_3.CPP Este programa muestra como utilizar las interrupciones generadas por la IRQ0 para producir retardos. En este caso, la CPU siempre estar desplazando un bit de derecha a izquierda y viceversa a intervalos de 100 ms. Los LEDS se conectan al PortA del PPI. Adems, cada 1 seg se leer el voltaje analgico dado por el potencimetro conectado al ADC0804. El programa termina cuando se alcance las 20 muestras.
Descripcin: a) Con un cable flat, conecte 8 LEDS al PortA del PPI. b) Conecte un potenciometro al ADC (Realice las conexiones de la figura 12.1) c) Para producir 100 ms, se deber contar aproximadamente 2 interrupciones. d) Para producir 1 seg, se deber contar aproximadamente 18 interrupciones. e) Cargue el programa con el TURBO C++ 3.0. f) Compile con ALT + F9. g) Ejecute con CRTL + F9.
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
void main(void) // Inicia programa principal { clrscr(); // Borra pantalla
Ing. Javier Barriga Hoyle 72 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA = PB = PC = outs
printf("\t************************************************************\n"); printf("\t* PROGRAMA QUE DESPLAZA UN BIT DE DERECHA A IZQUIERDA Y *\n"); printf("\t* VICEVERSA A INTERVALOS DE 100 ms POR EL PORTA DEL PPI. *\n"); printf("\t* ADEMAS, CADA 1 SEG CAPTURA UN DATO ANALOGICO DEL ADC *\n"); printf("\t* *\n"); printf("\t* El retardo de 100 ms se realiza usando la interrupcion *\n"); printf("\t* IRQ0 (2 interrupciones = 100 ms) *\n"); printf("\t************************************************************\n\n");
instala_imr_vector(); // Modifica el IMR e instala la RSI num_int_leds = 0; // Contador de interrupciones de LEDS num_int_adc = 0; // Contador de interrupciones de ADC mseg100 = 0; // Contador de cada 100 ms seg1 = 0; // Contador de cada 1 seg muestras = 0; // Contador de nmero de muestras tomadas dato = 0x01; sentido = 0; // Sentido: (0, izquierda) o (1, derecha) xout(0x78, dato); // Inicializa desplazamiento
/* Espera que se genere las interrupciones */ while(muestras <= 20) // Espera 20 muestras para terminar { if(mseg100==1) // Espera 100 ms para desplazar un bit { if(sentido==0) { // Desplaza a la izquierda mseg100 = 0; dato = dato << 1; xout(0x78, dato); // Enva a los 8 leds del PortA del PPI if(dato==0x80) sentido=1; // Cambia de sentido (derecha) } else { mseg100 = 0; dato = dato >> 1; xout(0x78, dato); // Enva a los 8 leds del PortA del PPI if(dato==0x01) sentido=0; // Cambia de sentido (izquierda) } }
if(seg1==1) // Espera 1 seg para tomar dato del ADC { while (flag_adc != 0x40) // INTR = 0? o termin conversin? flag_adc = inportb(Base+1)&0x40; /* Aqu no se usa xin, porque la lnea IRQ7 va directamente al puerto 379h */
dato_adc = xin(0x6C); // SI, lee dato del ADC voltios = ((float)dato_adc*5)/255; // Convierte a flotante printf("Valor ADC (%d) = %0.4f voltios\n",muestras,voltios); seg1 = 0; muestras++; } } restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_timer(...) // Rutina de servicio de interrupcin { old_timer(); // Llama a la rutina antigua num_int_leds++; // Incrementa cada vez que ocurre una INTR num_int_adc++; // Incrementa cada vez que ocurre una INTR if(num_int_leds == 2) { // Dos interrupciones? mseg100 = 1; num_int_leds = 0; }
Ing. Javier Barriga Hoyle 73 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM if(num_int_adc == 18) { // Dieciocho interrupciones? xout(0x6C, 0x00); // Captura dato e inicia conversin seg1 = 1; num_int_adc = 0; } outportb(0x20,0x20); // Enva el EOI }
void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = oldimr & 0xFE; // Activa IRQ0 = 1111 1110 outportb(0x21,newimr); old_timer = getvect(0x08); // Lee vector original setvect(0x08, new_timer); // Instala nuevo vector enable(); // Habilita interrupciones }
void restaura_imr_vector(void) { disable(); setvect(0x08, old_timer); // Restaura vector original outportb(0x21,oldimr); // Restaura IMR original enable(); }
Ing. Javier Barriga Hoyle 74 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 13.2 Aplicaciones con interrupciones: Sistema Operativo Win98. Con este Sistema Operativo, podemos usar las lneas de interrupciones IRQ0 y IRQ7 sin ningn problema. Similar al caso anterior, es imprescindible tener instalado el Borland C++ 3.0 para poder ejecutar los siguientes programas.
Programa 13.4: (IRQ7_1.CPP) Cuenta las interrupciones producidas por un pulsador sin rebotes conectado a la lnea IRQ7. El programa termina cuando se alcance 10 interrupciones. Realice la siguiente conexin.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Salida digital (8 leds) Power E/S Timer SW Timer NOTA: Quite el jumper del conector J10, para dejar libre el pin3 (ADC) y el pin2 (IRQ7). Ahora la salida del pulsador conctelo al pin 1 para generar interrupciones.
+5V S1 START + C1 10uF R2 10K R1 330 PIN 1 74HC14
Figura 13.1. Conexin Tarjeta - Pulsador sin rebotes, para generar interrupciones.
Observar que cada vez que pulsa S1 (START), generar una interrupcin, incrementa el contador y lo visualizar en la pantalla (sugerencia: analice el programa y trate de entenderlo para futuras aplicaciones).
/******************************************************************************** IRQ7_1.CPP Este programa cuenta las interrupciones generadas externamente por un pulsador conectado a la lnea IRQ7 del puerto paralelo de la computadora, las imprime en pantalla y las enva a 8 leds conectados al PortA del PPI de la tarjeta LPT V2.0
Descripcin: a) Conecte un pulsador sin rebote a la lnea IRQ7 (pin 1 del J10). b) Conecte 8 leds al PortA del PPI. c) Cada vez que se active el pulsador, generara una interrupcin a la CPU. d) El programa termina cuando se alcance 10 interrupciones. e) Cargue el programa Turbo C++ 3.0 y abra el programa INTE_1.CPP, luego compile con ALT+F9, y ejecute el programa con CTRL+F9.
Ing. Javier Barriga Hoyle 75 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Variables globales */ unsigned char oldimr, newimr; int num_int;
void main(void) // Inicia programa principal { clrscr(); // Borra pantalla inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA = PB = PC = outs
printf("\t*********************************************************\n"); printf("\t* PROGRAMA QUE CUENTA LAS INTERRUPCIONES EXTERNAS *\n"); printf("\t* GENERADAS EN LA LINEA IRQ7 *\n"); printf("\t* *\n"); printf("\t* El numero de interrupciones generadas por el pulsador *\n"); printf("\t* se imprime en pantalla y tambin en el PortA del PPI. *\n"); printf("\t*********************************************************\n\n");
instala_imr_vector(); // Modifica el IMR e instala la RSI num_int = 0; // Inicializa contador de interrupciones
/* Habilita la IRQ_EN del puerto paralelo, poniendo en UNO el BIT 4 del puerto 0x37A (base+2) */ outportb(0x37A, inportb(0x37A) | 0x10); // IRQ_EN = 1
/* Espera que se genere las interrupciones */ while(num_int <= 10) // Cuenta 10 interrupciones { xout(0x78, num_int); // Enva a los 8 leds del PortA del PPI printf("\t\t\tInterrupciones IRQ7: %d\r", num_int); } restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_irq7(...) // Rutina de servicio de interrupcin { old_irq7(); // Llama al vector antiguo num_int ++; // Incrementa contador de interrupciones outportb(0x20, 0x20); // Enva el EOI }
void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR
Ing. Javier Barriga Hoyle 76 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM newimr = 0x7F & oldimr; // Activa IRQ7 = 0111 1111 outportb(0x21,newimr); // Enva nueva IMR al PIC old_irq7 = getvect(0x0F); // Lee vector original setvect(0x0F,new_irq7); // Instala nuevo vector enable(); // Habilita interrupciones }
Programa 13.5: (IRQ7_2.CPP) Cada vez que se produce una interrupcin, lee el dato colocado en el PortB del PPI (Dipswitch) y lo enva al PortA del PPI (Leds). El programa termina cuando se alcance 10 interrupciones. Realice la siguiente conexin.
0s 1s Entrada digital (8 bits) ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Salida digital (8 leds) Power E/S Timer SW Timer
+5V S1 START + C1 10uF R2 10K R1 330 PIN 1 74HC14
Figura 13.2. Conexin Tarjeta - Pulsador sin rebotes Dipswitch y Leds.
/****************************************************************************** IRQ7_2.CPP Este programa cada vez que se active el pulsador, genera una interrupcion, se lee el dipswitch conectado al PortB del PPI y el valor ledo se enva al PortA del PPI. El programa termina cuando se genere 10 interrupciones IRQ7. Descripcin: a) Conecte un pulsador sin rebote a la lnea IRQ7 (J10). b) Conecte 8 leds al PortA del PPI de la tarjeta LPT V2.0. c) Conecte un dipswitch de 8 bits al PortB del PPI de la tarjeta LPT V2.0. d) Cargue el Turbo C++ 3.0, compile (ALT+F9) y ejecutelo (CTRL+F9).
Ing. Javier Barriga Hoyle 77 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM e) El programa termina cuando se alcance 10 interrupciones.
Autor: Ing. Javier Barriga Hoyle **************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
void main(void) // Inicia programa principal { clrscr(); inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 xout(0x7B, 0x82); // Configura PPI como PA=PC=out, PB=in
printf("\t*********************************************************\n"); printf("\t* PROGRAMA QUE MUESTRA LA UTILIDAD DE TRABAJAR CON *\n"); printf("\t* INTERRUPCIONES EXTERNAS (IRQ7) *\n"); printf("\t* *\n"); printf("\t* Al activarse el pulsador, se genera la interrupcion *\n"); printf("\t* se lee el dipswitch y el valor se envia a los leds. *\n"); printf("\t*********************************************************\n\n");
instala_imr_vector(); // Modifica el IMR e instala la RTI num_int = 0; // Inicializa contador de interrupciones
/* Habilita la IRQ_EN del puerto paralelo, poniendo en UNO el BIT 4 del puerto 0x37A (base+2) */ outportb(0x37A, inportb(0x37A) | 0x10); // IRQ_EN = 1
/* Espera que se genere las interrupciones */ while(num_int <= 10); // Cuenta 10 interrupciones restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_irq7(...) // Rutina de servicio de interrupcin { old_irq7(); // Llama al vector antiguo dato = xin (0x79); // Se lee del PortB del PPI xout (0x78, dato); // Se enva al PortA del PPI num_int++; // Incrementa contador de interrupciones outportb(0x20, 0x20); // Se enva el EOI } void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = 0x7F & oldimr; // Activa IRQ7 = 0111 1111
Ing. Javier Barriga Hoyle 78 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM outportb(0x21,newimr); // Enva nueva IMR al PIC old_irq7 = getvect(0x0F); // Lee vector original setvect(0x0F,new_irq7); // Instala nuevo vector enable(); // Habilita interrupciones }
Programa 13.6: (IRQ7_3.CPP) Cada vez que se produce una interrupcin, se enva a un LCD conectado al PortA del PPI el nmero de interrupciones generadas, mientras la CPU por el PortC realiza en todo instante un corrimiento de BITS por 8 leds. El programa termina cuando se pulse la tecla ESC(escape). Realice la siguiente conexin.
Salida digital (8 leds) G N D V C C V L C R s R
/
W E n D 0 D 1 D 2 D 3 D 4 D 5 D 6 D 7 ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Power E/S Timer SW Timer INTERRUPCIONES IRQ7 = 0
+5V S1 START + C1 10uF R2 10K R1 330 PIN 1 74HC14
Figura 13.3. Conexin Tarjeta - Pulsador sin rebotes - LCD y Leds.
El programa principal siempre est realizando lo siguiente: En un inicio los leds estn apagados y comienzan a prenderse desde los extremos hacia el centro; luego se van apagando desde el centro hacia los extremos y as sucesivamente. Es muy vistosa e interesante la lgica empleada para generarlo.
Ing. Javier Barriga Hoyle 79 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM
/****************************************************************************** IRQ7_3.CPP Este programa tiene como rutina principal, prender secuencialmente los leds desde los extremos hacia el centro, luego se irn apagando desde el centro hacia los extremos y as sucesivamente. Los leds se conectan al PortC del PPI. Cuando se genera una interrupcin por la lnea IRQ7, se incrementa la cuenta de interrupciones (mximo 99) y se enva al LCD conectado al PortA del PPI. El programa termina cuando se pulse ESC (escape).
Descripcin: a) Conecte un pulsador sin rebote a la lnea IRQ7 (jumper J10). b) Conecte 8 leds al Puerto C del PPI. c) Conecte el LCD al Puerto A del PPI de la siguiente manera: PortA : PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 LCD : D7 D6 D5 D4 EN RS X X nota: la seal WR, se pone a CERO porque solo se escribe.
e) Cargue el Turbo C++ 3.0, compile (ALT+F9) y ejectelo (CTRL+F9).
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Prototipos para la interrupcin */ void interrupt (*old_irq7)(...); // Vector antiguo void interrupt new_irq7(...); // Nueva RSI void instala_imr_vector(void); void restaura_imr_vector(void);
/* Prototipos para el LCD */ void PutcharLCD(UCHAR direc, UCHAR dato); void BorraLCD(void); void InitLCD(void); void GotoxyLCD(UCHAR fila, UCHAR columna);
/* Define constantes */ #define CONTROL 0 // Constante para el display LCD #define DATO 1 // Constante para el display LCD #define DISPLAY_ON 0x0E // Display ON, cursor ON, blink OFF #define DIS_ON_CUR_OFF 0x0C // Display ON, cursor OFF, blink OFF #define BORRAR_LCD 0x01 #define CURSOR_ORIGEN 0x80 // Apuntar al origen de la RAM de datos #define CG_RAM_ORIGEN 0x40 // Apuntar al origen de la RAM gen de caract #define UCHAR unsigned char
Ing. Javier Barriga Hoyle 80 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /* Define mensajes a enviar al LCD */ char Mensaje1[28] = {"ARQUITECTURA DE COMPUTADORAS"}; // ambas filas char Mensaje2[16] = {" INTERRUPCIONES "}; // fila 1 char Mensaje3[9] = {" IRQ7 = "}; // fila 2
/* Define variables globales */ UCHAR oldimr, newimr, car, bit, y, z, MSB, LSB, num_dec, num_int; int j, fin;
void main (void) // Inicia programa principal { clrscr(); // Borra pantalla inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 xout(0x7B, 0x80); // Configura PPI como PA = PB = PC = outs InitLCD(); // Inicializa LCD
printf("\t*********************************************************\n"); printf("\t* PROGRAMA QUE CUENTA LAS INTERRUPCIONES EXTERNAS *\n"); printf("\t* GENERADAS EN LA LINEA IRQ7 *\n"); printf("\t* *\n"); printf("\t* El numero de interrupciones generadas se envia al LCD *\n"); printf("\t* mientras se desplaza bits en el PortC del PPI. *\n"); printf("\t*********************************************************\n\n");
/* Enva mensaje de bienvenida al LCD */ while(j<28) { for(j=0; j<16; j++){ PutcharLCD(DATO, Mensaje1[j]); delay(150); } GotoxyLCD(2,2); // Posiciona cursor en la fila 2, columna 2 for(j=16; j<28; j++){ PutcharLCD(DATO, Mensaje1[j]); delay(150); } } delay(2000); // Retardo de 2 seg. BorraLCD(); // Borra el LCD
/* Enva mensaje para visualizar el nmero de interrupciones en el LCD */ for(j=0; j<16; j++) { PutcharLCD(DATO, Mensaje2[j]); delay(150); } GotoxyLCD(2,1); // Posiciona cursor al inicio de la fila 2 for(j=0; j<8; j++) { PutcharLCD(DATO, Mensaje3[j]); delay(150); } // Fin de enviar mensajes
instala_imr_vector(); // Modifica el IMR e instala la RSI
/* Habilita la IRQ_EN del puerto paralelo, poniendo en UNO el BIT 4 del puerto 0x37A (base+2) */ outportb(0x37A, inportb(0x37A) | 0x10); // IRQ_EN = 1
/* Rutina principal que desplaza bits, mientras se espera que se genere las interrupciones. Sale del programa cuando se pulse ESC */ fin = 0; bit = 0; num_int = 0; num_dec = 0; while( !fin ) // Se ejecuta mientras no se pulse ESC {
Ing. Javier Barriga Hoyle 81 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM y = 0x01; // Rutina de desplazamientos z = 0x80; for(j=1; j<=8; j++){ xout(0x7A, bit); // Se enva al PortC delay(200); // Retardo de 200 ms bit = bit ^ y; bit = bit ^ z; y = y << 1; z = z >> 1; } if(kbhit()){ // Se activ alguna tecla? car = getch(); // SI, entonces se lee la tecla y si es ESC if(car == 27) Fin=1; // salir del programa } } restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_irq7(...) // Rutina de servicio de interrupcin { old_irq7(); // Llama al vector antiguo num_int ++; // Incrementa contador de interrupciones if(num_int > 9){ num_int = 0; // Reinicia unidades num_dec++; // Incrementa decenas } GotoxyLCD(2,9); // Posiciona cursor en la fila 2 LSB = num_int + 0x30; // Convierte a ASCII MSB = num_dec + 0x30; PutcharLCD(DATO, MSB); // Se enva al LCD PutcharLCD(DATO, LSB); // Se enva al LCD outportb(0x20, 0x20); // Se enva el EOI }
void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = oldimr & 0x7F; // Activa IRQ7 = 0111 1111 outportb(0x21,newimr); // Enva nueva IMR al PIC old_irq7 = getvect(0x0F); // Lee vector original setvect(0x0F,new_irq7); // Instala nuevo vector enable(); // Habilita interrupciones }
/****************************************************************** Funcin: void InitLcd(void) Inicializa el display LCD. ******************************************************************/ void InitLCD(void) { xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 /* RS debe ser estable antes del flanco de subida de EN */ xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0
Ing. Javier Barriga Hoyle 82 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Sleep(5); // Demora superior a 4,1 ms
xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(1); // Demora superior a 100 s
xout(0x78, 0x38); // DB[7..4] EN RS X X // 0011 1 0 0 0 xout(0x78, 0x30); // DB[7..4] EN RS X X // 0011 0 0 0 0 Sleep(1); // Demora superior a 100 s /* Selecciona interface de 4 bits */ xout(0x78, 0x28); // DB[7..4] EN RS X X // 0010 1 0 0 0 xout(0x78, 0x20); // DB[7..4] EN RS X X // 0010 0 0 0 0 /* Tras esta inicializacin el display queda en modo 4 bits */ Sleep(1); // Demora superior a 100 s BorraLCD(); // Borra el LCD y lleva cursor al origen } // FIN DE InitLcd
/****************************************************************** Funcin: void PutcharLcd(UCHAR direc, UCHAR dato) Envia al display LCD un "dato". Si: direc = 0, se accede al registro de instrucciones direc = 1, se accede al registro de datos ******************************************************************/ void PutcharLCD(UCHAR direc, UCHAR dato) { UCHAR temp, temp2; temp2 = 0x08; // Para activar EN if (direc == DATO) // Es instruccin o dato? { temp2 |= 0x04; // Selecciona Dato/Control con RS xout(0x78, 0x04); // DB[7..4] EN RS X X } // 0000 0 1 0 0 else xout(0x78, 0x00); // DB[7..4] EN RS X X // 0000 0 0 0 0 /* RS debe ser estable antes del flanco de subida de EN */
/* Primero se enva el nibble alto */ temp = (dato & 0xf0) | temp2; xout(0x78, temp); // Manda nibble alto con EN = 1 temp &= 0xf5; xout(0x78, temp); // Desactiva EN
/* Despus se manda el nibble bajo */ temp = (dato << 4) | temp2; xout(0x78, temp); // Manda nibble bajo con EN = 1 temp &= 0xf5; xout(0x78, temp); // Desactiva EN Sleep(1); } // FIN DE PutcharLcd
/*------------------------------------------------------------------------------- Funcin: void BorraLCD(void) Establece control del LCD, Borra el LCD, establece Modo de entrada, y pone el cursor en el origen. -------------------------------------------------------------------------------*/ void BorraLCD(void) { PutcharLCD(CONTROL, DISPLAY_ON); // Display on, cursor ON, blink off PutcharLCD(CONTROL, BORRAR_LCD); // Borrar el Display PutcharLCD(CONTROL, 0x06); // Incremento automtico de AC al escribir
Ing. Javier Barriga Hoyle 83 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM PutcharLCD(CONTROL, 0x02); // Cursor en la esquina izquierda } // FIN DE BorraLCD
/*------------------------------------------------------------------------------- Funcin: void GotoxyLCD(UCHAR fila, UCHAR columna) Posiciona el cursor en la posicin especificada por fila, columna. Si alguna de las coordenadas es invalida no se hace nada. Coordenadas validas: fila = 1..2, columna = 1..16 -------------------------------------------------------------------------------*/ void GotoxyLCD(UCHAR fila, UCHAR columna) { UCHAR pos_fila, cursor;
Programa 13.7: (IRQ7_4.CPP) Uso de la tcnica de interrupciones (IRQ7) para leer el voltaje analgico dado por el potencimetro a intervalos de 2 segundos. Realice la siguiente conexin:
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Salida digital (8 leds) Power E/S Timer SW Timer Unir con el jumper el pin3 y el pin2 de J10, para que la lnea INTR del ADC se conecte con el pin 10 del conector DB25 (bit 6 del puerto 379h). +5V 5 K +5V 1 K 1 K
Figura 13.4. Conexin Tarjeta - ADC - Potencimetro - PPI - Leds.
Ing. Javier Barriga Hoyle 84 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM /****************************************************************************** IRQ7_4.CPP: (Emplea la interrupcin IRQ7 para leer el ADC) Este programa muestrea a intervalos de 2 seg. un voltaje analgico (0V-5V) de un potencimetro y lo imprime en la pantalla, adems enva el dato en binario al PortA (puede ser B o C) del PPI para que se vea en los 8 leds. El retardo de DOS segundos se genera llamando a la funcin delay. El programa termina cuando se pulse ESC(escape)
Descripcin: a) Implemente un circuito con un potencimetro entre 0 y 5V. b) El punto central de ste conctelo al terminal (VI+) de la bornera azul o al molex. c) El terminal VI-, conctelo a tierra. d) El terminal AGND conctelo a tierra. e) El terminal VREF puede conectarse a otro potencimetro con un voltaje de salida aproximado de 2.5 voltios. Con esto se consigue mayor exactitud en la toma de muestras. f) Cargue el programa Turbo C++ 3.0 y abra el programa ADC_5, luego compile con ALT+F9, y ejecute el programa con CTRL+F9.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera para la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
void main(void) { clrscr(); // Borra pantalla inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 xout(0x7B,0x80); // Configura PPI como PA = PB = PC = outs instala_imr_vector(); // Modifica IMR e instala vector de IRQ7
/* Habilita la IRQ_EN del puerto paralelo, poniendo en UNO el bit 4 del puerto 0x37A (base+2) */ outportb(0x37A, inportb(0x37A) | 0x10); // IRQ_EN = 1
printf("\n"); printf("\t*********************************************************\n"); printf("\t* PROGRAMA QUE CAPTURA SEALES ANALOGICAS PROVENIENTES *\n"); printf("\t* DE UN POTENCIOMETRO, USANDO LA INTERRUPCION IRQ7 *\n"); printf("\t* *\n"); printf("\t* El valor obtenido se enva a la pantalla y al PortA *\n"); printf("\t* del PPI. Las muestras se realizan cada 2 segundos. *\n"); printf("\t* Para salir del programa, pulse ESC(escape). *\n"); printf("\t*********************************************************\n\n");
Fin = 0;
Ing. Javier Barriga Hoyle 85 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM muestras = 0;
while(!Fin) // El programa termina cuando se pulse ESC { xout(0x6C, 0x00); // Inicia conversin del ADC if(datolisto == 1) // Termin conversin INT = 0? { dato_adc = xin(0x6C); // SI, procede a leerse el dato xout(0x78, dato_adc); // Enva dato ledo al PortA del PPI voltios = (float)dato_adc * 5 / 255; // Convierte a flotante gotoxy(22,12); printf("lectura ADC(%d) = %0.4f voltios",muestras,voltios); //4 decimales datolisto = 0; // Borra flag para otra interrupcin delay(2000); // Retardo de 2 segundos
if(kbhit()) // Se activ alguna tecla? { car = getch(); // SI, entonces se lee la tecla y si es ESC if(car == 27) Fin=1; // salir del programa } } } restaura_imr_vector(); /* Termina el programa, recupera la mscara y el vector original */ } // Fin de main
void interrupt new_adc(...) // Rutina de servicio de interrupcin { old_adc(); // Llama al vector original datolisto = 1; // Flag, indica que se activ interrupcin muestras++; // Incrementa nmero de muestras outportb(0x20,0x20); // Enva el EOI }
void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = 0x7F & oldimr; // Activa IRQ7 = 0111 1111 outportb(0x21,newimr); // Enva nueva IMR al PIC old_adc = getvect(0x0F); // Lee vector original setvect(0x0F,new_adc); // Instala nuevo vector enable(); // Habilita interrupciones }
Ing. Javier Barriga Hoyle 86 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Programa 13.8: (IRQ7_5.CPP) Uso de las interrupciones IRQ7 (ADC) e IRQ0 (TIMER de la PC). Utilice el circuito del programa IRQ7_4.CPP
/****************************************************************************** IRQ7_5.CPP: (Emplea las interrupciones IRQ0 y IRQ7) Este programa muestrea a intervalos de 1 seg. un voltaje analgico (0V-5V) de un potencimetro y lo imprime en la pantalla, adems enva el dato en binario al PortA (puede ser B o C) del PPI para que se vea en los 8 leds. El retardo de 1 segundo se genera programando la interrupcin IRQ0. La lnea INTR del ADC se conecta a la interrupcin IRQ7. El programa termina cuando se pulse ESC(escape).
Descripcin: a) Implemente un circuito con un potencimetro entre 0 y 5V. b) El punto central de ste conctelo al terminal (VI+) de la bornera azul o al molex; c) El terminal VI-, conctelo a tierra. d) El terminal AGND conctelo a tierra. e) El terminal VREF puede conectarse a otro potencimetro con un voltaje de salida aproximado de 2.5 voltios. Con esto se consigue mayor exactitud en la toma de muestras.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ ##include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera para la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
void main(void) // Inicia programa principal { clrscr(); // Borra pantalla inicio_tarjeta(); // Inicializa tarjeta de interfase LPT V2.0 instala_imr_vector(); // Modifica IMR e instala el vector de IRQ7 xout(0x7B,0x80); // Configura PPI como PA = PB = PC = out
/* Habilita la IRQ_EN del puerto paralelo, poniendo en UNO el bit 4 del puerto 0x37A (base+2) */ outportb(0x37A, inportb(0x37A) | 0x10); // IRQ_EN = 1
printf("\n"); printf("\t*********************************************************\n"); printf("\t* PROGRAMA QUE CAPTURA SEALES ANALOGICAS PROVENIENTES *\n"); printf("\t* DE UN POTENCIOMETRO, USANDO LAS INTERRUPCIONES IRQ0-7 *\n"); printf("\t* *\n");
Ing. Javier Barriga Hoyle 87 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM printf("\t* El valor obtenido se enva a la pantalla y al PortA *\n"); printf("\t* del PPI. Las muestras se realizan cada 1 segundo. *\n"); printf("\t* Para salir del programa, pulse ESC(escape). *\n"); printf("\t*********************************************************\n\n");
muestras = 0; // Inicia contador de muestras en cero num_int = 0; // Inicia Contador de interrupciones a cero Fin = 0; // Flag de fin xout(0x6C, 0x00); // Inicia conversin del ADC en t = 0 seg
while(!Fin) // Programa continua hasta que se pulse ESC { if(datolisto == 1) // Termin conversin INTR = 0? { dato_adc = xin(0x6C); // SI, procede a leerse el dato xout(0x78, dato_adc); // Enva dato ledo al PortA del PPI voltios = (float)dato_adc * 5 / 255; // Convierte a flotante gotoxy(22,12); printf("lectura ADC(%d) = %0.4f voltios",muestras,voltios); //4 decimales datolisto = 0; // Borra flag para otra interrupcin
if(kbhit()) // Se activ alguna tecla? { car = getch(); // SI, entonces se lee la tecla if(car == 27) Fin=1; // Salir del programa } } } restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_timer(...) // Rutina de servicio de interrupcin { old_timer(); // Llama al vector original num_int++; // Incrementa nmero de interrupciones if(num_int == 18) // Pas 1 segundo? { num_int = 0; // Reinicia contador de interrupciones xout(0x6C, 0x00); // Inicia conversin del ADC muestras++; // Incrementa nmero de muestras } outportb(0x20,0x20); // Enva el EOI }
void interrupt new_adc(...) // Rutina de servicio de interrupcin { old_adc(); // Llama al vector original datolisto = 1; // Flag que indica que termino conversin outportb(0x20,0x20); // Enva el EOI }
void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = oldimr & 0x7E; // Activa IRQ7 e IRQ0 (0111 1110) outportb(0x21,newimr); // Enva nueva IMR al PIC old_timer = getvect(0x08); // Lee vector 8 original setvect(0x08,new_timer); // Instala nuevo vector old_adc = getvect(0x0F); // Lee vector 15 original setvect(0x0F,new_adc); // Instala nuevo vector enable(); // Habilita interrupciones }
void restaura_imr_vector(void) {
Ing. Javier Barriga Hoyle 88 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM disable(); // Deshabilita interrupciones setvect(0x08,old_timer); // Restaura vector 8 original setvect(0x0F,old_adc); // Restaura vector 15 original outportb(0x21,oldimr); // Restaura IMR original enable(); // Habilita interrupciones }
Programa 13.9: (IRQ7_6.CPP) Uso de las interrupciones IRQ7 (ADC) e IRQ0 (TIMER de la PC). Los datos muestreados sern almacenados en un archivo muestreo.txt. Utilice el circuito del programa IRQ7_4.CPP
/****************************************************************************** IRQ7_6.CPP: (Emplea las interrupciones IRQ0 y IRQ7) Este programa muestrea a intervalos de 1/2 seg un voltaje analgico (0V-5V) de un potencimetro y lo imprime en la pantalla, adems enva el dato en binario al PORT A (puede ser B o C) del PPI para que se vea en los 8 leds. El retardo de 1/2 segundo se genera programando la interrupcin IRQ0. La lnea INT del ADC se conecta a la interrupcin IRQ7. El programa termina cuando se alcance las 200 muestras. Los datos se almacenan en el archivo muestreo.txt.
Descripcin: a) Implemente un circuito con un potencimetro entre 0 y 5V. b) El punto central de ste conctelo al terminal (VI+) de la bornera azul o al molex; c) El terminal VI-, conctelo a tierra. d) El terminal AGND conctelo a tierra. e) El terminal VREF puede conectarse a otro potencimetro con un voltaje de salida aproximado de 2.5 voltios. Con esto se consigue mayor exactitud en la toma de muestras.
Autor: Ing. Javier Barriga Hoyle ******************************************************************************/ #include <dos.h> // Librera DOS para el Turbo C++ #include <conio.h> #include <stdio.h> #include "BymDOS.h" // Librera para la tarjeta LPT V2.0
int Base = 0x378; // Direccin base del puerto paralelo
/* Declaracin de variables globales */ unsigned char oldimr, newimr, datolisto, car, dato_adc; int Fin, num_int, muestras; float voltios;
void main(void) // Inicia programa principal { FILE *archivo; clrscr(); // Borra pantalla inicio_tarjeta(); // Inicializa tarjeta LPT V2.0 xout(0x7B,0x80); // Configura PPI como PA = PB = PC = out
Ing. Javier Barriga Hoyle 89 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM printf("\n"); printf("\t**********************************************************\n"); printf("\t* PROGRAMA QUE CAPTURA SEALES ANALOGICAS PROVENIENTES *\n"); printf("\t* DE UN POTENCIOMETRO, USANDO LAS INTERRUPCIONES IRQ0-7 *\n"); printf("\t* *\n"); printf("\t* El valor obtenido se envia a la pantalla y al PortA *\n"); printf("\t* del PPI. Ademas, cada muestra se guarda en un archivo. *\n); printf(\t* Las muestras se realizan cada 1/2 segundo. *\n"); printf("\t* El programa termina cuando se pulse ESC(escape) o *\n"); printf("\t* cuando se alcance las 200 muestras. *\n"); printf("\t**********************************************************\n\n");
instala_imr_vector(); // Modifica IMR e instala el vector de IRQ7
/* Habilita la IRQ_EN del puerto paralelo, poniendo en UNO el bit 4 del puerto 0x37A (base+2) */ outportb(0x37A, inportb(0x37A) | 0x10); // IRQ_EN = 1
muestras = 0; // Inicia contador de muestras en cero num_int = 0; // Inicia Contador de interrupciones a cero Fin = 0; // Flag de fin
xout(0x6C,0x00); // Inicia conversin del ADC en t = 0 while(muestras <= 200) /* Programa contina hasta que se pulse ESC cuando se alcance 200 muestras */ { if(datolisto == 1) // Termin conversin INTR = 0? { dato_adc = xin(0x6C); // SI, procede a leerse el dato xout(0x78, dato_adc); // Enva dato ledo al PortA del PPI voltios = (float)dato_adc * 5 / 255; // Convierte a flotante fprintf(archivo,"%f\n",voltios); // Almacena dato en el archivo gotoxy(22,12); printf("lectura ADC(%d) = %0.4f voltios",muestras,voltios); //4 decimales datolisto = 0; // Borra flag para otra interrupcin if(kbhit()) // Se activ alguna tecla? { car = getch(); // SI, entonces se lee la tecla if(car == 27) Fin=1; // Salir del programa } } } fclose(archivo); // Cierra archivo muestreo.txt restaura_imr_vector(); /* Termina el programa, recupera la mascara y el vector original */ } // Fin de main
void interrupt new_timer(...) // Rutina de servicio de interrupcin { old_timer(); // Llama al vector original num_int++; // Incrementa nmero de interrupciones if(num_int == 9){ // Pas 1/2 segundo? num_int = 0; // SI, reinicio contador de interrupciones xout(0x6C,0x00); // Captura dato del ADC e inicia conversin muestras++; // Incrementa nmero de muestras } outportb(0x20,0x20); // Enva el EOI }
void interrupt new_adc(...) // Rutina de servicio de interrupcin { old_adc(); // Llama al vector original datolisto = 1; // Flag que indica que termino conversin outportb(0x20,0x20); // Enva el EOI }
Ing. Javier Barriga Hoyle 90 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM void instala_imr_vector(void) { disable(); // Deshabilita interrupciones oldimr = inportb(0x21); // Lee la mscara IMR newimr = oldimr & 0x7E; // Activa IRQ7 e IRQ0 (0111 1110) outportb(0x21,newimr); // Enva nueva IMR al PIC old_timer = getvect(0x08); // Lee vector 8 original setvect(0x08,new_timer); // Instala nuevo vector old_adc = getvect(0x0F); // Lee vector 15 original setvect(0x0F,new_adc); // Instala nuevo vector enable(); // Habilita interrupciones }
void restaura_imr_vector(void) { disable(); // Deshabilita interrupciones setvect(0x08,old_timer); // Restaura vector 8 original setvect(0x0F,old_adc); // Restaura vector 15 original outportb(0x21,oldimr); // Restaura IMR original enable(); // Habilita interrupciones }
Ing. Javier Barriga Hoyle 91 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM 14. Aplicaciones del DAC 0830 Programa 14.1: (DAC_1.CPP) Programa de prueba del DAC. Se le enva datos binarios para obtener voltajes de salida entre 0V hasta +5V. Realice la siguiente conexin.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Power E/S Timer SW Timer + - + - +5V 3 2 10K 10K Inversor +V -V El esquemtico completo puede verlo en la figura E8, del apndice E. LM741 LM741
Figura 14.1 Circuito simplificado de prueba del DAC0830 OPAMP 741.
/******************************************************************************** DAC_1.CPP Este programa sirve para probar el funcionamiento del DAC. Se le enva valores binarios desde 0 hasta 255 (00h - FFh), para obtener un voltaje de salida entre 0V y +5V aproximadamente.
Descripcin: a) Realice las conexiones mostradas en la figura 14.1 b) El voltaje de Referencia del DAC0830 es +5V. c) El primer OPAMP (U1) se conecta a la salida del DAC0830. El voltaje de salida estar entre 0 y -5V. d) Conecte a la salida del OPAMP (U1), el segundo OPAMP (U2) configurado para operar en modo INVERSOR, el cual invierte el voltaje de salida negativo a positivo (0V a +5V). e) Escriba el programa en Visual C++ (modo consola) f) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/ #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
int i, Fin; unsigned char car;
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 Fin=0; i = 0;
Ing. Javier Barriga Hoyle 92 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM while(!Fin){ xout(0x5C, i); // Enva dato = i, al DAC Sleep(100); // Pequeo retardo de 100 ms printf("i = %d\n",i); i++; // Incrementa valor de i if(i == 256) Fin = 1; if(kbhit()) // Pulso tecla? { car=getch(); // SI, leer tecla if(car == 27) Fin=1; // Si es ESC, salir del programa } } }
Programa 14.2: (DAC_2.CPP) Programa que lee un voltaje del ADC0804, lo convierte a digital y luego lo enva al DAC0830 para que lo muestre el voltaje en un multmetro. Realice la siguiente conexin.
ADC0804 L P T D B 2 5 DAC0830 P P I 8 2 C 5 5 TIMER 82C54 P A P B P C G 2 G 1 C L K 2 C L K 1 O U T 2 O U T 1 G 2 G 1 C L K 2 C L K 1 V I + V I - V R E F A G N D V R E F A G N D R F B O U T 2 O U T 1 IRQ7 LIBRE ADC J10 3 2 1 + 5 V G N D 8 MHZ Power E/S Timer SW Timer + - + - +5V 3 2 10K 10K Inversor +V -V El esquemtico completo puede verlo en las figuras E8 y E9, del apndice E. LM741 LM741 +5V 5 K Vcc / 2
Figura 14.2 Circuito simplificado de ADC0804 y DAC0830.
/******************************************************************************** DAC_2.CPP Este programa sirve para leer un valor analgico dado por un potencimetro y su valor obtenido, se enva a un DAC para medir el voltaje dado por el ADC.
Descripcin: a) Realice las conexiones mostradas en la figura 14.1 y 14.2 b) Vare el potencimetro para generar distintos niveles de voltaje que ingrese al ADC0804. c) Los valores obtenidos sern envados al DAC0830 para convertirlo a analgico. El voltaje estar entre 0V y +5V. d) El programa termina cuando pulse ESC. e) Escriba el programa en Visual C++ (modo consola) f) Compile (Ctrl + F7) -> Build (F7) -> Execute program (Ctrl + F5)
Autor: Ing. Javier Barriga Hoyle ********************************************************************************/
Ing. Javier Barriga Hoyle 93 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM #include <windows.h> #include <stdio.h> #include <conio.h> #include "BymWin.h" // Librera usada por la tarjeta LPT V2.0
int Base = 0x378; // Direccin del puerto paralelo
int i, Fin, flag_int; unsigned char car, dato_adc; float voltios;
void main (void) // Inicia programa principal { inicio_tarjeta(); // Inicializa Tarjeta de interfase LPT V2.0 Fin=0; while(!Fin) { xout(0x6C, 0x00); // Inicia conversin while (flag_int != 0x40) // INTR = 0? o termin conversin? flag_int = _inp(Base+1)&0x40; /* Aqu no se usa xin, porque la lnea IRQ7 va directamente al puerto 379h */ dato_adc = xin(0x6C); // Termin conversin, leo dato del ADC
xout(0x5C, dato_adc); // Enva dato_adc al DAC
voltios = ((float)dato_adc*5)/255; // Convierte a flotante /* Muestra en pantalla en formato decimal el dato convertido */ printf("Valor ADC = %0.4f voltios\n",voltios); // 4 decimales if(kbhit()) // Pulso tecla? { car=getch(); // SI, leer tecla if(car == 27) Fin=1; // Si es ESC, salir del programa } Sleep(500); // Retardo de 500 ms } }
Ing. Javier Barriga Hoyle 94 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Apndice A. DRIVER L293D
El circuito L293D es un circuito lineal, su aplicacin principal es el funcionamiento para motores a pasos y de corriente continua, tiene la caracterstica de que mediante entradas digitales, pueda activar o desactivar el motor que se tiene conectado a la salida, la configuracin de este es la siguiente.
Figura A.1 Circuito Integrado L293D y su diagrama simplificado.
Este circuito incluye cuatro canales de salida capaces de suministrar hasta 600 mA por canal (1.2 A de pico). Est diseado para atacar cargas inductivas (caso de un motor PAP o CC), dispone de diodos de proteccin en las salidas y puede operar en aplicaciones de conmutacin (Ej. PWM) a frecuencias de hasta 5 KHz. Las patillas centrales 4, 5, 12, y 13 (GND), estn agrupados en el centro del encapsulado con objeto de facilitar la conexin de disipadores de calor (disipa hasta 5 W con estas patillas a 80 C). Sus caractersticas son: tensin de alimentacin de los canales de salida (Vs) hasta 36 V; Tensin de alimentacin de la lgica TTL (Vss) hasta 36 V; tensin de las entradas (Vi) hasta 7 V; tensin de las entradas de Enable (Ven) hasta 7 V. A continuacin se muestra la disposicin interna y la tabla de funcionamiento.
V S V S V S V S 2 1 7 4, 5, 12, 13 6 14 15 9 10 16 11 3 8 IN1 IN2 E1 IN3 IN4 E2 OUT2 OUT4 OUT1 OUT3 VS VSS L293D GND
Figura A.2 Diagrama de interno del driver L293D.
Tabla de funcionamiento del L293D Enable Entrada Salida L X Z H L L H H H
Ing. Javier Barriga Hoyle 95 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Apndice B. TIMER 8253 de la PC
Este temporizador aparece en la computadora personal decodificado en los puertos de E/S 40h 43h para realizar las siguientes funciones: Generar una interrupcin bsica de temporizacin que ocurre aproximadamente a 18.2 Hz. Refrescar el sistema de memoria DRAM (cada 15 S). Proporcionar una fuente de temporizacin a la bocina interna y otros dispositivos. El temporizador en la computadora personal es un 8253, en lugar de un 8254. Todos los contadores van conectados a un reloj que oscila a una frecuencia de 1.193.180 ciclos por segundo (casi 1,2 MHz). El parlante se controla con la salida OUT del Canal 2 y con los dos primeros bits del PortB del PPI (PB1 y PB0) ubicado en la direccin 62h del puerto de E/S. Es decir, para que el parlante suene el bit PB0 que est conectado al GATE, debe estar en 1, as mismo, el bit PB1 que est conectado a la compuerta AND, debe estar en 1. Cuando este canal 2 se emplea slo para temporizar, el bit PB1 debe estar en 0 para evitar que el parlante suene y el bit PB0 debe estar en 1 para habilitarlo.
CLK GATE OUT CANAL 0 CLK GATE OUT CANAL 1 CLK GATE OUT CANAL 2 VCC R PB0 PB1 PPI VCC IRQ0 - Vector 8 Refresco de Memoria DRAM 1193180 Hz
Figura B.1 TIMER 8253 dentro de la computadora personal.
Ing. Javier Barriga Hoyle 96 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Apndice C. MODULACION POR ANCHO DE PULSOS (PWM)
Una manera de obtener una corriente continua cuyo valor medio se pueda variar es modular el ancho o la frecuencia de una seal pulsatoria de onda cuadrada que vare entre 0 V. y un valor mximo de tensin V MAX . Estos circuitos reciben el nombre de Modulador de Pulsos (PWM), si lo que se vara es el tiempo de duracin de pulso positivo, y Modulador de Frecuencia (PFM), si lo que se vara es el perodo total de la seal. Con cualquiera de estos dos sistemas se obtiene una seal cuadrada, cuyo valor medio es fcilmente variable, seal con la que se puede regular la velocidad de un motor DC. Nosotros veremos en esta aplicacin PWM. En una onda cuadrada se vara el ancho del pulso positivo, manteniendo constante la frecuencia, ya que de esta manera el valor medio de la onda resultante es variable dependiendo de la duracin del pulso positivo de la misma. La modulacin de anchura de pulsos (PWM) se consigue con circuitos electrnicos, de una de estas formas: Generando una seal triangular y comparndola con una tensin continua de referencia (variable a voluntad), de manera que en la salida se obtiene una onda cuadrada con regulacin del ancho del pulso positivo. Mediante un circuito astable que controla el disparo de un monoestable, para obtener en la salida una onda cuadrada de pulso positivo variable. Mediante software, por programa para P o C, obteniendo en el puerto de salida una seal cuadrada donde se puede variar el tiempo de pulso positivo. Empleando dos canales (o contadores) del TIMER 82C54 en interfaz con el P, Bus ISA o con el puerto paralelo de la PC.
C.1 Generacin de PWM con TIMER La tarjeta de interfase LPT V2.0 para puerto paralelo tiene incluido un TIMER con su oscilador de 8 MHz, la siguiente figura muestra como se debe conectar las salidas de los canales 1 y 2 hacia el Flip Flop RS 74LS279. 82C54 OUT0 OUT1 OUT2 CLK2 GATE2 CLK1 GATE1 CLK0 GATE0 D0 - D7 OSC 8 MHz PWM 5 6 7 74LS279 +5v 10K
Figura C.1 Diagrama de conexin para obtener una seal PWM.
Ing. Javier Barriga Hoyle 97 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Su funcionamiento es como sigue:
Se configura al contador 1 (canal 1) en modo 2 (rate generator), el cual genera un tren de pulsos continuos. Por ejemplo, si el contador es seteado con la cuenta de 1000, su salida estar en 1 lgico durante 999 pulsos y en 0 lgico durante 1 pulso. Se configura al contador 2 (canal 2) en modo 5 (hardware triggered strobe), en el cual la salida del contador 1 (OUT1) se conecta a la entrada GATE 2, para producir los disparos y activar al contador 2 (monoestable). El software cambia el valor almacenado en el contador 2, cada vez que se pulsa una tecla (para aumentar o disminuir el periodo). Como este nmero es cambiado, el tiempo entre la salida del contador 1 y la salida del contador 2 tambin cambiar. La salida OUT1 tambin se conecta a la entrada SETS, y la salida OUT2 se conecta a la entrada RESET del FLIP FLOP RS (74LS279), en donde su salida (Q) del FLIP FLOP es una seal PWM. Considerar que el esquema debe trabajar teniendo en cuenta que el nmero almacenado en el contador 2 debe ser un mnimo de 2 unidades menor que el nmero almacenado en el contador 1. Por ejemplo, si el contador 1 es programado con el nmero 1000, el contador 2 puede variar entre 1 y 998. Esto asegura que las seales SET y RESET enviadas al FLIP FLOP no se traslapen. La siguiente figura, muestra las seales que se producen en las salidas de los contadores 1 y 2 del TIMER y la salida del F/F. En este ejemplo, al contador 1 se le ha enviado el valor de 65535 (FFFFh), y el contador 2 vara a intervalos de 4095 (FFFh).
CONTADOR 1 CONTADOR 2 (WORD = 32775) CONTADOR 1 CONTADOR 2 SALIDA F/ F (WORD = 57345) SALIDA F/ F (WORD = 4110) CONTADOR 1 CONTADOR 2 SALIDA F/ F
Figura C.2 Formas de onda que se genera en las salidas de cada contador o canal.
Ing. Javier Barriga Hoyle 98 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM C.2 Driver L293D Como controlador de motor de corriente continua (motor de CC), se ha empleado el circuito integrado L293D (Apndice A). La siguiente figura muestra como conectar el motor con el CI L293D. A continuacin, se muestra el diagrama de cmo debe conectarse el motor DC al controlador L293D. El programa G5_E6.CPP genera una seal PWM para el control de un motor DC.
V S V S V S V S 2 1 7 4, 5, 12, 13 6 14 15 9 10 16 11 3 8 IN1 = PWM E1 = +5 V IN3 = Sentido de giro E2 = +5 V OUT1 OUT3 Vs = +5V o +12V Vss = +5V o +12 V L293D GND MOTOR DC +
Figura C.3 Ejemplo de conexin del driver L293D a un motor DC.
Ing. Javier Barriga Hoyle 99 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Apndice D. INTERRUPCIONES
D.1 Conceptos Una interrupcin se genera cuando se quiere que la CPU deje de ejecutar el proceso en curso y ejecute una funcin especfica de quien produce la interrupcin. Cuando se ejecuta esta funcin especfica decimos que la CPU est atendiendo la interrupcin. Podemos realizar una clasificacin de las interrupciones, atendiendo a la fuente que las produce. Interrupcin software, se produce cuando un usuario solicita una llamada del sistema. Se tratan de procedimientos a los que llama un programa para la ejecucin de tareas ligadas, en su mayora, al hardware de la computadora, tales como la adquisicin de una tecla, enviar informacin a la pantalla, transmisin y recepcin de datos va un canal de comunicacin con el exterior, etc. En realidad las interrupciones por software no interrumpen nada, ya que cumplen una funcin muy similar a una llamada a subrutina (por ejemplo, CALL en el caso de una PC). Interrupciones hardware, son causadas cuando un dispositivo hardware requiere la atencin de la CPU para que se ejecute su manejador (rutina de interrupcin). Internas: Son generadas dentro del CPU. Por ejemplo, un desbordamiento en la divisin, un cdigo de operacin no valido (illegal opcode), etc. Externas: Son interrupciones generadas externamente al CPU, pudiendo ser generadas por dispositivos dentro de la placa del sistema (mainboard) o por una unidad de E/S de algn perifrico fuera de la placa del sistema. Por ejemplo: El teclado, Un temporizador, Un DMA al finalizar la transferencia, etc. Estas se clasifican en: Enmascarables: Cuando las interrupciones pueden ser activadas (permitidas) o desactivadas (inhibidas) por programa (software). No enmascarables: Cuando las interrupciones no pueden ser desactivadas (inhibidas) por programa (software).
D.2 Interrupciones en la PC La CPU 80x86 de una PC, posee tres seales para lo que son interrupciones externas (las cuales se mantienen aun por compatibilidad en PCS actuales basados en procesadores Pentium).
CPU INTR NMI RESET INTA
Figura D.1 Lneas de interrupcin. Donde: Interrupt request (INTR): Solicitud de interrupcin, est disponible para ser utilizada por dispositivos perifricos externos que necesiten ser atendidos por el CPU, el procesador 80x86 muestrea esta seal cada vez que va a iniciar una instruccin, si detecta que tiene un nivel lgico 1, reconoce la interrupcin y salta a la rutina de servicio correspondiente para atender dicho requerimiento. Esta lnea de interrupcin es enmascarable, puede ser habilitada deshabilitada con la bandera de interrupcin (IF) del PSW. (CLI en Assembler y disable() en C++ hace que IF = 0 con lo que s deshabilita INTR, STI en Assembler y enable() en C++ hace que IF = 1 con lo que habilita INTR permitiendo as las interrupciones por esta lnea).
Ing. Javier Barriga Hoyle 100 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Nonmaskable interrupt request (NMI): Esta disponible para ser utilizada por perifricos externos que necesiten ser atendidos por el CPU, esta seal no es enmascarable, la peticin de interrupcin en este caso es capturada dentro del CPU en el flanco de subida (transicin de 0 a 1 de NMI) de la seal NMI y se salta a la rutina de servicio cuando se completa la instruccin en curso. Esta es utilizada frecuentemente para la deteccin de errores de paridad y otras fallas mayores del sistema, tales como la falta de energa. System reset (RESET): Es utilizada para generar una inicializacin completa del procesador 80x86, al pasar a nivel 1, se interrumpe la ejecucin de todo y s inicializan los registros internos del procesador y cuando vuelve a 0 la seal, el control es transferido al inicio de la rutina de servicio de RESET, esta rutina inicializa el resto de los recursos del sistema, como por ejemplo los puertos I/O, las banderas de interrupcin, los datos iniciales en la memoria, inicia una serie de tests, asegurando el correcto inicio de todo el sistema. Siempre que el microprocesador es restaurado, inicia la ejecucin de instrucciones en la localidad de memoria FFFF0h (para el 8086) e inhabilita interrupciones futuras restaurando el bit de bandera IF. INTA: La seal de reconocimiento de interrupcin, es una respuesta a la terminal de entrada INTR. La terminal INTA es normalmente empleada para ubicar el nmero de vector de interrupcin en el bus de datos, en respuesta a la solicitud de interrupcin.
INTA INT DATOS 80x86 INT INTA SP/ EN DATOS INT INTA DATOS BUS DE DATOS IRQ0 IRQ1 IRQ3 IRQ4 IRQ5 IRQ6 IRQ7 IRQ8 IRQ9 IRQ10 IRQ11 IRQ12 IRQ13 IRQ14 IRQ15 SP/ EN 1 0 CAS 0 CAS 1 CAS 2 8259A 8259A (master) (esclavo)
Figura D.2 Diagrama de conexin de la CPU y controladores de interrupciones en la PC.
Impresora PIC IRQ7 CPU INT INTA 00000H Vector 0 Vector 1 Vector 15 00004H Programa de la RSI MEMORIA JMP printer FFFFFH
Figura D.3 Secuencia de eventos que se generan debido a una interrupcin.
Las lneas de interrupcin (IRQx), estn conectadas a los perifricos tal como muestra la tabla siguiente. Adems se indica el nivel de prioridades (IRQ0 es la de mayor prioridad) PC
Ing. Javier Barriga Hoyle 101 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM
Lnea de interrupcin Dispositivo conectado * = Puede estar ubicado en otra lnea de IRQ (o podra no estar presente) Nmero de vector IRQ 0 Temporizador (TIMER, contador 0) 08h IRQ 1 Teclado (KEYBOARD) 09h IRQ 2 Cascada con el PIC esclavo 0Ah IRQ 3 Puerto de comunicaciones serial #2 (COM2) 0Bh IRQ 4 Puerto de comunicaciones serial #1 (COM1) 0Ch IRQ 5 *Tarjeta de sonido (SOUND BLASTER) 0Dh IRQ 6 Controlador estndar de disquetes (FDD) 0Eh IRQ 7 Puerto paralelo (LPT1, tpicamente utilizado para colocar una impresora) 0Fh IRQ 8 Reloj de tiempo real/Sistema CMOS (REAL TIME CLOCK/CMOS) 70h IRQ 9 (libre) 71h IRQ 10 Controlador de bus serie universal (USB) 72h IRQ 11 (libre) 73h IRQ 12 *MODEM 74h IRQ 13 Procesador de datos numricos (FPU) 75h IRQ 14 Controlador primario IDE 76h IRQ 15 *Controlador secundario IDE 77h
Tabla D.1 Asignacin de interrupciones en la PC
D.3 Controlador de interrupciones programable PIC 8259A
Figura D.4. Diagramas del Circuito Integrado 82C59A.
El 82C59 es un IC, diseado para manejar interrupciones, sus principales caractersticas son: Puede manejar hasta 8 interrupciones. Puede asignar prioridades a cada interrupcin. Programable por software. Permite su conexin con otros PICs (hasta 8 PICs esclavos) de modo que puede llegar a manejar hasta 64 interrupciones. Tiene la habilidad de aceptar seales de interrupcin por flancos (edge triggered) o por nivel (level sensitive). Tiene la capacidad de indicar al CPU la direccin de la rutina asociada al dispositivo que genera la interrupcin. Tiene capacidad de habilitacin o inhabilitacin individual de cada entrada de interrupcin.
Ing. Javier Barriga Hoyle 102 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM D.4 Vectores de interrupcin Un vector de interrupcin es un conjunto de dos valores, almacenados en 4 bytes del espacio de memoria, que representan la direccin de memoria donde se encuentra almacenada la rutina de servicio de interrupcin asociada a una interrupcin. En los primeros dos bytes de un vector, se encuentra el desplazamiento, y en los dos bytes siguientes se encuentra el segmento de dicha direccin.
CS_255 IP_255 VECTOR 255 0000 : 03FE h 0000 : 03FC h CS_254 IP_254 VECTOR 254 0000 : 03FA h 0000 : 03F8 h CS_1 IP_1 VECTOR 1 0000 : 0006 h 0000 : 0004 h CS_0 IP_0 VECTOR 0 0000 : 0002 h 0000 : 0000 h Segmento : Offset
Tabla D.2 Tabla de vectores de interrupcin en la PC.
Despus de que se genera una interrupcin, el CPU debe proceder a ejecutar la rutina de servicio que atender dicha interrupcin, para esto se dispone de una tabla de vectores de interrupcin. Esta tabla en el caso de la PC es capaz de soportar hasta 256 interrupciones, cuando se produce una interrupcin, se necesita el segmento (CS) y el desplazamiento (IP) de la primera instruccin de la rutina de servicio, estos datos son almacenados en la tabla de vectores de interrupcin: Al producirse la interrupcin, el CPU determina el nmero del vector asociado a la interrupcin y salta a la direccin contenida dentro del vector, observe que cada vector utiliza 4 bytes (tabla D.2).
D.5 Instalacin de vectores de interrupcin Para leer e instalar un vector de interrupcin de una manera cmoda y prctica se hace uso de la INT 21h del DOS, tal como muestra la siguiente tabla.
14.1 25H 14.2 ESTABLECER EL VECTOR Entrada AH = 25h AL = nmero del vector de interrupcin. DS:DX = Direccin del nuevo procedimiento para el vector de interrupcin.
Notas Antes de cambiar el vector de interrupcin, se sugiere que el vector de interrupcin actual sea primero guardado utilizando la funcin 35H del DOS. Esto permite un vnculo para que el vector original pueda ser posteriormente restaurado. 35H LEER EL VECTOR DE INTERRUPCION Entrada AH = 35h AL = nmero del vector de interrupcin. Salida ES:BX = Direccin archivada en el vector. Notas Esta funcin del DOS es usada con la funcin 25H para instalar/retirar los identificadores de los interrupciones.
Ing. Javier Barriga Hoyle 103 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Ejemplo: Leer el valor almacenado en el vector 8 de la IRQ0, guardarlo e instalar la RTI UPC en el vector.
Lenguaje Assembler Lenguaje C ; se lee el vector y se guarda MOV AH, 35H MOV AL, 08H ; num. vector 08h INT 21H MOV oldvec8_off, BX MOV oldvec8_seg, ES ; se instala la rutina de interrupcin UPC MOV DX, OFFSET UPC MOV AX, SEG UPC PUSH DS MOV DS, AX MOV AH, 25H MOV AL, 08H ; instala vector INT 21H POP DS /* se lee vector y se guarda */
oldvec8 = getvect (0x08);
/* se instala la rutina de interrupcin UPC */
setvect (0x08, UPC);
D.6 Mscara de interrupcin (IMR): Este registro de 8 bits, nos permite habilitar (0) /deshabilitar (1), cada una de las interrupciones asociadas a los pines IRQ.
Ejemplo: Escriba las instrucciones para habilitar la interrupcin del COM1 (IRQ4).
void main() { unsigned char oldimr, newimr; oldimr = inportb(0x21); // lee mascara IMR del PIC newimr = oldimr & 0xEF; // habilita la IRQ4 (1110 1111b) outportb(0x21, newimr); // se enva al PIC la nueva IMR }
Consideraciones previas: Al implementar su RSI, deber tener en cuenta lo siguiente: La instalacin de vectores de interrupcin y la habilitacin de interrupciones es hecha en el programa principal, no en la rutina de servicio. La rutina no deber ser demasiado extensa. Esto implica la no-implementacin de bucles en el interior de la RTI. Al terminar el programa, deber enviar el EOI: outportb(0x20,0x20); Tngase en cuenta los niveles de prioridad.
Ing. Javier Barriga Hoyle 104 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM D.7 Instalacin de rutinas de servicio de interrupcin (RSI) Es la rutina (o procedimiento) asociada a una interrupcin, y ser ejecutada en caso se encuentre habilitada. Su estructura es similar a un procedimiento convencional, con la salvedad que la instruccin de retorno es IRET. Dicha rutina, al estar en memoria, tiene un offset (desplazamiento), y un segmento. Ambos valores debern ser almacenados en la tabla de vectores de interrupcin (instalacin de los vectores de interrupcin).
Pasos a seguir para la instalacin / desinstalacin de la RSI: (Suponga la IRQ1 y vector 9h) Programa principal: Instalacin: a) Deshabilitar interrupciones. b) Leer y Guardar IMR. c) Modificar el IMR para que permita las interrupciones de la lnea IRQ1. d) Leer y Guardar el vector 09H. e) Colocar el nuevo vector 09H para que apunte a nuestra rutina de servicio. f) Habilitar interrupciones. g) Esperar hasta que se indique que se debe terminar la ejecucin del programa (bucle infinito) Desinstalacin: (para salir del programa) h) Deshabilitar interrupciones. i) Restaurar el vector 09H. j) Restaurar el IMR. k) Habilitar interrupciones. l) Terminar el programa. La rutina de servicio (RSI): a) Guardar todos los registros a utilizar. b) Rutina de servicio (programa a realizar). c) Restaurar todos los registros utilizados. d) Enviar al PIC el EOI (End of interrupt), enviando un 20H a la direccin 20H del espacio de E/S.
NOTA: Para ejecutar los programas que hagan uso de interrupciones, es necesario que se utilice el Sistema Operativo Windows 98, ya que los dems (Win2000 y WinXP) no permiten generar interrupciones, an usando el UserPort.
Ing. Javier Barriga Hoyle 105 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM Apndice E. ESQUEMATICOS DE ALGUNOS CIRCUITOS
D 6 U2 ULN2003 1 2 3 4 5 6 7 16 15 14 13 12 11 10 8 9 I0 I1 I2 I3 I4 I5 I6 S0 S1 S2 S3 S4 S5 S6 GND X 1K 1K VCC D0 Q0 VCC D3 U1 74LS48 7 1 2 6 4 5 3 13 12 11 10 9 15 14 1 2 4 8 BI/RBO RBI LT A B C D E F G 1K 47 a b c d e f g Q3 D5 D1 D 5 1K DIS_2 VCC D 4 VCC R1 DIS_0 VCC D4 D 7 Q1 VCC DIS_3 D7 VCC D0 D2 D3 D6 D2 Q2 DIS_1 D1 J1 PORT_A PPI 1 2 3 4 5 6 7 8 9 10 NOTA: LOS DISPLAYS SON DE ANODO COMUN
Ing. Javier Barriga Hoyle 106 sol_bym@viabcp.com Soluciones Electrnicas Integradas BYM E.4 Displays (cuatro) multiplexados en HEXADECIMAL
D0 Q1 DIS_2 1K Q2 VCC D4 D 4 1K DIS_1 D7 D2 Q0 D2 Q3 DIS_0 47 VCC a b c d e f g 1K NOTA: LOS DISPLAYS SON DE ANODO COMUN D1 D3 D6 VCC 1K J1 PORT_A PPI 1 2 3 4 5 6 7 8 9 10 DIS_3 U1 MC14495P 5 6 9 10 11 7 12 13 14 15 1 2 3 4 A B C D I LE a b c d e f g H+I VCC D1 D5 VCC D0 D 6 D3 R1 U2 ULN2003 1 2 3 4 5 6 7 16 15 14 13 12 11 10 8 9 I0 I1 I2 I3 I4 I5 I6 S0 S1 S2 S3 S4 S5 S6 GND X D 5 VCC D 7
E.5 Displays (ocho) multiplexados en salida binaria codificada en software
DIS4 R1 1K VCC Q1 D5 DIS6 47 Q3 Q2 1K D 1 1K D7 Q4 J2 PORT_B PPI 1 2 3 4 5 6 7 8 9 10 D2 DIS5 Q6 NOTA: LOS DISPLAYS SON DE ANODO COMUN VCC D1 VCC D5 D6 Q0 D 4 DIS0 DIS7 1K VCC VCC D6 D4 D3 D4 D 2 D 3 1K D 0 D 5 J1 PORT_A PPI 1 2 3 4 5 6 7 8 9 10 DIS3 DIS2 D3 VCC D 6 VCC a b c d e f g D0 1K VCC D2 1K 1K Q5 VCC U2 ULN2003 1 2 3 4 5 6 7 16 15 14 13 12 11 10 8 9 I0 I1 I2 I3 I4 I5 I6 S0 S1 S2 S3 S4 S5 S6 GND X VCC D 7 DIS1 D0 Q7 VCC D1
E.6 Control de un motor de pasos con el PORTA del PPI
Los Microprocesadores Intel: Arquitectura, programacin e interfaz de los procesadores 8086/8088, 80186/80188, 80286, 80386, 80486, Pentium, Pentium Pro y Pentium II. Barry B. Brey Prentice Hall. ISBN: 970-17-0424-X
Prcticas con Microcontroladores de 8 bits: Aplicaciones industriales Javier Martnez Prez Mariano Barrn Ruiz McGraw Hill ISBN: 84-481-0101-4
Microcontroladores PIC: Diseo prctico de aplicaciones Jos Ma Angulo Usategui Ignacio Angulo Martnez McGraw Hill ISBN: 84-841-2496-0
Amplificadores Operacionales y Circuitos Integrados Lineales Robert F. Coughlin Frederick F. Driscoll Prentice Hall ISBN: 968-880-284-0