11
. . . . . . . . . . . . . . . . . . . . Práctica 1 Programación de la E/S del PC. Control de un display de 7 segmentos desde el puerto paralelo. Laboratorio de Informática Industrial I Página Web: http://atc1.aut.uah.es/~infind e - mail: [email protected] Despacho: E - 232 Departamento de Automática

Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Embed Size (px)

DESCRIPTION

Practica en DEv C

Citation preview

Page 1: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

. . . . . . . . .

.

. . . . . .. . . .

Práctica 1

Programación de la E/S del PC.

Control de un display de 7 segmentos desde el puerto paralelo.

Laboratorio de Informática Industrial I

Página Web: http://atc1.aut.uah.es/~infind

e-mail: [email protected]

Despacho: E-232

Departamento de Automática

Page 2: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Laboratorio de Informática Industrial II 2 Dpto Automática

Acceso directo al Hardware en

Windows 2000/XP

Objetivo

Esta práctica tiene como doble objetivo conocer una de las posibilidades de acceso a dispositivos electrónicos básicos desde el PC, y por otro lado retomar el desarrollo de programas en C/C++ bajo Windows. Con esto se persigue presentar una introducción al control de dispositivos electrónicos sencillos a través del ordenador personal.

Más concretamente se deberá realizar el control de un display de 7 segmentos desde un programa de Windows a través del puerto paralelo del PC.

Descripción del Display El display de 7 segmentos es un elemento usado ampliamente en los circuitos

electrónicos para mostrar información numérica. Está constituido internamente por 8 diodos LED que forman el dígito, más un LED que hace la función de punto decimal.

El aspecto del display podría ser el siguiente:

Las patillas no tienen por qué coincidir de un fabricante a otro por lo que es fundamental

identificarlas correctamente antes de hacer cualquier montaje.

En el caso de tratarse de un display en el que los LEDs están configurados en modo de ánodo común, el esquema eléctrico interno es el siguiente:

Vcc

a b c d e f g pd

a

b

c

d

e

f

g

pd

Vcc

b

a

c

d e

f

Vcc

g

pd

Co

py

rig

ht

©20

06 D

avid

Ju

rad

o G

on

zále

z. S

e co

nce

de

per

mis

o p

ara

co

pia

r, d

istr

ibu

ir y

/o

mo

dif

ica

r es

te d

ocu

men

to b

ajo

lo

s

térm

ino

s d

e la

Lic

enci

a d

e D

ocu

men

taci

ón

Lib

re d

e G

NU

, Ver

sió

n 1

.2 o

cu

alq

uie

r o

tra

ver

sió

n p

ost

erio

r p

ub

lica

da

po

r la

Fre

e

So

ftw

are

Fo

un

da

tio

n; s

in S

ecci

on

es I

nv

ari

an

tes

ni

Tex

tos

de

Cu

bie

rta

Del

an

tera

ni

Tex

tos

de

Cu

bie

rta

Tra

sera

. U

na

cop

ia d

e la

lice

nci

a e

stá

in

clu

ida

en

la

secc

ión

tit

ula

da

GN

U F

ree

Doc

um

enta

tion

Lic

ense

.

Page 3: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Práctica 2 3 Acceso a dispositivos

Para excitarlos es necesario aplicar una tensión inferior a Vcc en los cátodos correspondientes a cada segmento.

La tensión V típica está comprendida entre 1 y 1,5 V, por tanto, si hacemos Vcc = 5V, para que luzca un LED, tendremos que aplicarle entre 3,5V y 4V a su cátodo. Para que no luzcan, habría que aplicarles Vcc, o bien dejarlos en alta impedancia.

Ya qua la intensidad de funcionamiento está comprendida entre 10mA y 15mA, la resistencia

que se acople en serie debe ser aproximadamente de 330 . Con esto podremos encender los LEDs llevando uno de los terminales de la resistencia a masa. La siguiente figura muestra el circuito necesario para que el display muestre el número 7:

