PROGRAMACIÓN EN LENGUAJE C
PARA CONTROL
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
2
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
TABLA DE CONTENIDO
Página
INTRODUCCIÓN ............................................................................................................ 5
FUNDAMENTACIÓN ..................................................................................................... 5
OBJETIVO ........................................................................................................................ 6
CAPITULO 1
3
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 6
PUNTEROS ..................................................................................................................... 53
7.1 DECLARACIÓN DE VARIABLES TIPO PUNTERO ..................................................................53
7.2 PUNTEROS Y ARRAYS..........................................................................................................55
7.3 ASIGNACIÓN ........................................................................................................................56
7.4 ARITMÉTICA DE PUNTEROS ................................................................................................57
7.5 PUNTEROS Y VARIABLES DINÁMICAS ..............................................................................58
7.6 PUNTEROS A STRINGS .........................................................................................................60
7.7 ARRAYS DE PUNTEROS .......................................................................................................62
CAPÍTULO 8
8.1 FUNCIONES DE ENTRADA Y SALIDA ...................................................................................65
8.2 CONFIGURACIÓN DE PUERTOS DE E/S ...............................................................................66
CONCLUSIONES........................................................................................................... 69
BIBLIOGRAFÍA............................................................................................................. 70
ANEXO A ........................................................................................................................ 71
ANEXO B ........................................................................................................................ 85
4
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
INTRODUCCIÓN
Este curso esta dividido en dos secciones: la primera trata sobre la teoría básica del
lenguaje C y la segunda sobre las funciones para dirigir la información de un programa a
salidas físicas que serán usadas como medio de control del robot SCARA de este curso.
Los primeros 7 capítulos se explican los aspectos teoricos del lenguaje C con la finalidad de
mostrar los elementos de sintaxis necesarios para implementar un algoritmo de control. El
último capítulo muestra como utilizar las funciones de entrada y salida a puertos, así como
también, la forma de habilitar dispositivos de tipo programable que serán instalados en la
computadora como periféricos de control.
Por otro lado el capitulo 5 trata el tema también de las funciones y las variables del
programa, sin embargo, las funciones de este capítulo son creadas por el usuario y los
argumentos de estas funciones son variables de diferentes tipos que se muestra la
metodología para hacer la declaración de dichos elementos.
Los capítulos 6 y 7 tratan el tema de arreglos de memoria y apuntadores los cuales son
pieza fundamental en la comprensión de los programas de control del robot, ya que se
destinará un arreglo de memoria para guardar las posiciones del manipulador de este curso
y además se utilizaran apuntadores para grabar los datos en localidades de memoria de
disco como respaldo, para la cual el uso de apuntadores es imprescindible.
Por último el capítulo 8 muestra el uso de funciones de entrada y salida de puertos paralelos
que serán el canal donde se transmita la información para activar el movimiento del robot y
recibir la información de las señales de retroalimentación.
FUNDAMENTACIÓN
Los elementos de un sistema mecatrónico no prosperan sin un buen cerebro de
computadora, actualmente la tecnología destina una gran parte de su inversión en el
desarrollo de nuevas tecnologías en el campo de la informática para desarrollar cerebros de
computadora más rápidos y baratos con la finalidad de hacer más eficiente e inteligente los
sistemas mecatrónicos. En este sentido la revolución de esta tecnología ha permitido que
cada vez mas usuarios pueden acceder a sistemas de computo que facilitan la
5
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
implementación de algoritmos de control solo conocidos en forma teórica, es así, que este
modulo muestra como dar control a un robot de arquitectura abierta con el fin de utilizar
formulaciones de cinemática y realizar el control de lazo semi cerrado de un robot tipo
SCARA.
OBJETIVO
Utilizar la teoría de lenguaje C con la finalidad de realizar control motores y hacer la
lectura de sensores por una computadora personal, hasta conseguir los elementos de
control y adquisición de datos suficientes para implementar formulaciones de las tareas
cinemáticas de robots manipuladores de tipo industrial, con lo cual dotar de la habilidad
suficiente al participante para plantear en forma teórica la programación de control de un
sistema dinámico a lazo cerrado.
6
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 1
INTRODUCCIÓN A LENGUAJE C
Este primer capítulo proporciona una introducción sobre el lenguaje C, es decir, quien lo
inventó, qué tipo de lenguaje es y qué nivel tiene. Situar al lenguaje C en relación al nivel
que tiene permite conocer el poder de éste, porque a medida que es de más bajo nivel tiene
más capacidad, pero por otro lado, se hace muy complejo para el usuario. El lenguaje C es
el justo medio entre complejidad y capacidad. Específicamente se hablará del origen del
lenguaje C, algunas características importantes del lenguaje, pasos para realizar un
programa.
Objetivo particular 1:
Utilizar el entorno del editor del lenguaje C, aplicando las sentencias básicas para que
puedan ser empleadas en los programas de control.
El lenguaje C fue inventado por Dennis Ritchie en 1972, cuando trabajaba junto con Ken
Thompson, en el diseño del sistema operativo UNIX.
El lenguaje C, deriva del lenguaje B de Thompson, el cual, a su vez, deriva del lenguaje
BCPL desarrollado por Martín Richards.
7
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Es un lenguaje de nivel medio. Este lenguaje permite programar a alto nivel (pensando a
nivel lógico y no en la máquina física) y a bajo nivel (con lo que se puede obtener la
máxima eficiencia y un control absoluto de cuanto sucede en el interior del ordenador).
Como desventajas habrá que resaltar que es más complicado de aprender que otros
lenguajes como Pascal o Basic y que requiere una cierta experiencia para poder
aprovecharlo a fondo.
Los pasos a seguir desde el momento que se comienza a escribir el programa C hasta que se
ejecuta son los siguientes:
Paso 1: Escribirlo
El programa se puede escribir en cualquier editor que genere archivos de texto estándar,
esto es, que los archivos generados no incluyan códigos de control y caracteres no
imprimibles. Estos archivos que contienen código C, se llaman archivos fuentes. Los
archivos fuentes son aquellos que contienen código fuente, es decir, archivos con texto que
el usuario puede leer y que son utilizados como entrada al compilador de C. Los programas
pequeños suelen ocupar un solo archivo fuente; pero a medida que el programa crece, se va
haciendo necesario distribuirlo en más archivos fuentes.
Paso 2: Compilarlo
El compilador produce archivos objetos a partir de los archivos fuentes. Los archivos
objetos son los archivos que contienen código objeto, es decir, archivos con código
8
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
máquina (números binarios que tienen significado para el microprocesador) y que son
utilizados como entrada al enlazador. La extensión de estos archivos es OBJ, aunque
también hay con extensión LIB. A estos últimos se les llama también archivos de librería o
biblioteca; contienen código máquina perteneciente a código compilado suministrado por el
compilador.
Paso 3: Enlazarlo
El enlazador produce un archivo ejecutable a partir de los archivos objetos. Los archivos
ejecutables son aquellos que contienen código máquina y se pueden ejecutar directamente
por el sistema operativo. La extensión estos archivos es EXE o COM.
Paso 4: Ejecutarlo
Hoy día los compiladores de C son muy sofisticados e incluyen entornos integrados desde
los cuales se editan, compilan, enlazan, y es posible realizar una multitud de servicios más.
En algunos de ellos se pueden realizar los pasos de compilado, enlazado y ejecutado con la
pulsación de una sola tecla.
/*****************************************************/
/********* PRIMER PROGRAMA C ************/
/*****************************************************/
#include <stdio.h>"
main ()
{
printf ("Hola mundo");
}
9
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Hola mundo
Realiza una llamada a una función denominada printf, con el argumento “Hola mundo”;
printf es una función de biblioteca que realiza una escritura en la salida estándar.
Normalmente la salida estándar es el monitor.
La función printf escribe concretamente una cadena (conocido también con los nombres de
cadena de caracteres, constante de caracteres y string).
Una cadena es una secuencia de caracteres. Cada instrucción en C, termina con un punto y
coma. La línea del main () no va seguida de punto y coma porque no se trata de una
llamada a una función sino de la definición de una función. La definición de una función
específica las instrucciones que posee dicha función así como los argumentos que tiene.
Una función de librería printf está definida en el archivo stdio.h (standard input/output
header). Las funciones de librería son aquellas suministradas por el compilador y que están
a nuestra disposición. Para utilizar una función de librería es necesario incluir el
correspondiente archivo de cabecera antes de utilizarla. Cada archivo de librería incluye
muchas funciones. Por ejemplo, la librería stdio.h define funciones de entrada y salida
estándar. Pero en el archivo ejecutable de nuestro programa sólo están las funciones de
librería que se han utilizado. De esta forma el tamaño del código ejecutable se reduce al
mínimo.
Todas las líneas que empiezan con # no son en realidad instrucciones del lenguaje C, sino
que son líneas para ser manipuladas por el preprocesador. El preprocesador realiza algunas
tareas antes de empezar a actuar el compilador.
10
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
#include <stdio.h>
Lo que hace es incluir la información que hay en el archivo stdio.h en este primer
programa.
/**************************************************/
/******** SEGUNDO PROGRAMA C ********/
/*************************************************/
#include <stdio.h>
main ()
{
printf ("Segundo programa en C.\n");
printf ("Pulsa la tecla ENTER para terminar.");
getch();
}
Segundo programa en C.
Hay dos novedades con respecto al primer ejemplo: la primera es la aparición del código \n
dentro de la cadena del primer printf. La segunda es la aparición de una nueva función de
librería: getch().
A todos los caracteres empezados por \ se les llaman secuencias de escape. Las secuencias
de escape son mecanismos para representar caracteres no imprimibles.
11
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Antes se vio la secuencia de escape \n que representaba a la nueva línea. Otras secuencias
de escape son \r para el retorno de carro, \t para el tabulador, \b para retroceso, \" para la
comilla, \' para el apóstrofe y \\ para la barra diagonal invertida.
Una solución alternativa es incluir la función getch () al final de la función main ().
getch() es una función que espera la pulsación cualquier tecla por parte del usuario.
Esta función no necesita argumentos pero los paréntesis son necesarios puesto que se trata
de una función. getch() se encuentra en la librería stdio.h, por lo tanto, siempre que se
utilice esta función en un programa es necesario incluir la línea:
#include <stdio.h>
/*************************************************************/
/****** TERCER PROGRAMA EN C *******/
/************************************************************/
#include <stdio.h>
main ()
{
int horas, minutos;
horas = 3;
minutos = 60 * horas;
printf ("Hay %d minutos en %d horas.", minutos, horas);"
getch();
}
12
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
son sentencias de asignación. La primera línea significa: dar a la variable horas el valor 3.
La segunda línea significa: dar a la variable minutos el resultado de multiplicar 60 por
horas. Nótese que las dos líneas terminan en punto y coma por ser dos sentencias o
instrucciones. En la línea int horas, minutos; se reserva espacio en memoria a las variables
horas y minutos. En las líneas hora = 3; minutos = 60 * horas; se les da valor a dichas
variables (al contenido de los espacios reservados). Posteriormente se les puede asignar a
estas variables valores diferentes. = es el operador de asignación y * es el operador de
multiplicación.
Otros operadores son: + (número positivo usado como operador unario y suma usado como
operador binario), - (número negativo usado como operador unario y substracción usado
como operador binario), / (operador de división), % (operador módulo, esto es, resto de la
división de dos números enteros).
Como se observa los dos %d no se han escrito y sin embargo se ha escrito en su lugar los
valores de las variables minutos y horas. El símbolo % avisa a la función printf que se va a
imprimir una variable en esta posición; la letra d informa que la variable a imprimir es
entera (digit).
printf significa escritura (print) con formato (format) porque nos permite formatear la
salida al gusto del ususario. La estructura de toda función C es:
{
declaración de variables
sentencias
}
13
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
14
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 2
OPERADORES Y EXPRESIONES DE C
En esta lección se hará un estudio completo sobre los tipos, operadores y expresiones del
lenguaje C. A modo de introducción se darán unas definiciones muy breves que serán
ampliadas a lo largo de toda la lección: Las variables y constantes son los objetos básicos
que se manipulan en un programa. Las declaraciones indican las variables que se van a
utilizar y establecen su tipo y, quizá su valor inicial. Los operadores especifican lo que se
va a hacer con ellas. Las expresiones combinan variables y constantes para producir
nuevos valores. Los programas funcionan con datos. Los datos son los números y los
caracteres que contienen la información a utilizar.
Objetivo particular 2
Las constantes son datos con valores fijos que no pueden ser alterados por el
programa.
Las variables son datos cuyo valor se puede cambiar a lo largo del programa.
Una segunda división de los datos se puede hacer según los tipos de que sean.
15
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Las dos asignaciones anteriores son equivalentes pero es preferible la primera asignación
porque es más portátil. A ch1 se le asigna en cualquier ordenador el carácter 'A'. Sin
embargo, a la variable ch2, en sistemas basados en código ASCII se le asigna el carácter 'A'
(el código ASCII de 65 es 'A'), y en sistemas basados en código EBCDIC se le asigna un
caracter distinto a 'A'. Todas las variables en C han de ser declaradas antes de poder ser
usadas. La forma general de declaración es la siguiente:
tipo lista_variables;
Aquí, tipo debe ser un tipo de datos válido de C y lista_variables puede consistir en uno o
más nombres de identificadores separados por comas. Las declaraciones deben estar antes
de la primera sentencia ejecutable. Ejemplos de declaraciones:
int i, j, k;
char caracter;"
Los identificadores en C, son los nombres usados para referenciar las variables, las
funciones y otros objetos definidos por el usuario. Los nombres de los identificadores están
compuestos por letras, dígitos y el caracter de subrayado. El número de caracteres
significativos de los identificadores depende del compilador. El primer caracter de un
identificador ha de ser letra o el caracter de subrayado.
Código Significado
\b retroceso
\f salto de página
\n nueva línea
\r retorno de carro
\t tabulación horizontal
\" comillas (")
16
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
char ch1, ch2, ch3, ch4; /*declaración de cuatro variables tipo caracter */
ch1 = '\n'; /* el caracter '\n' es el número 13 en ASCII */
ch2 = 13; /* 13 decimal <=> 12 octal <=> A hexadecimal */
ch3 = '\12'; /* también sería válido: ch3 = '\012'; */
ch4 = '\xA'; /* también sería válido: ch4 = '\xa'; */
Tipo entero
Es un número sin parte fraccionaria. Las constantes enteras se pueden escribir de uno de los
tres modos siguientes:
Las constantes de este tipo tienen parte real y parte fraccionaria. El tipo double tiene doble
precisión que el tipo float. Por lo demás, los dos tipos son iguales. La sintaxis correcta de
las constantes de estos dos tipos es: [signo] [dígitos] [.] [dígitos] [exponente] [signo]
dígitos]
Donde:
signo es + o -;
dígitos es una secuencia de dígitos;
. es el punto decimal;
exponente es E o e.
17
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Los elementos que están entre [] son opcionales, pero el número no puede empezar por e o
E, ya que el compilador lo interpretaría en este caso como un identificador y no como un
número. Algunos ejemplos de constantes de este tipo: 1.0e9, -3E-8, -10.1.
Tipo void
Significa sin valor, sin tipo. Uno de los usos de void se puede observar al comparar estos
dos programas:
Al poner void entre los paréntesis de la definición de una función, se define a ésta como
función que no tiene argumentos. No confundir con llamada a función, en cuyo caso no se
puede utilizar el void. Del mismo modo, al poner void antes del nombre de la función en la
definición de ésta, se declara como una función que no devuelve nada.
/***********************************************************/
/********** PROGRAMA DE EJEMPLO 4 ***********/
/***********************************************************/
#include <stdio.h>
i=1
c=c
f = 1.000000
d = 0.100000
18
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
2.2 Modificadores
A excepción del tipo void, los tipos de datos básicos pueden tener varios modificadores
precediéndolos. Hay modificadores de tipo y de acceso.
Modificadores de acceso
Un modificador de tipo se usa para alterar el significado del tipo base para que se ajuste
más precisamente a las necesidades de cada momento. Modificador Descripción Tipos a los
se les puede aplicar el modificador
El uso de signed con enteros es redundante aunque está permitido, ya que la declaración
implícita de entero asume un número con signo. El estándar ANSI elimina el long float por
ser equivalente al double. Sin embargo, como se puede observar en el último ejemplo visto,
para escribir un double con la función printf es necesario utilizar el código de formato de
printf: %lf; que significa: long float. Se puede utilizar un modificador de tipo sin tipo; en
este caso, el tipo se asume que es int. La longitud (y por tanto, también el rango) de los
tipos dependen del sistema que se utilice, no obstante, la siguiente tabla es válida para la
mayoría de sistemas:
19
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Modificadores de acceso
También hay otra clase que son los modificadores de acceso. Como su propio nombre
indica, estos modificadores modifican el acceso a los tipos.
Modificador Descripción
const constante
volatile volátil
Las variables de tipo const son aquellas a las que se les asigna un valor inicial y este valor
no puede ser cambiado a lo largo del programa. Se utilizan para declarar constantes.
Las variables de tipo volatile previenen al compilador que dicha variable puede ser
cambiada por medios no explícitamente especificados en el programa.
20
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Algunas sentencias de C:
int v;
v = 1;
v = 2;
volatile v;
En C, existen tipos derivados. Los tipos derivados son aquellos, que como su propio
nombre indica, derivan de los tipos básicos.
Cadenas de caracteres
Una cadena de caracteres (también conocido por el nombre de string) es una secuencia de
caracteres encerrados entre comillas.
Ejemplos de cadenas:
Las comillas no forman parte de la secuencia. Sirven para especificar el comienzo y final
de ésta, al igual que los apóstrofes marcaban los caracteres individuales.
Las cadenas son tratadas por el C, como un array de caracteres.
Un array (conocido también con el nombre de vector) es una secuencia de datos que se
encuentran almacenados en memoria de una forma consecutiva.
Un array de caracteres es una secuencia de caracteres.
El array:
"abc"
se almacenaría en memoria como:
a b c \0
21
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
El caracter '\0' se llama caracter nulo, y es utilizado por el C, para marcar el final de la
cadena en memoria.
El caracter nulo ('\0') no es la cifra 0 (cuyo código ASCII es 48), sino un caracter no
imprimible, cuyo código ASCII es 0.
Ejemplo:
#include<stdio.h>
void main (void)
{
printf ("\nInvertir en conocimientos produce siempre los mejores intereses. \n(%s)",
"Benjamín Franklin");
}
En este ejemplo se puede observar la aparición de dos elementos nuevos: la división de una
cadena de caracteres en varias líneas y el código de formato %s.
El código %s le indica a la función printf que escriba una cadena en su lugar. Una cadena
de caracteres se puede escribir en varias líneas de archivo cerrando las comillas al final de
la línea y volviéndolas a abrir en la línea siguiente. Haciéndolo de este modo, el compilador
lo interpreta como una sola cadena de caracteres escrita en varias líneas. En C, los finales
de instrucciones no se detectan con los finales de línea sino con puntos y comas al final de
cada instrucción.
22
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
2.3 Operadores
Operador Acción
- Resta, también menos monario
+ Suma, también suma monario
* Multiplicación
/ División
% División en módulo
-- Decremento
++ Incremento
int x, y; int x, y;
x = 2; x = 2;
y = ++x; y = x++;
/* ahora x tiene el valor 3 /* ahora x tiene el valor 3
e y tiene el valor 3 */ e y tiene el valor 2 */
Los operadores del mismo nivel de precedencia son evaluados por el compilador de
izquierda a derecha. Se puede alterar el orden de evaluación utilizando paréntesis.
23
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Ejemplo:
x1 = 2 + 3 * 4; /* x1 = 14; */
x2 = (2 + 3) * 4; /* x2 = 20; */
x3 = -4 - (-1); /* x3 = -3; */
x4 = 10 / 2 % 3; /* x4 = 2; */
x5 = ++x3 - x4; /* x3 = -2; x5 = -4; */
x6 = x3++ - x4; /* x6 = -4; x3 = -1; */
x1 = -x1; /* x1 = -14; */
x2 = (x1 + x2) / x3; /* x2 = -6; */
x3 = ((x1++) + (x2++)) - x3; /* x3 = -19; x1 = -13; x2 = -5; */
x4 = -(-(-x3)); /* x4 = 19; */
x5 = (x6 * x6 + x6 / x6); /* x5 = 17; */
x6 = (x1++) + (++x2) - (++x6); /* x2 = -4; x6 = -3; x6 = -14; x1 = -12; */
x1++; /* x1 = -11; */
--x2; /* x2 = -5; */
}
La palabra relacional se refiere a la relación entre unos valores y otros. La palabra lógico se
refiere a las formas en que esas relaciones pueden conectarse entre sí.
Los operadores se basan en la idea de cierto (true en inglés) y falso (false en inglés). En C,
cualquier valor distinto de cero es cierto, y el valor 0 es falso. Las expresiones que son
ciertas toman el valor de 1 y las que son falsas toman el valor de 0.
24
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Ejemplo:
x1 = 10 < 12; /* x1 = 1; */
x2 = 10 > 12; /* x2 = 0; */
x3 = -1 && 5; /* x3 = 1; */
x4 = 0 || x3; /* x4 = 1; */
x5 = x1 >= x2 <= x3; /* x5 = 1; */
x6 = x1 == x2 || x3 != x4; /* x6 = 0; */
x1 = !x1; /* x1 = 0; */
x2 = ! (!x1 || x3 <= x3); /* x2 = 0; */
x3 = 1 && 0; /* x3 = 0; */
x4 = 1 || 0; /* x4 = 1; */
x5 = !(-10); /* x5 = 0; */
x6 = !!x4; /* x6 = 1; */
}
Estos operandos realizan operaciones sobre los bits de un byte o una palabra (dos bytes).
Solo se pueden utilizar con los tipos char e int. Estos operadores son:
Operador Acción
& Y
| O
^ O exclusiva (XOR)
~ Complemento (NOT)
>> Desplazamiento a la derecha
<< Desplazamiento a la izquierda
25
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Ejemplo:
1) Un desplazamiento no es una rotación. O sea, los bits que salen por un extremo no se
introducen por el otro.
2) Normalmente, a medida que se desplaza los bits hacia un extremo se va rellenando con
ceros por el extremo opuesto. PERO NO EN TODOS LOS ORDENADORES ES ASI.
26
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 3
SENTENCIAS DE CONTROL
En este capítulo se estudiara las sentencias de control que posee el C entre las que se
encuentran las condicionales if y switch; las sentencias iterativas while, for y do; y las
sentencias break, y return, entre las más importantes.
Objetivo particular 3:
Se empleará todas las sentencias que posee el C para controlar el flujo del programa.
Primero se estudiará a través de diagramas de flujo las principales sentencias de control,
entre las que se encuentran las condicionales if y switch; las sentencias iterativas while, for
y do; y las sentencias break, y return, todo esto con la finalidad de elaborar programas que
realicen calculos de álgebra lineal simples y conduzcan a las tecnicas de diseño de
algoritmos de control del robot scara.
Las sentencias if, switch, while, for y do son sentencias simples. Todas estas sentencias
serán estudiadas en esta lección. Una sentencia compuesta está formada por ninguna, una o
varias sentencias simples delimitadas entre llaves. A las sentencias compuestas también
reciben el nombre de bloques. Las sentencias simples son todas aquéllas que no son
compuestas.
27
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
C posee dos sentencias condicionales: if y switch. Estas dos sentencias permiten hacer
algoritmos con toma de decisión bajo argumentos de tipo condición, es decir, bifurcar en un
programa a partir de una o más condiciones.
Existen dos tipos de sentencias como se mencionó, la primera es la if que permite bifurcar
bajo una sola condición. Mientras que la secuencia switch es para multiples condiciones.
Sentencia if
if ( expresión )
sentencia
o
if (expresión)
sentencia_1
else sentencia_2
Ejemplos:
if (x <= y)
if (x <= z)
numero_menor = x;
else
numero_menor = z;
else
if (y <= z)
numero_menor = y;
else
numero_menor = z;
El else siempre está asociado al if más cercano. Los dos siguientes ejemplos son distintos:
/**** Ejemplo 1: ****/
if (n > 0)
if (a > b)
z = a;
28
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
else
z = b;
Sentencia switch
switch (expresión)
{
case expresión_constante_1:
sentencias_1
break;
case expresión_constante_2:
sentencias_2
break;
case expresión_constante_3:
sentencias_3
break;
.
.
.
default:
sentencias_n
}
Una expresión constante es una expresión en la que todos los operandos son constantes.
El switch evalúa expresión. A continuación evalúa cada una de las expresiones constantes
hasta que encuentra una que coincida con expresión. Cuando la encuentra ejecuta las
sentencias correspondientes a ese case. Si no hay ninguna expresión case que coincida con
expresión, se ejecuta las sentencias correspondientes al default.
Ejemplo:
switch (operando)
{
case 1:
x=x * y; break;
case 2:
x=x / y; break;
case 3:
x=x + y; break;
case 4:
x=x- y; break;
29
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
default:
printf ("ERROR");
}
Observaciones
1) La sentencia default es opcional. Si fallan todas las comprobaciones de los case y no hay
default, no se ejecuta ninguna acción en el switch. Incluso el default puede ir en cualquier
posición y no obligatoriamente al final.
2) Las sentencias break en el switch son opcionales. El break hace que se produzca una
salida inmediata de la instrucción switch. Si no hay una sentencia break en un case, al
ejecutarse las sentencias que corresponden a ese case, también se ejecutarían las sentencias
correspondientes al siguiente case y así sucesivamente hasta encontrar un break o llegar al
final del switch. La sentencia break puede ir en cualquier sitio, no forzosamente al final de
las sentencias de los case.
Los bucles o sentencias iterativas permiten que un conjunto de instrucciones sea ejecutado
hasta que se alcance una cierta condición. Las sentencias iterativas son: while, for y do.
Sentencia while
Sintaxis
Descripción
Ejemplo:
While(conta<10)
{
gotoxy(10,10);
printf(“El contador es:%d”,conta);
conta++;
delay(300);
}
En este ejemplo el valor del contador se incrementa y despliega en la pantalla mientras sea
menor de 10. La función gotoxy manda poner la variable conta en la posición 10, 10 y la
función delay es un función de retardo y su argumento está dado en milisegundos, es decir,
para este caso el retardo es de 0.3 de segundo.
30
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Sentencia for
Descripción
Ejemplo:
#include <stdio.h>
{
int i;
for(i=0;i<100;i++)
{
printf(“Variable i=%d”,i);
}
}
Observación
La instrucción:
for (;;)
sentencia; es un bucle infinito. Sin embargo, aunque en este bucle no es posible salir por la
condición del for, se puede salir por otros medio (por ejemplo, mediante la sentencia
break.)
Sentencia do
Sintaxis
do
sentencia
while (expresión);
31
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
#include <stdio.h>
Observación
Las llaves en el ejemplo anterior no son necesarias al tratarse de una sola sentencia; pero en
el caso de la sentencia do, es recomendable que siempre se ponga las llaves para hacer el
programa más legible (para el lector, no para el compilador).
En esta lección se han estudiado las mas importantes sentencias de control de programa que
posee el C. Entre ellas se incluyen los constructores de bucles while, for y do, las sentencias
condicionales if y switch.
32
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 4
FUNCIONES BASICAS
Este capítulo describe el manejo de las funciones básicas de entrada y salida para hacer
algunos programas básicos e introducirse en el campo de las funciones que en otros
lenguajes de cómputo son conocidas como subrutinas. El material de este capítulo solo
presenta algunas funciones como: printf, scanf, kbhit, exit y getch; Con la finalidad de
conocer el uso de las funciones y al mismo tiempo entender la filosofía del lenguaje C para
ser capaces de crear funciones propias en el siguiente capítulo.
Objetivo particular 4
Emplear las funciones de control de programa, de entrada, salida y de consola con el fin
de introducirse en el uso de funciones estandar.
En la lección anterior se vieron las sentencias de control de programa: if switch, while, for,
do.
A continuación se estudiarán las funciones que pueden afectar al flujo de control de un
programa; esta funcion es: exit();
Función exit ()
33
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
El final de la entrada y salida se suele marcar (en el caso de archivos de texto ocurre
siempre) con un carácter especial llamado Fin-De-Archivo y se simboliza "EOF" (End-Of-
File). Hay una constante definida en el archivo stdio.h que se llama EOF y tiene el valor de
-1. El caracter de fin de archivo se suele escribir con CONTROL-Z (código ASCII 26) en el
DOS y CONTROL-D en UNIX. Algunas funciones del C (por ejemplo, scanf) devuelven el
valor de EOF cuando leen el caracter de marca de fin de archivo.
En las operaciones de E/S, los datos utilizados suelen pasar por buffers. Un buffer es una
cantidad de memoria utilizada para meter y sacar datos.
Tras estos preliminares ya estamos en condiciones de ver las principales funciones de E/S:
printf, scanf, putchar, getchar, puts y gets.
La función printf escribe datos formateados en la salida estándar. La función scanf lee datos
formateados de la entrada estándar. El término "con formato" se refiere al hecho de que
estas funciones pueden escribir y leer datos en varios formatos que están bajo su control.
Ambas funciones están declaradas en el archivo stdio.h, y tienen la forma general:
La cadena de control está formada por caracteres imprimibles y códigos de formato. Debe
haber tantos códigos de formato como argumentos. Los códigos u órdenes de formato son
las siguientes:
Código Formato
%c Simple caracter
%d Entero decimal con signo
%e Punto flotante en notación científica: [-]d.ddd e [+/-]ddd
%f Punto flotante en notación no científica: [-]dddd.ddd
%s Cadena de caracteres
%x Entero hexadecimal sin signo
%p Puntero
34
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Las órdenes de formato pueden tener modificadores. Estos modificadores van entre el % y
la letra que identifica el código. Si el modificador es un número, especifíca la anchura
mínima en la que se escribe ese argumento. Si ese número empieza por 0, los espacios
sobrantes (si los hay) de la anchura mínima se rellenan con 0. Si ese número tiene parte real
y parte fraccionaria, indica el número de dígitos de la parte real y de la parte fraccionaria a
imprimir en el caso de imprimir un número, o indica el número mínimo y máximo a
imprimir en el caso de imprimir una cadena de caracteres. Por defecto, la salida se justifica
a la derecha en caso de que se especifique anchura mínima; si el modificador es un número
negativo, la justificación se hará a la izquierda. Otros dos modificadores son las letras l y
h; el primero indica que se va a imprimir un long, y h indica que se va a imprimir un short.
En la explicación de los modificadores se ha hablado de imprimir, es decir, se ha hablado
del printf. Los modificadores de scanf son los mismos.
Ejemplos:
Hay una diferencia muy importante entre los argumentos de printf y scanf. En printf los
argumentos son expresiones pero en scanf los argumentos han de ser direcciones de
memoria (punteros).
Los punteros se van a estudiar en un capítulo posterior. No obstante, hablaremos en este
momento un poco de ellos para saber utilizar la función scanf.
Los punteros hemos dicho que son direcciones de memoria. Para obtener la dirección de
memoria de una variable es necesario aplicar el operador monario & (no confundirlo con el
operador binario, que es el and entre bits) de la siguiente forma:
& variable
35
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Hay un tipo de variable un poco especial a este respecto, que son los vectores (también
llamados arrays), cuyo nombre es un puntero que apunta al primer elemento del vector.
Ahora mismo se pretende saber cómo usar la función scanf, no los punteros, que es tema de
otro capítulo lección; por cierto, el tema de los punteros es, quizás, una de los más difíciles
del C.
Programa ejemplo:
/********************************************************************************************
Programa que lee números enteros de teclado hasta que se introduce un 0.
El programa no es muy útil pero sí instructivo.
********************************************************************************************/
Las llamadas a funciones son expresiones y como el resultado de evaluar una expresión es
un valor (a no ser que el resultado de la expresión sea de tipo void), las funciones pueden
devolver valores y la llamada a esa función toma el valor devuelto por la función.
Suponiendo que f() es una función que devuelve un entero, entonces, las siguientes
expresiones son correctas:
int x, y, z;
x = f ();
y = f () * 2;
f ();
(void) f ();
z = f () + f ();
if (f () < 0)
printf ("ERROR");
La función printf devuelve un valor entero que contiene el número de caracteres escritos.
En caso de error, devuelve EOF.
36
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Las funciones de consola que se describirán no están definidas en el estándar ANSI, ya que
son funciones, que por su propia naturaleza, dependen del entorno fijado y en gran parte no
son portátiles. Sin embargo, estos tipos de funciones tienen una importancia primordial a la
hora de crear un software de calidad.
Todo lo que se diga sobre estas funciones es válido para los dos compiladores de C más
importantes: el de Microsoft y el de Borland. Si utilizas otro compilador distinto a los
anteriores, es probable que los nombres de las funciones coincidan con las que vamos a ver,
en caso contrario, estas funciones tendrán otros nombres.
Las características de consola específicas de Borland sólo se estudian si la opción turbo
está en modo on.
La función cprintf es similar a la función printf. Lo mismo sucede con los pares de
funciones: cscanf-scanf, cputs-puts, putch-putchar, getch-getchar, getche-getchar, cputs-
puts y cgets-gets.
Las diferencias entre estos pares de funciones se muestran en la tabla:
37
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
2) Las funciones de escritura estándar siempre escriben en pantalla con los colores
blanco sobre negro. Las funciones de escritura de consola escriben con cualquier
atributo de pantalla.
Función kbhit ()
La función kbhit devuelve un valor cierto (distinto de cero) si hay una tecla disponible y
falso (0) si no la hay.
Ejemplo:
#include <conio.h>
do{
numero++;
}while(!kbhit());
getch ();
}
Este programa incrementa en uno a la variable numero hasta que es presionada una tecla.
38
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 5
VARIABLES Y FUNCIONES
Este capítulo trata el tema de las funciones creadas por el usuario, su relación con las
variables que formaran parte del argumento de dichas funciones. La idea central de este
estudio es proporcionar al alumno en el campo fascinante de cómo crear las funciones y
emplearlas en un programa de control.
Objetivo particular 5:
Los programas en C, al menos que sean muy simples, en cuyo caso estarían compuestos
sólo por la función main, están formados por varias funciones.
{
cuerpo_de_la_funcion
}
39
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Ejemplo:
#include <stdio.h>
2+3=5
2 - 3 = -1
El funcionamiento de este ejemplo parece claro. Hay una observación importante que hacer
acerca del mismo: Si la función main se hubiera definido antes de las funciones funcion_1
y funcion_2, el compilador al procesarlas llamadas a funcion_1 y funcion_2 no sabe que
tipo son dichas funciones y nos puede informar de un error o asumir que devuelven un
entero. Es bueno declarar todas las funciones a utilizar (excepto main) antes de su
definición para evitar problemas de este tipo. El ejemplo anterior se escribiría de la
siguiente forma:
#include <stdio.h>
40
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
En las declaraciones (no en las definiciones que son las descripciones completas de las
funciones) explícito suprimir el nombre de los parámetros, así que también se podría haber
hecho:
e incluso también:
Al igual que se declaran las variables. A las declaraciones de las funciones también se les
llama prototipos.
Todas las funciones, excepto aquéllas del tipo void, devuelven un valor. Este valor se
especifíca explícitamente en la sentencia return y si no existe ésta, el valor es 0.
La forma general de return es:
return expresión;
1) La sentencia return tiene dos usos importantes. Primero, fuerza a una salida inmediata
de la función, esto es, no espera a que se llegue a la última sentencia de la función para
acabar. Segundo, se puede utilizar para devolver un valor.
2) return no es una función sino una palabra clave del C, por lo tanto no necesita
paréntesis como las funciones, aunque también es correcto: return (expresión); pero
teniendo en cuenta que los paréntesis forman parte de la expresión, no representan una
llamada a una función.
3) En las funciones de tipo void se puede hacer: return; y de esta forma se provoca la
salida inmediata de la función.
Ejemplo:
#include <stdio.h>
41
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Existen tres lugares básicos donde se pueden declarar variables: dentro de funciones, en la
definición de parámetros de funciones y fuera de las funciones. Estas variables son,
respectivamente, variables locales, parámetros formales y variables globales.
Variables locales
Son aquéllas que se declaran dentro de una función. Estas variables se declaran al principio
de un bloque de código, se destruyen al llegar al final del bloque de código y sólo puede ser
utilizada (ya que sólo tiene existencia) dentro de ese bloque. Recuerda que un bloque de
código empieza con una llave abierta y termina con una llave cerrada.
Ejemplos:
void f1 (void)
{
int x; /* se reserva memoria para x */
x = 10; /* se le asigna un valor */
} /* se libera la memoria asignada a x */
void f2 (void)
{
int x = 1; /* se reserva memoria para x */
/* sentencias */
{
int y = 2; /* se reserva memoria para y */
/* sentencias */
} /* se libera memoria asignada a y */
/* sentencias */ /* en ese punto no existe la variable y */
} /* se libera memoria asignada a x */
void f3 (void)
{
int x, y; /* se reserva memoria para las variables x e y */
x = 1; /* se asigna 1 a la variable x */
y = x; /* se asigna x (1) a la variable y */
42
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Si una función va a usar argumentos, entonces debe declarar las variables que van a aceptar
los valores de esos argumentos. Estas variables son los parámetros formales de la función.
Se comportan como cualquier otra variable local de la función.
Variables globales
A diferencia de las variables locales, las variables globales se conocen a lo largo de todo el
programa y se pueden usar en cualquier parte de código. Además, mantienen su valor
durante toda la ejecución del programa. Las variables globales se crean al declararlas en
cualquier parte fuera de una función.
Ejemplo:
int x;
void f2 (void)
{
x = 11;
}
void f3 (void)
{
int x; /* esta variable x es local, es distinta a la global */
x = 12; /* se le asigna x a la variable x local, no a la global */
}
43
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Se usan para indicar al compilador cómo se debe almacenar la variable que le sigue. El
especificador de almacenamiento precede al resto de la declaración de variable. Su forma
general es:
Extern
Static
Las variables globales son variables permanentes. Tienen dos significados diferentes
dependiendo si son locales o globales.
La diferencia con las variables locales normales es que su contenido no se pierde al salirse
de la función, de tal manera que al volver a entrar en la función, la variable estática tiene el
mismo valor que el que tenía cuando terminó la función en la llamada anterior. La variable
estática sólo es inicializada en la primera llamada a la función.
Ejemplo:
#include <stdio.h>
44
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
f1 ();
f1 ();
f2 ();
f2 ();
}
void f1 (void)
{
static int x = 1;
printf ("\nx = %d", x);
x++;
}
void f2 (void)
{
int y = 1;
printf ("\ny = %d", y);
y++;
}
Cuando se aplica el modificador static a una variable global, se indica al compilador que
cree una variable global conocida únicamente en el archivo en el que se declara la variable
global static. Esto significa que, aunque la variable es global, las rutinas de otros archivos
no la reconocerán ni alternarán su contenido directamente; así, no esta sujeta a efectos
secundarios.
5.6 Register
Varias observaciones:
1) El acceso a los registros de la CPU es mucho más rápido que el acceso a la memoria.
2) Las variables register se almacenan en los registros si se puede, si no, se almacenan en
memoria.
3) Las variables register sólo pueden ser de tipo int y char, y además han de ser locales no
estáticas o parámetros de función.
4) En la mayoría de los sistemas sólo se permiten una o dos variables register al mismo
tiempo. En la práctica, se declaran variables register aquéllas que se utilizan como índices
en los bucles."
45
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Ejemplo:
5.7 Auto
Las variables auto (automáticas) son todas aquellas variables locales que no son estáticas.
En la práctica, este especificador de clase de almacenamiento no se utiliza nunca, ya que
todas las variables locales que no llevan el especificador static son consideradas auto.
46
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 6
ARREGLOS DE MEMORIA
Este capítulo trata el tema de arreglos de memoria, es decir, localidades de memoria que se
agrupan y pueden ser accesados en forma indexada. Este tipo de variables se les conoce
como vectores. Estos pueden ser arreglos de n dimensiones. Para el caso exclusivo de este
curso se emplean estos arreglos para guardar valores numéricos que representan las
posiciones del brazo del robot, esto con el fin de memorizar los datos en un conjunto que se
denominarán PATHS del movimiento. (El módulo de mecatrónica aplicada estudiará con
aplicaciones directas en el robot con mayor detalle.)
Objetivo particular 6
Realizar operaciones de álgebra lineal utilizando arreglos de una y dos dimensiones para
guardar en dichos arreglos los datos correspondientes a posiciones del robot.
Los arreglos o conjuntos de datos ordenados (arrays) recolectan variables del MISMO tipo,
guardándolas en forma secuencial en la memoria. La cantidad máxima de variables que
pueden albergar está sólo limitada por la cantidad de memoria disponible. El tipo de las
variables involucradas puede ser cualquiera de los ya vistos, con la única restricción de que
todos los componentes de un array deben ser del mismo tipo.
Por ejemplo:
int var1[10];
char nombre[50];
float numeros[200];
long double cantidades[25];
Si en el primer caso, se declara un array de 10 variables enteras, cada una de ellas quedará
individualizada por el subíndice que sigue al nombre del mismo es decir:
47
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Se puede referenciar a cada elemento, en forma individual, tal como se ha hecho con las
variables anteriormente, por ejemplo:
var1[5] = 40;
contador = var1[3] + 7;
if(var1[0] >>= 37)
Por supuesto los subíndices resultantes de las operaciones tienen que estar acotados a
aquellos para los que el array fue declarado y ser enteros. La inicialización de los arrays
sigue las mismas reglas que vi para los otros tipos de variables, es decir: Si se declaran
como globales (afuera del cuerpo de todas las funciones) cada uno de sus elementos será
automáticamente inicializado a cero. Si en cambio, su declaración es local a una función,
no se realiza ninguna inicialización, quedando a cargo del programa cargar los valores de
inicio.
int numero[8] = { 4, 7, 0, 0, 0, 9, 8, 7 };
Obsérvese que la lista está delimitada por llaves. Otra posibilidad, sólo válida cuando se
inicializan todos los elementos del array, es escribir:
int numero[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int numero[10] = { 1, 1, 1 };
En éste caso los tres primeros elementos del mismo valdrán 1, y los restantes cero en el
caso que la declaración sea global, o cualquier valor impredecible en el caso de que sea
local.
48
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Los strings son simplemente arrays de caracteres, con el agregado de un último elemento
constante: el caracter NULL ( ASCII == 0, simbolizado por la secuencia de escape \0 ).
Este agregado permite a las funciones que procesan a los mismos determinar fácilmente la
finalización de los datos. Podemos generar un string, declarando:
Ambas maneras son equivalentes. Sin embargo hay, en el lenguaje C, una forma más
compacta de declararlos:
Un caso interesante es el de la tercer línea (comentada como ERROR ), con el fin de poder
albergar al caracter "\n"20( ASCII 179 ) se intentó asignar el string a un array de enteros,
Esto no es permitido por el compilador, que lo rechaza como una asignación inválida.
La razón de ello se verá más adelante cuando se analicen punteros, ya que el string
constante usado como value es un puntero a char, y no a int. La solución más común para
este caso es, declarar el array como unsigned char, con lo que se lleva el alcance de sus
elementos a 255. Para el caso de tener que albergar en un string el caracter EOF ( -1 ) y al
mismo tiempo caracteres con ASCII mayor que 127, se podría definir el array como int,
pero su inicialización se tendrá que hacer obligatoriamente usando llaves, como se vio
anteriormente. Se deduce entonces, de lo antedicho que un string sigue siendo un array de
caracteres, con la salvedad del agregado de un terminador, por lo que las propiedades que
se estudiarán a continuación, se aplicarán indistintamente a ambos.
Los arrays, como todos los otros tipos de variables, pueden ser pasados como argumentos a
las funciones. Vea esquemáticamente como sería la sintaxis:
49
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Es necesario analizar con mucho detenimiento, este último ejemplo. En la primer línea se
declara el prototipo de funcion_1 () que recibe como argumentos dos arrays, uno de 10
elementos del tipo float, y otro de caracteres de longitud indeterminada.
En el primer caso la función necesitará saber de alguna manera cual es la longitud del array
numérico recibido, mientras que en el segundo, no hace falta, ya que la función puede ser
construida para que, por sí misma, detecte la finalización del string por la presencia del
caracter NULL. Se podría generalizar más el programa declarando:
En el lenguaje C se prefiere, para evitar el uso abusivo del stack, cuando hay que enviar a
una función una larga estructura de datos, en lugar de copiar a todos ellos, cargar el stack
sólo con la dirección de la posición de memoria donde está ubicado el primero. El nombre
de un array equivale sintácticamente a la dirección del elemento cero así será:
Esto habilita a las funciones a que puedan acceder a los arrays directamente, allí donde el
programa los ha ubicado en la memoria, por lo que pueden MODIFICARLOS EN FORMA
PERMANENTE aunque no hayan sido declarados como locales a la función misma ni
globales al programa.
Es muy importante recordar este último concepto, a fin de evitar errores muy comunes, en
los primeros intentos de programación en C. Otra característica importante de los arrays es
que, su nombre (o dirección del primer elemento) es una CONSTANTE y no una variable.
El nombre de los arrays implican para el compilador el lugar de memoria donde empieza la
estructura de datos por lo que, intentar cambiar su valor es tomado como un error, así si
escribiera por ejemplo:
50
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Las estructuras de datos del tipo array pueden tener más de una dimensión, es bastante
común el uso de arrays "planos" o matriciales de dos dimensiones, por ejemplo:
Si declara:
int matriz[3][4];
columnas: 0 1 2 3
Por supuesto, aunque menos usados, se pueden generar arrays de cualquier número de
dimensiones. Para inicializar arrays multidimensionales, se aplica una técnica muy similar
a la ya vista, por ejemplo para dar valores iniciales a un array de caracteres de dos
dimensiones, se escribirá:
char dia_de_la_semana[7][8] = {
"lunes", "martes", " miercoles",
"jueves", "viernes", "sábado",
"domingo"
};
En este caso el elemento [0][0] será la "l" de lunes, el [2][3] la "r" de miércoles, el [5][2]
la "b" de sábado, etc. Nótese que los elementos [0][5], [1][6],etc están inicializados con el
caracter NULL y demás [0][6] y [0][7], etc no han sido inicializados. Si le parece que en
51
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
este párrafo se nos escapó un error, está equivocado, lo que ocurre es que se olvidó de
contar los índices desde 0. Este último ejemplo también podría verse como un array
unidimensional de strings.
52
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 7
PUNTEROS
Este capítulo trata el complejo tema de los punteros en el Lenguaje C, son variables que
"apuntan", es decir que poseen la dirección de las ubicaciones en memoria de otras
variables, y por medio de ellos se tendrá un poderoso método de acceso a todas ellas.
Quizás este punto es el más conflictivo del lenguaje, ya que muchos programadores en
otros idiomas, y novatos en C, lo ven como un método extraño o al menos
desacostumbrado, lo que les produce un cierto rechazo. Sin embargo, y en la medida que
uno se va familiarizando con ellos, se convierten en la herramienta más cómoda y directa
para el manejo de variables complejas, argumentos, parámetros, etc, y se empieza a
preguntar como es que hizo para programar hasta aquí, sin ellos. La respuesta es que no lo
ha hecho, ya que se han usado en forma encubierta, sin decir lo que eran. ( Perdón por el
pequeño engaño ).
Objetivo particular 7
Utilizar los apuntadores de lenguaje C para llevar los datos de memoria RAM a memoria
fija en disco, con la finalidad de respaldar la información de las posiciones del robot.
En estas declaraciones sólo se dice al compilador que reserve una posición de memoria
para albergar la dirección de una variable, del tipo indicado, la cual será referenciada con el
nombre que se haya dado al puntero.
Obviamente, un puntero debe ser inicializado antes de usarse, y una de las eventuales
formas de hacerlo es la siguiente:
53
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
En realidad, como se abordará más adelante, en la declaración del puntero, está implícita
otra información: cual es el tamaño (en bytes) de la variable apuntada. El símbolo &, o
dirección, puede aplicarse a variables, funciones, etc, pero no a constantes o expresiones,
ya que éstas no tienen una posición de memoria asignada. La operación inversa a la
asignación de un puntero, de referenciación del mismo, se puede utilizar para hallar el valor
contenido por la variable apuntada. Así por ejemplo serán expresiones equivalentes:
y = var1;
y = *pint;
printf("%d", var1 );
printf("%d", *pint);
En estos casos, la expresión " *nombre_del_puntero ", implica " contenido de la variable
apuntada por el mismo ". Vea un corto ejemplo de ello:
#include <stdio.h>
main()
{
char var1; /*una variable del tipo caracter */
char *pchar; /* un puntero a una variable del tipo caracter */
pc = &var1; /*asigna al puntero la dirección de la variable */
for (var1 = 'a'; var1 <<= 'z'; var1++)
printf("%c", *pchar); /* imprime el valor de la variable apuntada */
return 0;
}
Se ve, que en el FOR se incrementa el valor de la variable, y luego para imprimirla usa la
de referencia de su puntero. El programa imprimirá las letras del abecedario de la misma
manera que lo habría hecho si la sentencia del printf() hubiera sido, printf("%c", var1 )
Hay un error, que se comete con bastante frecuencia, y es cargar en la dirección apuntada
por un puntero a un tipo dado de variable, el contenido de otro tipo de las mismas, por
ejemplo:
54
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
double d = 10.0;
int i = 7, *pint;
pint = &i;
*pint = 10; /* correcto, equivale a asignar a i el valor 10 */;
*pint = d; /* ERROR se pretende cargar en una variable entera un valor double */
pint = &d; /* INCORRECTO se pretende apuntar a una variable double con un
puntero declarado como apuntador a int */
pint = 4358; /* ?????? */
Hay un sólo caso en el que esta asignación de una constante a un puntero es permitida,
muchas funciones para indicar que no pueden realizar una acción o que se ha producido un
error de algún tipo, devuelven un puntero llamado "Null Pointer", lo que significa que no
apunta a ningún lado válido, dicho puntero ha sido cargado con la dirección NULL ( por lo
general en valor 0 ), así la asignación: pint = NULL; es válida y permite luego operaciones
relacionales del tipo if( pint )..... o if( print != NULL ) para convalidar la validez del
resultado devuelto por una función.
Una advertencia: si bien se retomará más adelante sobre este tema, se debe desde ahora
tener en cuenta que los punteros no son enteros, como parecería a primera vista, ya que el
número que representa a una posición de memoria, sí lo es. Debido al corto alcance de este
tipo de variable, algunos compiladores pueden, para apuntar a una variable muy lejana, usar
cualquier otro tipo, con mayor alcance que el antedicho.
Hay una relación muy cercana entre los punteros y los arrays. Ya vi previamente que el
designador (nombre de un array ) era equivalente a la dirección del elemento [0] del
mismo. La explicación de esto es ahora sencilla: el nombre de un array, para el compilador
C, es un PUNTERO inicializado con la dirección del primer elemento del array. Sin
embargo hay una importante diferencia entre ambos, que se hace notar más abajo. Ahora se
ven algunas operaciones permitidas entre punteros:
55
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
7.3 Asignación
ASIGNACIÓN ERRONEA
56
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Se han declarado y asignado dos punteros, uno a int y otro a double, con las direcciones de
dos arrays de esas características. Ambos estarán ahora apuntando a los elementos [0] de
los arrays. En las dos instrucciones siguientes se incrementan en uno dichos punteros.
¿Adónde apuntaran hora?.
Para el compilador, estas sentencias se leen como: incremente el contenido del puntero
(dirección del primer elemento del array) en un número igual a la cantidad de bytes que
tiene la variable con que fue declarado. Es decir que el contenido de pint es incrementado
en dos bytes (un int tiene 2 bytes) mientras que pdou es incrementado 8 bytes ( por ser un
puntero a double ), el resultado entonces es el mismo para ambos, ya que luego de la
operación quedan apuntando al elemento SIGUIENTE del array, arreglo_int[1] y
arreglo_dou[1].
De ésta manera será muy fácil "barrer" arrays, independientemente del tamaño de variables
que lo compongan, permitiendo por otro lado que el programa sea transportable a distintos
tipos de hardware sin preocuparse de la diferente cantidad de bytes que pueden asignar los
mis, a un dado tipo de variable.
De manera similar las dos instrucciones siguientes, vuelven a incrementarse los punteros,
apuntando ahora a los elementos siguientes de los arrays Todo lo dicho es aplicable, en
idéntica manera, al operador de decremento --.
int *p, a[] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 };
int var;
p = a;
A partir de aquí, el puntero está apuntando a a[0]. Ver las distintas variantes que puede
tener la siguiente instrucción:
*p = 27;
La más sencilla de las opciones, simplemente se asigna al elemento apuntado por p ( a[0]
) un valor constante. Vea la inversa de ella:
var = *p;
var sería asignada al valor 0 (contenido de a[0]), y p seguiría apuntando al mismo elemento.
¿Qué hubiera pasado, si en vez de ello se hubiera escrito?
var = *( p + 1 );
57
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Se podría traducir el sentido de la operación como: cargue var con el contenido del
elemento siguiente al apuntado por p ( a[1] ). Lo interesante de remarcar acá es que p, en sí
mismo, NO VARIA Y LUEGO DE ESTA SENTENCIA SEGUIRA APUNTANDO A
a[0]. De la misma forma: var = *( p + 3 ) asignará 30 a var, sin modificar el contenido de p
En cambio la expresión:
var = *( p++ );
Poder leerla como: asigna el valor de lo apuntado por p y LUEGO incrementa éste para que
apunte al próximo elemento. Así en var quedaría 0 (valor de a[0] ) y p apuntaría finalmente
a a[1]. Si en vez de esto hubiera preincrementado a p tendría:
var = *( ++p );
la que puede leerse como: apunte con p al próximo elemento y asigne a var con el valor de
éste. En este caso var sería igualada a 10 ( a[1] ) y p quedaría apuntando al mismo. En las
dos operaciones anteriores los paréntesis son superfluos ya que al analizarse los operadores
de derecha a izquierda, daría lo mismo escribir:
La aritmética más frecuentemente usada con punteros son las sencillas operaciones de
asignación, incremento o decremento y diferenciación. Todo otro tipo de aritmética con
ellos está prohibido o es de uso peligroso o poco transportable. Por ejemplo no está
permitido, sumar, restar, dividir, multiplicar, etc, dos apuntadores entre sí. Lo cual es
bastante lógico, ya que de nada me serviría sumar dos direcciones de memoria, por
ejemplo.
Otras operaciones están permitidas, como la comparación de dos punteros, por ejemplo (
punt1 == punt2 ) o ( punt1 < punt2 ) sin embargo este tipo de operaciones son
potencialmente peligrosas, ya que con algunos modelos de pointers pueden funcionar
correctamente y con otros no.
El ámbito o existencia de las variables, la menos duradera de ellas era la del tipo local a una
función, ya que nacía y moría con ésta. Sin embargo, esto es algo relativo, en cuanto a la
función main(), ya que sus variables locales ocuparán memoria durante toda la ejecución
del programa.
Para un caso típico, se debe recibir una serie de datos de entrada, del tipo double, y
procesar según un determinado algoritmo a aquellos que aparecen una o más veces con el
mismo valor.
Si no se está seguro de cuántos datos van a ingresar a nuestro programa, póngase alguna
limitación, suficientemente grande a los efectos de la precisión requerida por el problema,
diga 5000 valores como máximo, debe definir entonces un array de doubles capaz de
58
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
albergar a cinco mil de ellos, por lo que el mismo ocupará del orden de los 40 k de
memoria.
Si se define este array en main(), ese espacio de memoria permanecerá ocupado hasta el fin
del programa, aunque luego de aplicarle el algoritmo de cálculo ya no se le necesite más,
comprometiendo seriamente la disponibilidad de memoria para albergar a otras variables.
Una solución posible sería definirlo en una función llamada por main() que se ocupará de
llenar el array con los datos, procesarlos y finalmente devolviera algún tipo de resultado,
borrando con su retorno a la masiva variable de la memoria.
Sin embargo en C existe una forma más racional de utilizar los recursos de memoria de
manera conservadora. Los programas ejecutables creados con estos compiladores dividen la
memoria disponible en varios segmentos, uno para el código ( en lenguaje máquina ), otro
para albergar las variables globales, otro para el stack ( a través del cual se pasan
argumentos y donde residen las variables locales ) y finalmente un último segmento
llamado memoria de apilamiento o amontonamiento ( Heap ).
El Heap es la zona destinada a albergar a las variables dinámicas, es decir aquellas que
crecen ( en el sentido de ocupación de memoria ) y decrecen a lo largo del programa,
pudiéndose crear y desaparecer (desalojando la memoria que ocupaban) en cualquier
momento de la ejecución
Vea cual sería la metodología para crearlas; suponga primero que quiere ubicar un único
dato en el Heap, se define primero un puntero al tipo de la variable deseada:
double *p;
Notar que esta declaración no crea lugar para la variable, sino que asigna un lugar en la
memoria para que posteriormente se guarde ahí la dirección de aquella. Para reservar una
cantidad dada de bytes en el Heap, se efectúa una llamada a alguna de las funciones de
librería, dedicadas al manejo del mismo. La más tradicional es malloc() ( su nombre deriva
de memory allocation ), a esta función se le da como argumento la cantidad de bytes que se
quiere reservar, y nos devuelve un pointer apuntando a la primer posición de la "pila"
reservada. En caso que la función falle en su cometido ( el Heap está lleno ) devolverá un
puntero inicializado con NULL.
p = malloc(8);
Como es algo engorroso recordar el tamaño de cada tipo variable, agravado por el hecho de
que, si reserva memoria de esta forma, el programa no se ejecutará correctamente, si es
compilado con otro compilador que asigne una cantidad distinta de bytes a dicha variable,
es más usual utilizar sizeof, para indicar la cantidad de bytes requerida:
p = malloc( sizeof(double) );
59
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
En caso de haber hecho previamente un uso intensivo del Heap, se debería averiguar si la
reserva de lugar fue exitosa:
if( p == NULL )
rutina_de_error();
Si no lo fue estas sentencias me derivan a la ejecución de una rutina de error que tomará
cuenta de este caso. Por supuesto podría combinar ambas operaciones en una sola,
Si ahora quisiera guardar en el Heap el resultado de alguna operación, sería tan directo
como,
*p = a * ( b + 37 );
|var = *p;
No hay gran diferencia entre el trato de punteros a arrays, y a strings, ya que estos dos son
entidades de la misma clase. Sin embargo analice algunas particularidades. Así como
inicializa un string con un grupo de caracteres terminados en '\0', pode asignar al mismo un
puntero:
Esta operación no implica haber copiado el texto, sino sólo que a p se le ha asignado la
dirección de memoria donde reside la "E" del texto. A partir de ello pode manejar a p como
lo he hecho hasta ahora. Véase el ejemplo siguiente:
#include <stdio.h>
#define TEXTO1 "¿ Hola, como "
#define TEXTO2 "le va a Ud. ?
main()
{
char palabra[20], *p;
int i;
p = TEXTO1;
60
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Se definen primero dos strings constantes TEXTO1 y TEXTO2, luego se asigna al puntero
p la dirección del primero, y seguidamente en el FOR copia el contenido de éste en el array
palabra, observe que dicha operación termina cuando el contenido de lo apuntado por p es
el terminador del string, luego asigna a p la dirección de TEXTO2 y finalmente se
imprimen ambos strings, obteniendo una salida del tipo: " ¿Hola, como le va a UD?
(espero que bien).
Hay que reconocer que esto se podría haber escrito más compacto, si hubiera recordado que
palabra también es un puntero y NULL es cero, así se puede poner en vez del FOR.
Véase que aquí se ha agregado muy poco a lo ya ha aprendido, sin embargo hay un tipo de
error muy frecuente, que se puede analizar, en el EJEMPLO siguiente:
¿Algún problema ?.
( CON ERRORES )
#include <stdio.h>
char *p, palabra[20];
printf("Escriba su nombre: ");
scanf("%s", p );
palabra = "¿ Cómo le va ";
printf("%s%s", palabra, p );
}
Pues hay dos errores, a falta de uno, el primero ya fue analizado antes, la expresión
scanf("%s", p ) es correcta pero, el error implícito es no haber inicializado al puntero p, el
cual sólo fue definido, pero aun no apunta a ningún lado válido. El segundo error está dado
por la expresión: palabra = " ¿Cómo le va "; ( también visto anteriormente ) ya que el
nombre del array es una constante y no puede ser asignado a otro valor.¿Cómo se escribiría
para que funcione correctamente ?
(CORRECTO)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *p, palabra[20];
p = (char *)malloc(sizeof(char)128);
printf("Escriba su nombre: ");
scanf("%s", p );
61
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
( CORRECTO )
#include <stdio.h>
main()
{
char p[20], *palabra;
printf("Escriba su nombre: ");
scanf("%s", p );
palabra = "¿ Como le va ";
printf("%s%s", palabra, p );
}
Obsérvese, que es idéntico al primero, con la salvedad que se han invertido las
declaraciones de las variables, ahora el puntero es palabra y el array es p. Ambas soluciones
son equivalentes y dependerá del resto del programa, cual es la mejor elección.
Es una práctica muy habitual, sobre todo cuando se tiene que tratar con strings de distinta
longitud, generar array cuyos elementos son punteros, que albergarán las direcciones de
dichos strings.
Conciba a un puntero como una flecha, un array de ellos equivaldría a un carcaj indio lleno
de aquellas. Así como:
char *flecha;
definía a un puntero a un caracter, la definición
char *carcaj[5];
implica un array de 5 punteros a caracteres.
62
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Los arrays de punteros pueden ser inicializados de la misma forma que un array común, es
decir dando los valores de sus elementos, durante su definición, por ejemplo si se quisiera
tener un array donde el subíndice de los elementos coincidiera con el nombre de los días de
la semana, podría escribir:
char *dias[] = {
"número de día no válido",
"lunes" ,
"martes" ,
"miercoles" ,
"jueves" ,
"viernes" ,
"sabado" ,
"por fin es domingo"
}
Igual que antes, no es necesario en este caso indicar la cantidad de elementos, ya que el
compilador los calcula por la cantidad de términos dados en la inicialización. Así el
elemento dias[0] será un puntero con la dirección del primer string, dias[1], la del segundo,
etc.
63
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
64
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CAPÍTULO 8
INSTRUCCIONES DE ENTRADA Y SALIDA
Este capítulo es el colofón de este módulo y trata el tema de entradas y salidas en forma
física de los datos y las señales que serán empleadas en el control del robot tipo SCARA de
este curso.
Estas instrucciones de entrada y salida son hechas por medio de funciones creadas por el
lenguaje y son usualmente poco utilizadas en aplicaciones generales, sin embargo, en este
curso son muy importantes, se emplearán durante todo el módulo siguiente para darle vida
al robot mencionado.
Todos los tópicos tratados en los capítulos anteriores serán empleados en las practicas de
este capítulo.
Objetivo particular 8:
Para poder mandar datos a los puertos de la computadora personal, existen diversas
instrucciones dentro del lenguaje “C”, como son las siguientes:
Declaración:
Observaciones:
Las instrucciones inp y inpw son macros que leen del puerto de entrada especificado por
portid.
Las instrucciones outp y outpw son macros que escriben a la salida del puerto especificado
por portid.
65
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Valor de Retorno:
Para poder manipular los bits de los puertos de entrada y salida, usaremos la estructura
normal de programación de C.
Primero se verá el manejo de las instrucciones inp y outp, para el caso de leer un puerto y
sacar un dato por un puerto de salida.
Para lograr acceder a los puertos de la tarjeta Kentac que va en uno de los “slot” de la PC,
es necesario que dentro del programa se inicialice la función que tendrán cada uno de ellos
(puerto de entrada o de salida).
Por ejemplo para el caso de nuestra tarjeta de visualización la cual esta preparada para dos
puertos de salida por medio de LED’s y un puerto de entrada a través de interruptores, se
tiene la necesidad de programar los “chips” 8255 de esta manera, de salida o de entrada.
Haciendo referencia a las características de la tarjeta kentac, tenemos que los puertos de la
tarjeta de visualización están de la siguiente manera:
Puerto 300H (PA1) equivale a usar el Puerto F9 (Para el módulo kentac 846 )
Puerto 302H (PB1) equivale a usar el Puerto FC (En la tarjeta de visualización)
Puerto 308H (PA2) equivale a usar el Puerto FD ( “ )
Puerto 304H (PC1) equivale a usar el Puerto FE ( “ )
De la tabla 1, del mapa de puertos de E/S, se tiene que la dirección de la palabras de control
son 306H (CW1) y 30EH (CW2).
D7 D6 D5 D4 D3 D2 D1 D0 CW
1 0 0 1 0 0 1 0 92
S.Modo Modo 00 PA PC Al. Modo 0 PB (FC) PC Ba.
(F9) (FE) (FE)
En los puertos:
1 = Entrada
0 = Salida
66
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
D7 D6 D5 D4 D3 D2 D1 D0 C.W
1 0 0 0 0 0 0 0 80
S.Modo Modo PA (FD) PCH M PB PCL
En los puertos:
1 = Entrada
0 = Salida
67
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
68
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
CONCLUSIONES
Este texto busca mostrar en forma muy resumida los elementos para hacer programación de
un sistema de robot a lazo semiabierto, la idea principal es contar con los elementos que un
programa de control requiere. Esto significa tener los elementos de sintaxis necesarios para
realizar una codificación en forma secuencial de aspectos de cinemática de robots,
específicamente del robot SCARA.
Los elementos mostrados de programación pueden ser implementados para realizar las
tareas de control a lazo cerrado de un sistema, para el siguiente módulo se mostrará la
forma de programar un sistema de control moderno mediante lenguaje C, el cual puede ser
el pilar de futuras implementaciones en este aspecto.
Llegar a un completo dominio de todos las funciones del lenguaje es altamente complejo en
un curso de tan corta duración, sin embargo, se cuenta con todos los aspectos mínimos
básicos que permiten de manera autodidacta el manejo de este gran volumen de
información que es el propio lenguaje.
El compilador de este lenguaje cuenta con multiples ayudas y ejemplos que facilitan la
utilización de las funciones y su sintaxis. Es por esta razón que esta información omite
algunas de estas referencias ya que acostumbra al usuario a utilizar de forma más ágil el
programa de compilación.
69
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
BIBLIOGRAFÍA
Aitken y Jones
Aprendiendo C en 21 Días
Prentice Hall
Herbert Shieldt
Introducción a la Programación de C
McGraw Hill
Kernigan
Lenguaje de programación C
Prentice Hall
Borland
Turbo C++ 3.0,
User´s Guide
70
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
ANEXO A
71
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Practica 1
/**********************************************************************************/
/****** PROGRAMA 1 INICIO DE LA PROGRAMACION EN C ******/
/*********************************************************************************/
#include<conio.h>
#include<stdio.h>
void main(void)
{
clrscr();
printf("HOLA MUNDO");
getch();
}
Práctica 2
/***********************************************************************************/
/****** PROGRAMA 2 INICIO DE LA PROGRAMACION EN C ******/
/*********************************************************************************/
#include<conio.h>
#include<stdio.h>
void main(void)
{
float temp_far,temp_cen;
clrscr();
printf("INTRODUZCA EL VALOR DE LA TEMPERATURA EN GRADOS
FAHRENHEIT:\n");
scanf("%f",&temp_far);
temp_cen=(temp_far-32)*5/9;
printf("\nLA TEMPERATURA EN GRADOS CENTRIGRADOS ES: %f",temp_cen);
getch();
}
72
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Práctica 3
/***********************************************************************************************/
/****** PROGRAMA 3 USO DE OPERADORES Y CONDICIONALES EN C ******/
/**********************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<math.h>
void main(void)
{
float a,b,c,x1,x2,im_x,root,deno;
clrscr();
printf("CALCULO DE RAICES DE ECUACION DE 2ø GRADO\n\n\n");
printf("ax2+bx+c=0\n\n\n");
printf("INTRODUZCA LA CONSTANTE a= ");
scanf("%f",&a);
printf("INTRODUZCA LA CONSTANTE b= ");
scanf("%f",&b);
printf("INTRODUZCA LA CONSTANTE c= ");
scanf("%f",&c);
root=b*b-4*a*c;
deno=2*a;
if(deno==0){
printf("\n\n\n ERROR AL INTRODUCIR LOS DATOS");
getch();
exit(1);
};
if(root<0){
root=fabs(root);
printf("\n\n LA SOLUCION ES:\n\n");
x1=-b/2*a; im_x=sqrt(root)/2*a;
printf("x1=%f %f i\n",x1,im_x);
printf("x2=%f %f i\n",x1,-im_x);
getch();
exit(1);
};
printf("\n\n LA SOLUCION ES:\n\n");
x1=(-b+sqrt(root))/deno;
x2=(-b-sqrt(root))/deno;
printf("x1=%f\n",x1);
printf("x2=%f\n",x2);
getch();
}
73
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Práctica 4
Emplear el manejo de un bucle (loop) para realizar una operación iterativa como
es el factorial de un numero entero
/***********************************************************/
/******* PROGRAMA 4 USO DE BUCLES 1 *******/
/***********************************************************/
#include<conio.h>
#include<stdio.h>
#include<math.h>
void main(void)
{
float fact=1;
int n;
clrscr();
printf("CALCULO DEL FACTORIAL\n\n\n");
do{
fact=fact*n;
n=n-1;
}while(n>1);
printf("ES= %f",fact);
getch();
}
74
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Practica 5
/****************************************************************************************/
/******* PROGRAMA 5 USO DE VECTORES UNIDIMENSIONALES *******/
/****************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define no_items 5
void main(void)
{
float num[no_items],no_max;
int i;
clrscr();
printf("\n\n\n");
for(i=0;i<no_items;i++)
{
printf("INTRODUZCA NUMERO %d = ",i+1);
scanf("%f",&num[i]);
}
no_max=num[0];
for(i=1;i<no_items;i++)
{
if(no_max<num[i])no_max=num[i];
}
75
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Práctica 6
/*************************************************************************/
/******* PROGRAMA 6 USO DE BUCLES 3 *******/
/******* MULTIPLICACION DE MATRICES *******/
/************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define R1 4
#define C1 6
#define R2 6
#define C2 2
void main(void)
{
float A[R1][C1]={
{5,6,1,2,8,2},
{4,2,8,5,9,1},
{8,5,4,6,4,0},
{7,9,5,8,6,1},
};
float B[R2][C2]={
{8,5},
{4,2},
{7,9},
{4,5},
{3,2},
{1,7},
};
float C[R1][C2];
float prod=0;
int i,j,k;
clrscr();
printf("\n\n\n");
for(i=0;i<R2;i++)
76
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
{
for(k=0;k<C2;k++)
{
prod=0;
for(j=0;j<C1;j++)
{
prod=prod+A[i][j]*B[j][k];
}C[i][k]=prod;
}
}
for(i=0;i<R1;i++)
{
for(j=0;j<C2;j++)
{
printf(" %f ",C[i][j]);
}
printf("\n");
}
getch();
}
77
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Práctica 7
Realizar un programa para tomar decisiones entre dos alternativas dadas desde el
teclado, incrementar un número con flecha arriba, decrementarlo con flecha abajo,
todo esto con una saturación inferior y superior de +127 a –128, el número es
representado por la variable num de tipo char.
/*********************************************************/
/******* PROGRAMA 7 USO DE SWITCH *******/
/*********************************************************/
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define ESC 27
#define ENTER 13
#define UP_ARROW 72
#define DW_ARROW 80
#define LEFT_ARROW 75
#define RIGHT_ARROW 77
#define F1 59
#define F2 60
#define F3 61
#define F4 62
#define F5 63
#define F6 64
#define F7 65
#define F8 66
#define F9 67
#define F10 68
void main(void)
{
char tecla,num=0;
clrscr();
do{ gotoxy(10,10);
printf("num= %d ",num);
tecla=getch();
if(!tecla){
tecla=getch();
switch(tecla)
{
case UP_ARROW:{ if(num<127)num++;
else num=127;
break;
}
case DW_ARROW:{ if(num>-128)num--;
else num=-128;
78
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
break;
}
default: break;
}
}
}while(tecla!=ESC);
}
Practica 8
/***********************************************************************/
/******* PROGRAMA 8 USO DE APUNTADORES *******/
/***********************************************************************/
#include<conio.h>
#include<stdio.h>
void main(void)
{
int *p;
int x=0,i=0;
p=&x;
printf("EL VALOR APUNTADO ES: %d",*p);
getch();
79
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Práctica 9
/***********************************************************************/
/******* PROGRAMA 9 USO DE APUNTADORES 2 *******/
/***********************************************************************/
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define Pi 3.1416
void main(void)
{
float *p;
float teta=0,teta_rad=0,z[1000];
int i=0;
for(i=0;teta<360;i++)
{
teta_rad=teta*Pi/180;
z[i]=sin(teta_rad);
teta++;
}
p=&z[0];
for(i=0;i<360;i++)
{
printf("z[%d]=%f\n",i,*p);
p++;
}
getch();
80
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
Práctica 10
Utilizar a los apuntadores como variables que emplea una función y pueden ser
empleados en la función principal. Dibujar en modo gráfico un cuadro que tiene como
dimensiones las coordenadas apuntadas por el mouse de la computadora y salir en el
momento que esas coordenadas sean parte del cuadro.
/***********************************************************************/
/******* PROGRAMA 10 USO DE APUNTADORES 3 *******/
/***********************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
#include<math.h>
#include<graphics.h>
#define Pi 3.1416
#define ESC 27
void main(void)
{
char tecla=0;
int px=0,py=0,x1,x2,y1,y2,x1_old=0,x2_old=0,y1_old=0,y2_old=0;
int xmax,ymax;
initgr();
mouse_reset();
cursor_on();
set_mouse_position(0,0);
xmax=getmaxx();
ymax=getmaxy();
x1=xmax/2-10;
y1=ymax/2-10;
x2=xmax/2+10;
y2=ymax/2+10;
do{
mouse_position(&px,&py);
setcolor(BLACK);
rectangle(x1_old,y1_old,x2_old,y2_old);
setcolor(YELLOW);
rectangle(x1-px,y1-py,x2+px,y2+py);
x1_old=x1-px;
81
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
y1_old=y1-py;
x2_old=x2+px;
y2_old=y2+py;
gotoxy(2,2);
printf("x=%d y=%d ",px,py);
delay(15);
if(x1_old<px && y1_old<py)tecla=ESC;
}while(tecla!=ESC);
cursor_off();
mouse_reset();
closegraph();
clrscr();
}
initgr()
{
int gdriver = DETECT,gmode, errorcode;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
errorcode = graphresult();
if (errorcode != grOk)
{
clrscr();
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
mouse_reset()
{
union REGS r;
r.x.ax=0; /* reset al mouse */
int86(0x33,&r,&r);
if((int) r.x.ax !=-1)
{
closegraph();
printf("hardware or software del mouse no esta instalado");
getch();
exit(1);
}
if(r.x.bx !=3)
{
closegraph();
printf("Se require mouse de dos botones");
getch();
82
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
exit(1);
}
}
cursor_off()
{
union REGS r;
r.x.ax = 2; /* Remover el cursor del mouse */
int86(0x33,&r,&r);
}
cursor_on()
{
union REGS r;
r.x.ax = 1; /* Mostrar el cursor del mouse */
int86(0x33,&r,&r);
}
{
union REGS r;
rightb_pressed(void)
{
union REGS r;
r.x.ax = 3; /* lee posicion y estatus del boton */
int86(0x33,&r,&r);
return r.x.bx & 2;
}
leftb_pressed(void)
{
83
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
union REGS r;
r.x.ax = 3; /* lee posicion y estatus del boton */
int86(0x33,&r,&r);
return r.x.bx & 1;
}
set_mouse_position(int x,int y)
{
union REGS r;
84
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
ANEXO B
85
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
/********************************************************************************************/
/**** PROGRAMA 1 ACTIVACIÓN DE PUERTOS DE SALIDA ****/
/**** PROGRAMA TOGGLE.C ****/
/**** ELABORADO POR EL ING. RICARDO BAUTISTA QUINTERO ****/
/**** FECHA: 15-AGOSTO-1999 ****/
/******************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
void main(void)
{
char data=0;
init_ppi();
clrscr();
do{
outp(fe,data);
gotoxy(10,10);
printf("EL DATO ES: %x",data);
data=data^0x01;
delay(unseg);
}while(!kbhit());
init_ppi()
{
outp(CW1,0X82);
outp(CW2,0X80);
}
86
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
/*************************************************************************************************/
/**** PROGRAMA 4 LEE UN BIT ESPECIFICO DEL PUERTO DE ENTRADA ****/
/**** ELABORADO POR EL ING. RICARDO BAUTISTA QUINTERO ***/
/**** FECHA: 16-AGOSTO-1999 ****/
/************************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
void main(void)
{
unsigned char dummy=0,flag=0;
void init_ppi();
clrscr();
do{ gotoxy(10,10);
dummy=inp(fc);
dummy=dummy&Bit1;
if(dummy){flag=1;printf("EL BIT n ESTA ACTIVADO: flag=%X",flag);}
else {flag=0;printf("EL BIT n ESTA INACTIVO: flag=%X",flag); }
}while(!kbhit());
}
void init_ppi(void)
{
outp(CW1,0X92);
outp(CW2,0X80);
}
87
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
/***********************************************************************************************/
/**** PROGRAMA 3 PONE A UNO UN BIT ESPECIFICADO ****/
/**** POR EL PUERTO DE SALIDA ****/
/**** PROGRAMA TURN_ON.C ****/
/**** ELABORADO POR EL ING. RICARDO BAUTISTA QUINTERO ****/
/**** FECHA: 17-AGOSTO-1999 ****/
/*********************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
void main(void)
{
unsigned char dummy=0;
void init_ppi();
clrscr();
gotoxy(10,10);
dummy=inp(fe);
printf("DUMMY ANTERIOR ES: %X",dummy);
dummy=dummy|Bit0;
outp(fe,dummy);
gotoxy(10,11);
printf("DUMMY ACUAL ES: %X",dummy);
getch();
void init_ppi(void)
{
outp(CW1,0X82);
outp(CW2,0X80);
}
88
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
/***************************************************************************************************/
/**** PROGRAMA 4 PONE A CERO UN BIT ESPECIFICADO POR EL PUERTO *****/
/**** DE SALIDA *****/
/**** ELABORADO POR EL ING. RICARDO BAUTISTA QUINTERO ****/
/**** FECHA: 18-AGOSTO-1999 ****/
/***************************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
void main(void)
{
unsigned char dummy=0;
void init_ppi();
clrscr();
gotoxy(10,10);
dummy=inp(fc);
printf("DUMMY ANTERIOR ES: %X",dummy);
dummy=dummy&~Bit0;
outp(fc,dummy);
gotoxy(10,11);
printf("DUMMY ACUAL ES: %X",dummy);
getch();
}
void init_ppi(void)
{
outp(CW1,0X82);
outp(CW2,0X80);
}
89
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
/*****************************************************************************************/
/**** PROGRAMA 5 INTEGRACION DE PROGRAMAS TURN_ON, ***/
/**** TURN_OFF Y TEST_BIT ****/
/**** PROGRAMA OUTIN.C ****/
/**** ELABORADO POR EL ING. RICARDO BAUTISTA QUINTERO ****/
/**** FECHA: 19-AGOSTO-1999 ****/
/***************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
void main(void)
{
unsigned char dummy=0,flag=0;
void init_ppi();
clrscr();
do{
if(test_bit(fc,bit0))turn_on(fe,actuador1);
if(test_bit(fc,bit1))turn_off(fe,actuador1);
}while(!kbhit());
void init_ppi(void)
{
outp(CW1,0x82);
outp(CW2,0x80);
}
90
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
dummy=inp(port);
dummy=dummy&mask;
if(dummy)flag=1;
else flag=0;
return flag;
}
91
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
/********************************************************************************************/
/** PROGRAMA 6 PROGRAMACIÓN DE UNA FUNCIÓN A TIEMPO REAL ***/
/**** PROGRAMA INTER1.C ***/
/**** ELABORADO POR EL ING. RICARDO BAUTISTA QUINTERO ****/
/**** FECHA: 20-AGOS-1999 ****/
/*******************************************************************************************/
#include<conio.h>
#include<stdio.h>
#include<dos.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include "c:\tc\user\icord.h" /* Header file */
#include "c:\tc\user\icord.c"
char Data_Task1=0,Data_Task2=0;
void main(void)
{
int cmd; /* Bandera para iniciar o no el programa */
double clock = 1; /* Intervalo de base de tiempo (1 milisec) */
int stimeTask1 = 1000; /* No. de veces que se ejecuta Base de tiempo */
int stimeTask2 = 2; /* No de veces de ejecucion de task1 */
92
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo
Centro Nacional de Actualización Docente Mecatronica
Quinto curso internacional de ingeniería mecatrónica
show_leds()
{
do
{
gotoxy(10,10);
printf("Data Task1=%x",Data_Task1);
gotoxy(10,11);
printf("Data Task2=%x",Data_Task2);
}while(!kbhit());
outp(Puerto_out,0x00);
}
/********************************************************************/
/**** FUNCION DE INTERRUPCION TASK1 y TASK2 ***/
/********************************************************************/
void task1(void)
{
enable(); /*Habilita interrupcion*/
Data_Task1=Data_Task1^0x01;
outp(Puerto_out,Data_Task1);
return;
}
void task2(void)
{
enable(); /* Habilita interrupcion */
Data_Task2=Data_Task2^0x02;
outp(Puerto_out,Data_Task2);
return;
}
void taskErr(void)
{
printf("\nTIME OUT (taskErr) !!%c %d \n", 0x07, getErrcode());
exit(0); /*Se sale al existir translape en interrupcion*/
}
93
MODULO V Programación en lenguaje c para control M. en C. Bautista Quintero Ricardo