Si el display fuera de cátodo común la excitación se realizaría usando lógica positiva y el circuito

quedaría:

La excitación de los LEDs la realizaremos directamente desde los terminales de datos del puerto paralelo del PC, en el que también están presentes varias líneas de masa. Lamentablemente no se puede obtener directamente la tensión Vcc de ninguna de las líneas del cable, lo que obliga a tener que usar la configuración del display en cátodo común si no contamos con fuente de alimentación externa. Como única medida de limitación de intensidad, usaremos 8 resistencias de 330Ω en serie con los LEDs tal como aparecen en las figuras.

Pines del puerto paralelo La siguiente figura muestra los pines del puerto paralelo. Los de datos corresponden al rango de

patillas 2 a 9.

Vcc

a b c d e f g pd

Vcc

330 330

330

Vcc

a b c d e f g pd

330

Vcc Vcc

Page 4: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Laboratorio de Informática Industrial II 4 Dpto Automática

Para mayor comodidad contaremos con un cable plano extensor del puerto que podremos conectar directamente a una placa entrenadora de circuitos electrónicos a través de un conector de inserción de zócalo DIP. La topología del cable es la siguiente:

Vista de la base del interfaz paralelo centronics desde el conector hembra del PC.

25 24 23 22 21 20 19 18 17 16 15 14

13 12 11 10 9 8 7 6 5 4 3 2 1

D7 D6 D5 D4 D3 D2 D1 D0

S7 S6 S5 S4 S3

C3 C2 C1 C0

Byte de datos

Byte de control

Byte de estado

14 15 16 17 18 19 20 21 22 23 24 25

1 2 3 4 5 6 7 8 9 10 11 12 13

D0 D1 D2 D3 D4 D5 D6 D7

14 15 16 17 18 19 20 21 22 23 24 25

1 2 3 4 5 6 7 8 9 10 11 12 13

Hilo

Rojo

Masa

Datos

Byte de datos

Vista de la base del interfaz paralelo centronics desde el conector macho del cable.

Page 5: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Práctica 2 5 Acceso a dispositivos

Desarrollo de programas Windows 2000/XP en C/C++

Para desarrollar esta práctica es necesaria la configuración de un entorno de trabajo basado en el lenguaje C/C++ del que también nos serviremos para poder compilar algunos de los programas que se vayan a realizar a lo largo del curso.

Compiladores de C/C++ para Windows Cuando se habla de un compilador de C++, se asume que también es capaz de compilar

programas escritos en C puro, dada su compatibilidad hacia atrás. Podemos considerar al lenguaje C++ como un súper conjunto que engloba la práctica totalidad del lenguaje C.

En Windows existe una gran variedad de compiladores de C++, de los que destacaremos los basados en el compilador GNU llamado gcc. Este compilador surge del proyecto GNU (acrónimo recursivo de "GNU's Not Unix") con el objetivo de tener un compilador con el que poder desarrollar un Sistema Operativo estilo UNIX de libre distribución y fuentes abiertas, y otras aplicaciones asociadas. La denominación gcc se debía al acrónimo GNU C Compiler, pero debido a la incorporación de una numerosa cantidad de herramientas auxiliares, en las que se incluye la posibilidad de desarrollo cruzado, y en diferentes lenguajes, el significado cambia al de GNU Compiler Collection. Se trata de un compilador optimizador multiplataforma de última generación que soporta ampliamente el estándar ANSI-ISO, e incorpora extensiones propias. gcc ha sido portado a la práctica totalidad de sistemas de desarrollo modernos, y además a algunos antiguos, como es el caso de la adaptación para el microcontrolador 68HC11 de Motorola.

Existen principalmente dos conversiones a Windows de este compilador: Gygwin y MinGW.

Cygwin es una solución muy completa que incluye además un gran soporte de compatibilidad con POSIX en Windows. Incorpora casi todas las órdenes típicas de línea de comandos de un sistema UNIX, y además incluye varias bibliotecas de funciones portadas del proyecto GNU entre las que cabe destacar Glibc. Esto lo hacen idóneo como solución de desarrollo en aplicaciones portables entre sistemas operativos.

MinGW es una implementación minimalista del conjunto de herramientas GNU sobre plataforma Windows (Minimalist GNU for Windows). En un principio utilizaba la biblioteca de C de tiempo de ejecución de Microsoft, lo que entre otras cosas conseguía una gran integración con el Sistema Operativo. En la actualidad utiliza también las bibliotecas GNU estándar.

En esta primera práctica usaremos MinGW, que impone una escasa sobrecarga a los programas que genera debido a la alta integración con Windows.

Notas:

* Las siglas POSIX hacen referencia a una especificación de bibliotecas de programación,

comandos de Sistema Operativo (de línea de órdenes), comportamiento del sistema,... cuyo

objetivo es conseguir la uniformidad entre diferentes Sistemas Operativos. Ciñéndonos a

esta especificación nuestros desarrollos serán más portables.

El Sistema Operativo Windows en su implementación actual casi no ofrece soporte POSIX.

Microsoft tan solo ha portado una pequeña parte de la biblioteca de funciones POSIX para

el trabajo con sus compiladores de C/C++, aunque recomienda que no sea usada en la

medida de lo posible, y se empleen funciones nativas Win32 ó Win64 en su lugar.

* Como es sabido, además de gcc existe una gran cantidad de compiladores comerciales de

C++ para Windows como Visual C++. Sin embargo su uso no es libre.

Entornos de Desarrollo Integrado Los compiladores de C++ toman el código fuente de un archivo de texto plano. Cualquier

editor de texto ASCII-ANSI-UTF8 es válido para escribir los programas. Por otra parte existen los llamados Entornos de Desarrollo Integrados (IDE), que nos dan facilidades a la hora de mantener un proyecto de programación, como son el coloreado del código, ayuda en línea, administración de recursos, depuración, búsqueda avanzada de código, interfaz con el compilador, etc.

Page 6: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Laboratorio de Informática Industrial II 6 Dpto Automática

Para esta práctica vamos a ver un sencillo IDE llamado Dev-C++ compuesto principalmente por editor de textos, compilador, y depurador que nos permitirá compilar programas de una forma rápida y cómoda.

El editor presenta coloreado de la sintaxis y funciones de autocompletar entre otras.

La versión actual del compilador es gcc 3.2 para x86 al que se le ha incorporado una gran cantidad de funciones de biblioteca. Su objetivo último es traducir programas escritos en C/C++ a código máquina ejecutable.

La depuración que consiste en eliminar fallos de software se realiza mediante el programa gdb acrónimo de GNU debugger, que es el más usado en entornos GNU. Se trata de un depurador avanzado, que toma un programa ejecutable y ofrece un amplio abanico de posibilidades para controlar y supervisar su ejecución. Entre las posibilidades que ofrece, se encuentra la de depuración a nivel de código fuente, con la que se nos permite tener sesiones de depuración en las que contamos con el mismo código que utilizamos en la elaboración del programa. Esta es una característica básica de los depuradores modernos.

La interacción con gcc y gdb que se realizara tradicionalmente con la línea de comandos queda oculta por Dev-C++, con el que interactuamos a través de una cómoda interfaz gráfica.

Acceso al puerto paralelo desde un programa en Windows

Los microprocesadores x86 que incluyen los PCs permiten acceder a dispositivos de dos maneras distintas: como si se trataran de simples posiciones de memoria, o como posiciones especiales de Entrada/Salida (I/O). Esta última se diferencia de la primera en que en el momento de acceder al dispositivo, el microprocesador activa una línea adicional que indica que la dirección puesta en su bus de direcciones va destinada a un dispositivo, y no a la RAM. El acceso a los dispositivos de esta forma requiere instrucciones en ensamblador específicas, no codificables directamente en lenguaje C. Las direcciones de los puertos se expresan con palabras de 16 bits. Esta forma de direccionamiento poco a poco va quedando en desuso. Se utiliza mayormente para mantener la compatibilidad con periféricos antiguos.

En el proceso de arranque del PC, el programa almacenado en la ROM BIOS copia las direcciones I/O de los 3 primeros puertos paralelos que se detecten en las posiciones de memoria 0x00000408 y sucesivas. Windows 2000 por lo general no permite leer de posiciones de memoria absolutas que no hayan sido reservadas previamente, por lo que no es posible consultar directamente dichas direcciones. Para poder conocer exactamente la posición sería preciso consultarla mediante llamadas al API (Application Programming Interface) Win32, aunque por simplicidad podemos verla directamente en las Propiedades del puerto de Impresora dentro del Administrador de dispositivos del sistema.

Normalmente el único puerto paralelo que se incluye se sitúa en la posición 0x0378. Cada

entrada de puerto paralelo estándar consta de 3 bytes consecutivos: Datos, Estado, y Control, de los que sólo nos interesa el byte de Datos. El sistema tampoco nos dará acceso al puerto directamente por lo que es necesario hacer llamadas directamente al driver del puerto paralelo, o bien utilizar alguna utilidad que pase por alto esta limitación. La documentación para acceder directamente al driver está en Kit de Desarrollo de

Page 7: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Práctica 2 7 Acceso a dispositivos

Drivers (DDK) de Windows, que es complicado de usar. Sin embargo tenemos otra opción que nos brindan algunos programas de uso libre basadoas en eliminar la protección de Windows haciendo uso de ciertas llamadas al sistema no documentadas. Tal es el caso de WinIO que permite que una aplicación pueda acceder selectivamente a los recursos que necesite.

Nota: Aunque WinIO soluciona un problema común para el programador de bajo nivel en Windows, se desaconseja su uso en aplicaciones comerciales ya que entraña cierto peligro de corrupción de datos para otras aplicaciones que intenten acceder a los mismos recursos. En tales casos sería necesario ceñirse a llamadas a la función DeviceIOControl de acceso a dispositivos en Win32.

Puesta a punto de un puesto de trabajo

Los pasos necesarios para poder programar nuestros programas en C son los siguientes:

Instalar Dev-C++ en el directorio raíz del disco duro C. El programa debe quedar en

C:\Dev-C++ o en cualquier ruta que no incluya espacios intermedios.

Para crear un nuevo proyecto, seleccionamos ArchivoNuevoProyecto en el menú principal.

Nos aparece un cuadro de diálogo en el que seleccionaremos proyecto de tipo consola al que damos un nombre identificativo.

Guardarlo dentro de una carpeta creada con igual nombre dentro de Mis documentos.

Se creará un archivo similar al siguiente al que habrá que comentar o eliminar la primera línea, que sólo tendría utilidad en la programación en C++.

//#include <iostream>

#include <stdlib.h>

int main(int argc, char *argv[])

system("PAUSE");

return 0;

Si podemos compilar el programa seleccionando EjecutarCompilar y ejecutar, es que todo está correctamente configurado. Lo único que hace este sencillo programa es llamar a la orden PAUSE del sistema. Si no se encontrara presente en el sistema, podríamos sustituir la línea por getchar().

Las aplicaciones tipo consola tienen una interfaz basada en texto, al estilo de los antiguos programas para MS-DOS. Este modo nos permite realizar programas que utilicen la entrada/salida estándar de C con funciones como printf y scanf, a la par que se crea una aplicación Windows nativa (posibilidad de hacer llamadas al API Win32 ó Win64).

Para poder usar WinIO copiaremos los archivos WinIo.sys, WINIO.VXD, WinIo.dll, y libwinio.a a la carpeta del proyecto. Además hay que indicarle al enlazador que use la biblioteca libwinio.a en la caja de diálogo Opciones de proyecto.

Page 8: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Laboratorio de Informática Industrial II 8 Dpto Automática

Introducir ahora el siguiente programa:

#include <windows.h>

#include <stdio.h>

#define WINIO_DLL

#include "winio.h"

int main()

DWORD dwPortVal;

DWORD dwMemVal;

BYTE bPortVal;

bool bResult;

HANDLE hPhysicalMemory;

PBYTE pbLinAddr;

// Llamar a InitializeWinIo para iniciar la biblioteca WinIo.

bResult = InitializeWinIo();

if (bResult)

// Bajo Windows NT/2000/XP, Después de llamar a InitializeWinIo,

// se puede llamar a _inp/_outp en lugar de usar GetPortVal/SetPortVal

//

// 0x378 es el puerto más habitual para impresoras

SetPortVal(0x378, 0x0f, 1); // Escribe 0x0f

GetPortVal(0x378, (DWORD*) &bPortVal, 1); // Verificar que se ha escrito

printf("En el puerto hay 0x%X.\n", (int) bPortVal);

Sleep(3000); // Esperar 3000 milisegundos

SetPortVal(0x378, 0xf0, 1); // Escribe 0xf0

GetPortVal(0x378, (DWORD*) &bPortVal, 1); // Verificar que se ha escrito

printf("En el puerto hay 0x%X.\n", (int) bPortVal);

getchar(); // Esperar a que se presione Enter

// Cuando se termine de usar WinIo, llamar a ShutdownWinIo

ShutdownWinIo();

else

printf("Error durante el inicio de WinIo.\n");

return 0;

Page 9: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Práctica 2 9 Acceso a dispositivos

Las llamadas a InitializeWinIo y ShutdownWinIo sirven respectivamente para iniciar y terminar el uso de la biblioteca WinIO. La Función GetPortVal obtiene el contenido del puerto especificado en su primer argumento copiándolo a la dirección que se le indique en su segundo argumento. El tercer argumento indica el número de bytes a copiar: 1, 2, ó 4. La función SetPortVal escribe datos en el puerto especificado. La función Sleep detiene la ejecución durante el número de milisegundos que se especifique.

Una vez compilado, el programa escribirá 0x0f y 0xf0 en el puerto paralelo, lo que nos sirve para comprobar que el circuito funciona correctamente. Las llamadas a GetPortVal no son necesarias en este programa y sólo figuran para comprobar que se ha establecido el dato como era de esperar.

Depuración en Dev-C++ Como ejemplo vamos a realizar una sesión de depuración con este programa. Para ello es

necesario indicarle al enlazador (linker) que incorpore al ejecutable información adicional con los datos necesarios para el depurador consistentes principalmente en tablas de símbolos con equivalencias entre nombres lógicos y direcciones más offsets. También se añade al ejecutable el código fuente de los archivos que han intervenido en la compilación del programa oal menos una referencia a los mismos.

Para habilitar el depurador abrimos el diálogo ProyectoOpciones de proyectoConfiguración y seleccionamos Yes en la opción de Generar Información de Debug

Tras recompilar el programa, podremos ver que el tamaño ha aumentado considerablemente.

Estrategias de depuración

Los depuradores suelen implementar un conjunto de funcionalidades básicas:

Ejecutar la aplicación hasta el final o hasta la siguiente condición de ruptura.

Puntos de ruptura (breakpoints).- Detienen la ejecución del programa en un punto determinado. Esta opción es muy útil para permitir comprobar la evolución interna del programa.

Puntos de comprobación (watchpoints).- Vinculan una condición bolean a una expresión del lenguaje (habitualmente una variable). Cuando esa condición se cumpla, se detendrá la ejecución del mismo.

Ejecución paso a paso.- Permite ejecutar el código línea a línea de tal forma que podamos comprobar la correcta marcha del programa. Existen tres posibilidades básicas de ejecución paso a paso:

o Paso a paso continuando por subrutinas.- Ejecuta paso a paso normalmente. Cuando nos encontremos sobre la llamada a una subrutina de la que disponemos de su código fuente, entraremos en la misma para seguir ejecutando sus líneas de código.

o Paso a paso sin entrar en subrutinas.- Ejecuta paso a paso normalmente pero al llegar a una llamada a subrutina, no la ejecuta internamente paso a paso, sino que lo hace de una vez.

o Salir de subrutina.- Ejecuta el código hasta salir de la subrutina actual.

Page 10: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Laboratorio de Informática Industrial II 10 Dpto Automática

Mostrar los registros de la CPU.

Mostrar las posiciones de memoria específicas.

Mostrar el contenido de la pila, por el que podremos avanzar y retroceder para conocer cuál ha sido la secuencia de llamadas hasta el punto actual.

Inspección de expresiones.- Muestra el resultado de evaluar expresiones sencillas relativas al programa.

Contenido de las variables.- Muestra el contenido de las variables visibles en ese momento.

Para que la ejecución se detenga en un punto determinado, pondremos un punto de interrupción haciendo clic sobre la banda negra en la línea donde deseemos detenerla.

Para iniciar la depuración presionamos [F8] o bien el botón .

A la izquierda de la barra aparecen los botones de ejecución paso a paso. A la derecha se

encuentra el botón Añadir watch que permite añadir las expresiones que señalemos a la caja central donde se mostrará el contenido de las mismas.

Page 11: Practica_1 en Dev C Para Puerto Paralelo (Directo Al Hw Desde Windows)

Práctica 2 11 Acceso a dispositivos

Proceso de desarrollo

1. Identificar los terminales del display así como los del cable plano suministrado alargador del puerto paralelo (mirar en la figura).

2. Realizar el montaje del circuito completo. Procurar que todas las resistencias y el CI tengan la misma orientación de lectura.

3. Realizar un programa básico en C que ofrezca combinaciones de tensión por los pines de datos del puerto paralelo (se puede usar el de ejemplo). Comprobar que aparecen en el otro extremo del cable plano.

4. Realizar un programa en C para que aparezca en el display la siguiente secuencia:

a. Una cuenta de 0 a 9 con un intervalo entre valor y valor de 250 ms.

b. Una ruleta que de 20 vueltas y encienda los LEDs del dígito 0 uno a uno según el sentido horario con un intervalo entre valor y valor de 100 ms.

c. Una ruleta que de 20 vueltas y encienda los LEDs del dígito 0 uno a uno según el sentido antihorario con un intervalo entre valor y valor de 100 ms.

d. Una cuenta de 9 a 0 con un intervalo entre valor y valor de 250 ms.

5. Conectar el circuito completo y hacer pruebas con el programa C definitivo (hallar previamente las combinaciones de segmentos para dar los símbolos requeridos).

Evaluación de la práctica

Para el desarrollo de la práctica se tiene 2 semanas. Se entregará funcionando a la 3ª.

Se mostrará la el circuito controlado por el PC. En el display deberán aparecer los 10 dígitos decimales.

El programa en C ha de estar correctamente realizado con las líneas alineadas y con los comentarios necesarios. Hacerlo LO MÁS COMPACTO POSIBLE. Utilizando arrays y bucles según sean necesarios.

Para esta primera práctica no se pide memoria.

Material necesario para el desarrollo de la práctica

1 Display de 7 segmentos (LEDs) de cátodo común.

8 Resistencias de 330 .

1 Placa entrenadora de circuitos (protoboard).

Hilos eléctricos de interconexión. Al menos 2 largos para conectar a la fuente de alimentación si fuera necesario (si el display es de cátodo común, no lo es).

Material eléctrico variado: Cortahilos, pinzas, alicates de uso electrónico,...