Вы находитесь на странице: 1из 118

MANUAL DE PRÁCTICAS DE

PROGRAMACIÓN.
Facultad de Ciencias de la Electrónica.
2016
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Para los alumnos de la Facultad de Ciencias de la Electrónica de la


BUAP.

“No quiero caminar entre locos, dijo Alicia. Oh, no puedes hacer
nada, le respondió el gato, todos estamos locos aquí”
-Lewis Carroll

1
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Contenido
1. Prólogo ............................................................................................................................ 3
2. Introducción: Comunicación USB .................................................................................. 6
3. Práctica 0: Funciones básicas del microcontrolador ....................................................... 8
4. Practica 1: Operaciones bit a bit .................................................................................... 11
5. Práctica 2: Sentencia IF-ELSE ...................................................................................... 14
6. Práctica 3.1: Ciclo FOR................................................................................................. 17
7. Práctica 3.2: Ciclo WHILE............................................................................................ 19
8. Práctica 4: SWITCH-CASE .......................................................................................... 22
9. Práctica 5.1 : Arreglo unidimensional ........................................................................... 25
10. Práctica 5.2: Arreglo unidimensional de temperaturas ................................................. 28
11. Práctica 6: Cadena de caracteres ................................................................................... 31
12. Práctica 7. Matriz de temperaturas ................................................................................ 34
13. Práctica 8.1: Funciones vacías....................................................................................... 38
14. Práctica 8.2 Funciones tipo entero con parámetros ....................................................... 42
15. Práctica 8.3 Matriz de LEDS multiplexada ................................................................... 45
16. Práctica 9.1. Apuntadores con arreglos unidimensionales. .......................................... 49
17. Práctica 9.2. Apuntadores con arreglos bidimensionales. ............................................ 52
18. Práctica 10. Estructuras ................................................................................................ 56
19. Práctica 11. Memoria dinámica .................................................................................... 62
20. Práctica 12. Archivos ................................................................................................... 65
Apéndice A. Circuito y Tarjetas de desarrollo ..................................................................... 69
Apéndice B. Bits de configuración (PCWHD) ..................................................................... 75
Apéndice C. Código del Microcontrolador (PCWHD). ....................................................... 77
Apéndice D. Programador del microcontrolador ................................................................. 88
Apéndice F. Compilador para el microcontrolador (PIC C) ................................................ 89
Apéndice G. Periféricos del microcontrolador y dispositivos externos. .............................. 94
Apéndice H. Circuitos adicionales ..................................................................................... 101
Apéndice I. Biblioteca de comunicación ............................................................................ 103
Apéndice J. Instalación de Drivers ..................................................................................... 106

2
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

1. Prólogo
Este manual fue desarrollado con la finalidad de facilitar la comprensión de los conceptos
más importantes en programación estructurada a los alumnos que cursen la materia de
programación, realizando prácticas aplicadas al manejo de un microcontrolador PIC
18F4550.
Se sugiere además tres formas diferentes de ocupar el PIC antes mencionado, adquiriendo la
tarjeta ATA-NQH 0714, la tarjeta Miuva de la empresa INTESC o adquirir los componentes
necesarios para hacer funcionar el PIC por separado y armar el circuito. De cualquier forma
la comunicación se debe lograr satisfactoriamente.
La estructura del manual consiste en las siguientes secciones:
 Introducción. Describe detalladamente los requerimientos para lograr la
comunicación, lo que incluye la instalación de los drivers y la configuración del
programa a utilizar.
 Prácticas. En esta sección se describe los objetivos de la práctica, un breve marco
teórico con la finalidad de recordad al alumno el manejo de los temas a ocupar, el
algoritmo en pseudocódigo él cual se pide realizar y finalmente algunas prácticas
mencionan pequeños consejos, a manera de información adicional, que pueden
facilitar al alumno algunas cuestiones de programación.
 Apéndices. Se menciona información que no es primordial para la realización de las
prácticas, sin embargo puede ser de utilidad para el alumno que desea más
información sobre la programación enfocada a PICs. Estos apéndices muestran las
diferencias entre las dos tarjetas ocupadas para el desarrollo de este manual, los
códigos implementados en el microcontrolador, los programas necesarios para
desarrollar y cargar un código en dicho microcontrolador, los periféricos adicionales
que tienen en particular el PIC 18F4550 y algunos circuitos adicionales
recomendados.

Finalmente es necesario aclarar que algunos pseudocódigos (principalmente los


pseudocódigos de las últimas prácticas) combinan instrucciones propias del lenguaje de
programación C con la única finalidad de aclarar tipos de datos o funciones en particular.
Esto permitirá al alumno distinguir entre diferentes tipos de datos, apuntadores, estructuras
y enumeraciones.
Los alumnos que deseen contribuir al desarrollo de actualizaciones o simplemente deseen
hacer un comentario sobre este manual pueden escribir al correo:
carlos.arrietaf@alumno.buap.mx

3
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Objetivos
Se muestra a continuación el objetivo de cada práctica, el cual muestra el propósito de ésta y
el programa que se requiere.
 Práctica 0. Establecer la comunicación a través de un programa que encienda y
apague un LED, lea del convertidor analógico-digital un dato (que puede variar por
medio de un potenciómetro) y finalmente lea el estado del botón pulsador conectado
a E0 o C0 según la configuración que se ocupe del circuito.
 Práctica 1. Entender el funcionamiento de las operaciones bit a bit en programación
y comprobar dicho funcionamiento con un programa que lea los datos en el puerto B
y D, muestre su valor en decimal, octal y hexadecimal y que realice las operaciones
AND, OR, corrimiento a la derecha y corrimiento a la izquierda, mostrando el
resultado.
 Práctica 2. Entender el funcionamiento de la sentencia IF ELSE en programación y
comprobar dicho funcionamiento con un programa que simule un “semáforo manual”
el cual según la letra prenda el LED del color correspondiente.
 Práctica 3.1. Entender el funcionamiento del ciclo FOR en programación y
comprobar dicho funcionamiento con un programa que pregunte el número de veces
que se quiere hacer parpadear un LED.
 Práctica 3.2. Entender el funcionamiento del ciclo WHILE en programación y
comprobar dicho funcionamiento con un programa que haga parpadear un LED hasta
que se presione un botón pulsador. Además de identificar la función para la lectura
de datos.
 Práctica 4. Entender el funcionamiento de la sentencia SWITCH-CASE en
programación y comprobarlo con un programa que conste de:
a) Un programa menú que pregunte cual programa desea ejecutar.
b) Un subprograma que encienda 1 LED de acuerdo a su posición (sólo 1 a la vez).
c) Un subprograma que haga una secuencia de LEDS continua, la cual consista en
prender el LED consecutivo (prender sólo el LED 0, luego sólo el LED 1 así hasta
prender los 8 LEDS).
 Práctica 5.1 Entender el funcionamiento de un arreglo unidimensional y como
acceder a cada variable dentro del arreglo. Además crear un programa que mande al
microcontrolador los datos contenidos en el arreglo de tipo entero para encender 8
LEDS según su equivalente binario.
 Práctica 5.2 Crear un programa que obtenga varias mediciones de temperatura y las
ordene en un arreglo unidimensional, además que calcule el promedio de todas estas
temperaturas.
 Práctica 6. Entender el funcionamiento de las cadenas de caracteres y como unir
varias cadenas en una sola. Comprobar dicho funcionamiento con un programa que
pida el nombre de la persona y que el programa conteste con un saludo y el nombre
ingresado. El dato debe mostrarse en el LCD.

4
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

 Práctica 7. Entender el funcionamiento de un arreglo bidimensional y como acceder


a cada variable dentro del arreglo. Crear un programa que obtenga datos del
convertidor analógico-digital conectado a un sensor de temperatura y que ordene
estos datos en un arreglo bidimensional separando las muestras según el día en que
fueron tomadas. Mostrar el promedio de las temperaturas, máximo y mínimo por día
y finalmente el promedio total de todas las temperaturas, máximo y mínimo de todas
las temperaturas sensadas.
 Práctica 8.1 Comprender la importancia de las funciones vacías en programación.
Comprobar dicho funcionamiento ocupando funciones vacías para organizar el
código de la práctica 4 (SWITCH-CASE).
 Práctica 8.2 Comprender la importancia de las funciones de tipo entero en
programación. Comprobar dicho funcionamiento ocupando funciones de tipo entero
para organizar el código de la práctica 1 (Operaciones bit a bit)
 Práctica 8.3 Entender la diferencia entre una variable global y local. Aplicar los
conocimientos adquiridos de funciones y arreglos de dos dimensiones para hacer un
programa que pregunte que LED se quiere prender de una matriz, imprimir en
pantalla un arreglo que represente la matriz de LEDS, mostrando un 1 en caso de que
el LED se quiera encender y un 0 en caso de que este apagado. Finalmente, mandar
los datos al microcontrolador para encender los LEDS que el usuario índico.
 Práctica 9.1. Entender el funcionamiento de un apuntador y el concepto de aritmética
de apuntadores aplicado a un arreglo unidimensional. Utilizar el programa de la
práctica 5.1 de arreglo unidimensional para mandar los valores al microcontrolador
por apuntadores. Mostrar los valores en el microcontrolador del primero al último y
después mostrarlos del último al primero.
 Práctica 9.2. Entender el funcionamiento de un apuntador y el concepto de aritmética
de apuntadores aplicado a un arreglo bidimensional. Utilizar el programa de la
práctica 7 de arreglo bidimensional para acceder indirectamente a los datos de la
matriz de temperatura.
 Práctica 10. Entender el funcionamiento de las estructuras en C y como acceder a sus
variables. Aplicar el concepto de estructuras y enumeración para desarrollar un
programa capaz de calcular el valor de una resistencia según los colores de sus franjas.
Ocupar el convertidor analógico-digital para leer el valor real de una resistencia
ocupando una resistencia de referencia de 10KΩ.
 Práctica 11. Entender el funcionamiento de la memoria dinámica en C. Utilizar el
programa de la práctica 5.2 de arreglo de temperaturas declarando el número de
mediciones durante la ejecución del programa.
 Práctica 12. Entender el manejo de archivos en C. Desarrollar un programa que lea
temperaturas de un archivo existente y cree un nuevo archivo leyendo las
temperaturas guardadas y nuevas lecturas con el sensor LM35. Utilizar el programa
de la práctica 5.2 de arreglo de temperaturas.

5
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

2. Introducción: Comunicación USB


Existen varias formas de hacer una conexión USB entre la computadora y un
microcontrolador PIC. La comunicación descrita en este manual se conoce como HID
(Dispositivo de interfaz humana). La comunicación será establecida con el programa
Microsoft Visual Studio (ocupando la versión Ultimate 2013 para el desarrollo de este
manual, aunque bien los protocolos y bibliotecas son compatibles con versiones anteriores,
como la 2010), usando lenguaje de programación C. Para lograr una comunicación exitosa
es necesario:
A. Direccionar correctamente los datos enviados de la computadora al microcontrolador,
es decir, tener en el microcontrolador el programa que interprete los datos recibidos.
Este código se encuentra descrito en el apéndice C.
B. El microcontrolador debe ser reconocido por la computadora como un dispositivo de
interfaz humana, es necesario instalar los drivers proporcionados para su correcto
funcionamiento. Cabe señalar que estos drivers se instalan en el puerto USB al que
fue conectado, por tanto se debe conectar siempre al puerto en donde se instalaron.
Los drivers se encuentran en la página de Microchip los cuales son compatibles con
Windows vista, 7, 8 y 10(La instalación de los drivers se encuentra descrita en el
apéndice J).
C. Una vez creado el proyecto en Visual Studio se deben copiar los archivos “USB.h”,
“usb2550.h”, “USB.cpp”, “usb2550.lib”, “Comunicación.h” y “usb2550.dll”a la
carpetas del mismo proyecto, dónde se encuentra el archivo .cpp del código fuente.
Las bibliotecas también fueron desarrolladas por la empresa Microchip, salvo la de
“Comunicación.h” la cual fue desarrollada con la finalidad de hacer más simple la
comunicación, ésta se encuentra brevemente explicada en el apéndice I.
D. Agregar los archivos “USB.h”, “usb2550.h”, “Comunicación.h” y “USB.cpp” desde
el programa como se muestra en la imagen. Los archivos de tipo .h deberán ser
agregados en archivos de cabecera (Header files), mientras que los de tipo .cpp
deberán estar en archivos fuente (Source files). Estas bibliotecas contienen las
funciones necesarias para mandar y recibir datos del microcontrolador.

Figura 1.1 Agregar archivos desde el explorador de soluciones

6
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

E. Se debe vincular además, la biblioteca “usb2550.lib”, para hacerlo se debe ir al menú


“Proyecto”, seleccionar la opción de “propiedades de (nombre de proyecto)”. Se
desplegará una ventana llamada “Pagina de propiedades de (nombre de proyecto)”.
Se despliega la opción “Propiedades de configuración”, se despliega “Vinculador” y
se selecciona la opción entrada. En la opción “Dependencias adicionales” se escribe
“usb2550.lib” como se muestra en la imagen.

Figura 1.2 Páginas de propiedades del proyecto.

F. Se debe incluir sólo la biblioteca “Comunicacion.h”1 en el código como se hace


normalmente en el orden mostrado a continuación, de lo contrario generará un error
de compilación.

Figura 1.3 Incluir bibiliotecas de comunicación

El archivo “usb2550.dll” se debe colocar en la carpeta “Debug”. Visual Studio crea 2 carpetas
“Debug”, el archivo debe ser colocado en donde se encuentra el ejecutable del programa.
Esta carpeta no aparece cuando se crea el proyecto, sólo aparecerá hasta que se compile el
proyecto.
Finalmente se debe mencionar que el programa (ya sea Visual Studio o en su defecto el
ejecutable del programa) debe ser ejecutado como administrador (esto se logra dando click
derecho en el ejecutable o en el icono del programa y seleccionando la opción de “Ejecutar
como administrador”), de lo contrario no se logrará la comunicación.

1
La biblioteca “Comunicacion.h” contiene las otras dos bibliotecas “USB.h” y “usb2550.h”, por lo que ya no
es necesario agregarlas al programa.

7
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

3. Práctica 0: Funciones básicas del microcontrolador


OBJETIVO
Establecer la comunicación a través de un programa que encienda y apague un LED,
lea del convertidor analógico-digital un dato (que puede variar por medio de un
potenciómetro) y finalmente lea el estado del botón pulsador conectado a E0 para la
tarjeta ATA-NQH 0714 o C0 para la tarjeta Miuva.

MATERIAL
 Microcontrolador PIC 18F45502
 1 LED
 1 Potenciómetro (preferentemente menor a 10KΩ)

MARCO TEÓRICO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y crear un
programa que:
1. Pida escribir al usuario un 1 para encender un LED.
2. Pida escribir al usuario un 0 para apagarlo.
3. Lea el dato analógico que controla el potenciómetro.
4. Lea el estado del botón (1 en caso de estar presionado y 0 en caso contrario).

En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más


avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

2
El circuito necesario para implementar el microcontrolador está descrito en el apéndice A

8
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

PSEUDOCÓDIGO
Programa: Comunicación USB
Inicio del programa
Imprime “Envíe un 1 para encender el LED”
Lee dato
Mandar paquete (LED, dato)
Imprime “Envíe un 0 para apagar el LED”
Lee dato
Mandar paquete (LED, dato)
Imprime “Se leerá el convertidor A/D”
Recibir paquete (ADC, datoadc1, datoadc2)
Dato = (corrimiento de 8 lugares a la izquierda de datoadc2) + datoadc1
Imprime dato
Imprime “Se leerá el estado del botón”
Recibir paquete (PB, dato)
Imprime dato
Fin del programa
La instrucción Mandar paquete (LED, dato) es una función descrita en la biblioteca
“Comunicación.h”, los dos datos dentro del paréntesis son parámetros, de los cuales el
primero habilita la opción de encender el LED conectado al pin E1, mientras que el segundo
manda el valor de tipo entero a este puerto, si el valor es 1, el LED encenderá, si es 0 se
apagará. La instrucción es la siguiente
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐿𝐸𝐷_𝑂𝑁, &𝑑𝑎𝑡𝑜);
Es necesario agregar el operador & antes del nombre de la variable, tal y como se hace con
la instrucción 𝑠𝑐𝑎𝑛𝑓 o 𝑝𝑟𝑖𝑛𝑡𝑓.

9
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

La instrucción Recibir paquete (ADC, datoadc1, datoadc2) esta descrita en la biblioteca


“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital3. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐1, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐2);
La instrucción Recibir paquete (PB, dato) es una función que permite leer el estado del botón
(conectado al pin C0 para la tarjeta Miuva o al pin E0 para la tarjeta ATA-NQH), devolviendo
el valor 1 en caso de que se encuentre presionado el botón o un 0 en caso contrario. La función
contiene dos parámetros, el primero le indica al microcontrolador que lea el estado del botón
pulsador y el segundo almacena el valor leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝐵_𝑂𝑁, &𝑑𝑎𝑡𝑜);
Información adicional.
Se muestra a continuación la conexión de un potenciómetro tanto en la tarjeta Miuva como
en la ATA-NQH sobre un protoboard.

Figura 3.1 Conexión de un potenciómetro en las tarjetas Miuva y ATA-NQH.

3
Este funcionamiento se explica a detalle en el apéndice G

10
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

4. Practica 1: Operaciones bit a bit


OBJETIVO
Entender las operaciones bit a bit (AND y OR) y las conversiones entre sistemas binario,
octal, decimal y hexadecimal.
Probar estos conceptos adquiriendo los datos en el puerto B y el puerto D, mostrando
sus equivalentes en los sistemas antes mencionados y aplicándoles operadores bit a bit.

MATERIAL
 Microcontrolador PIC 18F4550
 2 Interruptores DIP de 8 conexiones (Dip switch)
 16 resistencias de 1 KΩ
MARCO TEÓRICO
Cuando se adquiere un dato de un puerto completo (los 8 bits del puerto), este se interpreta
en el microcontrolador como un dato binario. Esto quiere decir que de acuerdo a la posición
del bit, su valor será diferente, siendo el pin 0 el bit menos significativo y el bit 7 el más
significativo. Se muestra en la figura 3.1 una tabla de los valores que el microcontrolador
interprete según la posición del bit.
Puerto(Bit 7 a Bit 0) Equivalente en sistema decimal
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8
0001 0000 16
0010 0000 32
0100 0000 64
1000 0000 128
Figura 3.1 Interpretación binaria según el dato decimal en el microcontrolador

En los casos particulares del puerto B y D, los bits más significativos son el B7 y D7, esto se
debe tomar en cuenta a la hora de conectar los interruptores. Se muestra en el apéndice H el
esquemático del circuito con los interruptores conectados al puerto D.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

11
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

PSEUDOCÓDIGO
Programa: Operación bit a bit con comunicación USB
Inicio del programa
Imprime “Programa que lee los datos del puerto B y D y hace operaciones a nivel bit”
Recibir paquete (Puerto B entrada, puerto B)
Recibir paquete (Puerto D entrada, puerto D)
Imprime “El valor en el puerto B es:” puerto B
Imprime “El valor en el puerto D es:” puerto D
Imprime “El valor en el puerto B es:” puerto B “en sistema octal”
Imprime “El valor en el puerto D es:” puerto D “en sistema octal”
Imprime “El valor en el puerto B es:” puerto B “en sistema hexadecimal”
Imprime “El valor en el puerto D es:” puerto D “en sistema hexadecimal”
Resultado = puerto B OR puerto D
Imprime “La operación OR entre ambos números en decimal es” resultado
Resultado = puerto B AND puerto D
Imprime “La operación AND entre ambos números en decimal es” resultado
Resultado = Corrimiento de 1 bit a la izquierda de puerto B
Imprime “El corrimiento de un bit a la izquierda de puerto B es Resultado”
Resultado = Corrimiento de 1bit a la derecha de puerto_B
Imprime “El corrimiento de un bit a la derecha de” puerto_B “es” Resultado
Fin del programa
La instrucción Recibir paquete (Puerto B entrada, puerto B) hace referencia a una función
descrita en la biblioteca “Comunicación.h”, los dos datos dentro del paréntesis son
parámetros, el primero habilita el puerto B como entrada, mientras que el segundo le indica
a la función dónde guardar el dato recibido, que en este caso es la variable puerto_B. La línea
de código correspondiente es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐵_𝐼𝑁𝑃𝑈𝑇, &𝑝𝑢𝑒𝑟𝑡𝑜𝐵);
Es necesario agregar el operador & antes del nombre de la variable, tal y como se hace con
la instrucción 𝑠𝑐𝑎𝑛𝑓.

12
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

De igual manera la instrucción Recibir paquete (Puerto D entrada, puerto D) hace


referencia a la misma función explicada anteriormente, con la diferencia de que los
parámetros cambian para que se habilite el puerto D como entrada y se almacene el dato en
el segundo parámetro, es decir, la variable puerto D. El código queda de la siguiente
manera:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝐼𝑁𝑃𝑈𝑇, &𝑝𝑢𝑒𝑟𝑡𝑜𝐷);
Información adicional.
Se muestra la conexión de los interruptores sobre un protoboard. En el diagrama sólo se
conectaron 4 pines con la finalidad de mostrar claramente la conexión, sin embargo es
necesario conectar todos los pines del puerto B y D

Figura 4.1 Conexión del interruptores al puerto B y D con la tarjeta Miuva.

Figura 4.2 Conexión del interruptores al puerto B y D con la tarjeta ATA-NQH.

13
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

5. Práctica 2: Sentencia IF-ELSE


OBJETIVOS
Entender el funcionamiento de la sentencia IF-ELSE en programación.
Comprobar dicho funcionamiento con un programa que simule un “semáforo manual”
el cual se encienda el LED del color correspondiente según la letra que se escriba.

MATERIAL
 Microcontrolador PIC 18F4550
 3 LEDS4 de color verde, amarillo y rojo.
MARCO TEÓRICO
Una de las funciones más básica en la programación es el de la toma de decisiones, es decir,
que se ejecuten diferentes instrucciones según una condición determinada. La función que
permite esta toma de decisiones es la sentencia IF-ELSE. La sintaxis de esta función es:
𝑖𝑓(𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛){𝑐ó𝑑𝑖𝑔𝑜1; }
𝑒𝑙𝑠𝑒 𝑖𝑓(𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛2){𝑐ó𝑑𝑖𝑔𝑜2; }
𝑒𝑙𝑠𝑒{𝑐ó𝑑𝑖𝑔𝑜3; }
Si la condición es verdadera se ejecutará el primer código, sino se verificara la siguiente
condición, si ninguna condición es verdadera se implementara el código del 𝑒𝑙𝑠𝑒. Se pueden
incluir tantos 𝑒𝑙𝑠𝑒 𝑖𝑓 como sea necesario.

PSEUDOCÓDIGO
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Ciclo FOR con comunicación USB
Inicio del programa
Imprime “Semáforo manual con conexión USB”

4
Los LEDS pueden ir conectados a los puertos del microcontrolador sin necesidad de resistencias, pero si se
alimentan directamente a 5 Volts pueden quemarse. Debido a esto se recomienda conectar resistencias de 220Ω
entre los LEDs y la alimentación como medida de seguridad.

14
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Imprime “Presione v para encender el LED verde, a para encender el LED amarillo y r para
encender el LED rojo“
Leer letra
Si letra = v
Dato=1
Si letra = a
Dato=2
Si letra = r
Dato=4
Sino
Imprime “Caracter no reconocido”
Fin del Si
Mandar Paquete (PUERTOD_SALIDA, dato)
Fin del programa
La instrucción Mandar Paquete (PUERTOD_SALIDA, dato) se encuentra en la biblioteca
“Comunicación.h”. Esta instrucción le indica al microcontrolador que se va a utilizar el
puerto D como salida y que se desea escribir en dicho puerto el número almacenado en dato.
La línea de código para esta instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝑂𝑈𝑇𝑃𝑈𝑇, &𝑑𝑎𝑡𝑜);
Los números que deben mandarse son 1, 2 y 4 debido a que el microcontrolador lo interpreta
en su código binario y lo envía al Puerto D, se muestra a continuación una tabla con los
valores en binario para una mejor comprensión de este funcionamiento.
Puerto D Dato a enviar Dato en
binario
D0 1 0000 0001
D1 2 0000 0010
D2 4 0000 0100
D3 8 0000 1000
D4 16 0001 0000
D5 32 0010 0000
D6 64 0100 0000
D7 128 1000 0000
Figura 5.1 Encendido de bits del puerto D

15
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Es posible encender varios LEDS al mismo tiempo siguiendo este concepto, simplemente se
debe buscar el valor en decimal correspondiente.
Información adicional
Cuando el código dentro de cualquier sentencia sólo consta de una línea de código, el
programador puede quitar las llaves del código a realizar. Ejemplo:
𝑖𝑓(𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛)
𝑐ó𝑑𝑖𝑔𝑜1;
La conexión de los LEDs al puerto D en un protoboard se muestra a continuación.

Figura 5.2. Conexión de tres LEDs al puerto D en la tarjeta Miuva.

16
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

6. Práctica 3.1: Ciclo FOR


OBJETIVOS
Entender el funcionamiento del ciclo FOR en programación.
Comprobar dicho funcionamiento con un programa que pregunte el número de veces
que se quiere hacer parpadear un LED.

MATERIAL
 Microcontrolador PIC 18F4550
 1 LED
MARCO TEORICO
Un bucle o Ciclo en programación sirve para repetir una parte del código un número definido
o indefinido de veces. En lenguaje C existen 3 funciones que permiten un ciclo: FOR,
WHILE, Do…WHILE. Cada una diseñada para diferentes situaciones.
El ciclo FOR es un bucle que permite repetir cierta operación un determinado número de
veces, es decir un número de veces que el programador conoce, a diferencia del bucle WHILE
el cual no necesariamente se debe conocer el número de veces que se quiere repetir.
La sintaxis del ciclo FOR en lenguaje C es:
𝑓𝑜𝑟(𝑖𝑛𝑖𝑐𝑖𝑜; 𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛; 𝑖𝑛𝑐𝑟𝑒𝑚𝑒𝑛𝑡𝑜)
La condición en la sintaxis debe ser entendida como una condición de “mientras”, ya que el
ciclo sólo repetirá el código sí la condición es verdadera.

PSEUDOCÓDIGO
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Ciclo FOR con comunicación USB
Inicio del programa
Imprime “Ciclo FOR con comunicación USB”
Imprime “Envíe el número de veces que parpadeará el LED”
Lee dato
Mientras i < dato
led = 1

17
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Mandar Paquete (LED, led)


Esperar (1 segundo)
led = 0
Mandar Paquete (LED, led)
Esperar (1 segundo)
Fin de mientras
Fin del programa
La instrucción Mandar paquete (LED, led) es una función descrita en la biblioteca
“Comunicación.h”, los dos datos dentro del paréntesis son parámetros, de los cuales el
primero habilita la opción de encender el LED conectado al pin E1, mientras que el segundo
manda el valor de tipo entero a este puerto, si el valor es 1, el LED encenderá, si es 0 se
apagará. La instrucción es la siguiente:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐿𝐸𝐷_𝑂𝑁, &𝑙𝑒𝑑);
La instrucción Esperar (1 segundo) es una función en la biblioteca standard de c, la cual le
dice al sistema que espere un periodo de tiempo en milisegundos. El código para esta
instrucción es:
𝑆𝑙𝑒𝑒𝑝(1000);
Información adicional.
En algunas ocasiones es necesario hacer un ciclo infinito, es decir que se repita siempre, en
el caso particular de la instrucción FOR esto se logra mediante la siguiente instrucción:
𝑓𝑜𝑟(; ; )
Con esta instrucción el código que se encuentre dentro se repetirá infinitamente.

18
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

7. Práctica 3.2: Ciclo WHILE


OBJETIVO:
Entender el funcionamiento del ciclo WHILE en programación
Comprobar dicho funcionamiento con un programa que haga parpadear un LED hasta
que se presione un botón pulsador.

MATERIAL:
 Placa de desarrollo PIC 18F4550
 1 LED
 1 botón pulsador
MARCO TEORICO
Un bucle o Ciclo en programación sirve para repetir una parte del código un número definido
o indefinido de veces. En lenguaje C existen 3 funciones que permiten un ciclo: FOR,
WHILE, Do…WHILE. Cada una diseñada para diferentes situaciones.

El ciclo WHILE es un bucle que permite repetir cierta operación mientras se cumpla una
condición. La sintaxis del ciclo WHILE en lenguaje C es:
𝑤ℎ𝑖𝑙𝑒(𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛){𝑐𝑜𝑑𝑖𝑔𝑜; }
La condición en la sintaxis debe ser entendida como una condición de “mientras”, ya que el
ciclo sólo repetirá el código sí la condición es verdadera.
El ciclo DO-WHILE parte del mismo concepto que el ciclo WHILE con la diferencia que el
código dentro de este ciclo se ejecutará al menos una vez y al final evaluará la condición. La
sintaxis de este ciclo es la siguiente:
𝐷𝑜{𝑐𝑜𝑑𝑖𝑔𝑜}
𝑤ℎ𝑖𝑙𝑒(𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛);

PSEUDOCÓDIGO
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Ciclo WHILE con comunicación USB
Inicio del programa
Imprime “Ciclo WHILE con comunicación USB”

19
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Imprime “Presionar botón para apagar el LED”


Hacer mientras(𝑑𝑎𝑡𝑜 == 0)
Led = 1
Mandar Paquete (LED, led)
Esperar (1 segundo)
Led = 0
Mandar Paquete (LED, led)
Esperar (1 segundo)
Recibir Paquete (PB, dato)

Fin de Hacer
Imprime”Dato recibido”
Fin del programa
La instrucción Mandar paquete (LED, led) es una función descrita en la biblioteca
“Comunicación.h”, los dos datos dentro del paréntesis son parámetros, de los cuales el
primero habilita la opción de encender el LED conectado al pin E1, mientras que el segundo
manda el valor de tipo entero a este puerto, si el valor es 1, el LED encenderá, si es 0 se
apagará. La instrucción es la siguiente:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐿𝐸𝐷_𝑂𝑁, &𝑙𝑒𝑑);
La instrucción Recibir paquete (PB, dato) es una función que permite leer el estado del botón
(conectado al pin C0 para la tarjeta Miuva o al pin E0 para la tarjeta ATA-NQH), devolviendo
el valor 1 en caso de que se encuentre presionado el botón o un 0 en caso contrario. La función
contiene dos parámetros, el primero le indica al microcontrolador que lea el estado del botón
pulsador y el segundo almacena el valor leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝐵_𝑂𝑁, &𝑑𝑎𝑡𝑜);
La instrucción Esperar (1 segundo) es una función en la biblioteca standard de c, la cual le
dice al sistema que espere un periodo de tiempo en milisegundos. El código para esta
instrucción es:
𝑆𝑙𝑒𝑒𝑝(1000);
Información adicional.

20
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

De igual manera que en el ciclo FOR, es posible hacer un ciclo infinito con el ciclo WHILE
haciendo siempre verdadera la condición que evalúa. Las formas más simples de hacer esto
son las siguientes:
𝑤ℎ𝑖𝑙𝑒(1)
𝑤ℎ𝑖𝑙𝑒(𝑡𝑟𝑢𝑒)

Ambas instrucciones generan un ciclo que se repetirá infinitamente.

21
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

8. Práctica 4: SWITCH-CASE
OBJETIVO:
Entender el funcionamiento de la sentencia SWITCH- CASE en programación.
Comprobar dicho funcionamiento con un programa que conste de:
a. Un programa menú que pregunte cual programa desea ejecutar.
b. Un subprograma que encienda 1 LED de acuerdo a su posición (sólo 1 a la vez).
c. Un subprograma que haga una secuencia de LEDS continua, la cual consista en
prender el LED consecutivo (prender sólo el LED conectado al pin D0, luego sólo el
LED a D1 así hasta prender el LED conectado a D7 )
MATERIAL:
 1 microcontrolador PIC 18F4550
 8 LEDS5 de cualquier color.
MARCO TEORICO
Una de las funciones más básica en la programación es el de la toma de decisiones, es decir,
que se ejecuten diferentes instrucciones según una condición determinada. La sentencia
SWITCH-CASE permite ejecutar cierto código para casos muy específicos. La diferencia
principal entre una sentencia IF-ELSE es el hecho que la condición puede ser una operación
lógica o una desigualdad (mayor, menor o diferente que) mientras que en el SWITCH-CASE
sólo pueden ser igualdades.

PSEUDOCÓDIGO
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Switch-Case con comunicación USB
Inicio del programa
Imprime “SWITCH CASE con comunicación USB”
Imprime “Indique ejercicio”

5
Los LEDS pueden ir conectados a los puertos del microcontrolador sin necesidad de resistencias, pero si se
alimentan directamente a 5 Volts pueden quemarse. Debido a esto se recomienda conectar resistencias de 220Ω
entre los LEDs y la alimentación como medida de seguridad.

22
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Lee ejercicio
Si 𝑒𝑗𝑒𝑟𝑐𝑖𝑐𝑖𝑜 = 1
Mientras (verdadero)
Imprime “Indique posición del LED”
Lee número
Si número = 0
Led = 1
Si número = 1
Led = 2
Si número = 2
Led = 4
Si número = 3
Led = 8
Si número = 4
Led = 16
Si número = 5
Led = 32
Si número = 6
Led = 64
Si número = 7
Led = 128
Sino
Imprime “Introduce un numero entre 0 y 7”
Led = 0
Fin de si
Mandar Paquete (PUERTOD_SALIDA, dato)
Fin de hacer
Si 𝑒𝑗𝑒𝑟𝑐𝑖𝑐𝑖𝑜 = 2

23
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Imprime “Secuencia de LEDS”


Hacer mientras (i<8)
Si i = 0
Led = 1
Si i = 1
Led = 2
Si i = 2
Led = 4
Si i = 3
Led = 8
Si i = 4
Led = 16
Si i = 5
Led = 32
Si i = 6
Led = 64
Si i = 7
Led = 128
Fin de si
Mandar Paquete (PUERTOD_SALIDA, dato)
Fin de hacer
Fin de si
Fin del programa
La instrucción Mandar Paquete (PUERTOD_SALIDA, dato) se encuentra en la biblioteca
“Comunicación.h”. Esta instrucción le indica al microcontrolador que se va a utilizar el
puerto D como salida y que se desea escribir en dicho puerto el número almacenado en dato.
La línea de código para esta instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝑂𝑈𝑇𝑃𝑈𝑇, &𝑑𝑎𝑡𝑜);

24
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

9. Práctica 5.1 : Arreglo unidimensional


OBJETIVOS
Entender el funcionamiento de un arreglo unidimensional y como acceder a cada
variable dentro del arreglo.
Crear un programa que mande al microcontrolador los datos contenidos en el arreglo
de tipo entero para encender 8 LEDS según su equivalente binario.

MATERIAL
 1 microcontrolador PIC 18F4550
 8 LEDS de cualquier color.
MARCO TEORICO
Un arreglo se puede definir como un conjunto de datos del mismo tipo. Este tipo de
declaración resulta conveniente cuando se manejan un gran número de variables del mismo
tipo que guardan una correlación entre sí. Para poder utilizar dicho arreglo hay que reservar
el espacio de memoria, por eso siempre se debe especificar el tamaño del arreglo. Según el
número de parámetros que ocupe el arreglo se pueden clasificar como unidimensionales o
multidimensionales. En esta práctica sólo se ocupará un arreglo unidimensional.
La sintaxis para declarar un arreglo en lenguaje C es el siguiente:
𝑇𝑖𝑝𝑜 Nombre[𝑡𝑎𝑚𝑎ñ𝑜];

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y crear una
interfaz que pregunte el número de datos a enviar tomando 10 como máximo, luego
guardarlos en el arreglo y finalmente preguntando el intervalo de tiempo para mandar y
mostrar cada variable en el puerto D del microcontrolador.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

Programa: Manejo de arreglos con comunicación USB


Inicio del programa
Imprime “Arreglo unidimensional con comunicación USB”
Imprime “Indique número de datos que desea mandar”
Lee máximo

25
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Mientras i < máximo


Imprime “Numero a guardar en el espacio i”
Lee arreglo[i]
Fin del Mientras
Imprime “Indique tiempo en segundos”
Lee tiempo
tiempo = tiempo * 1000
Imprime “Mandando datos al PIC en binario”
i=0
Mientras i < máximo
Mandar Paquete (PUERTOD_SALIDA, arreglo[i])
Esperar (tiempo)
Fin de Mientras
Fin del programa
La instrucción Mandar Paquete (PUERTOD_SALIDA, arreglo[i]) es una función descrita
en la biblioteca “Comunicación.h”, los dos datos dentro del paréntesis son parámetros, de los
cuales el primero le indica al microcontrolador que el puerto D será ocupado como salida y
se le mandará el dato en la segunda variable, en este caso arreglo[i]. La instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝑂𝑈𝑇𝑃𝑈𝑇, &𝑎𝑟𝑟𝑒𝑔𝑙𝑜[𝑖]);
La instrucción Esperar (tiempo) es una función en la biblioteca standard de c, la cual le dice
al sistema que espere un periodo de tiempo en milisegundos. El código para esta
instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑡𝑖𝑒𝑚𝑝𝑜);
Información adicional.
Se muestra la conexión de 8 LEDs con la tarjeta Miuva en un protoboard.

26
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura 9.1 Conexión del 8 LEDs al puerto D de la tarjeta Miuva.

Como se puede observar existen 2 conexiones al puerto D en la tarjeta Miuva, es necesario


conectar los LEDs como se muestra en la figura 9.1 de lo contrario no encenderán todos los
LEDs. Si se desea se pueden conectar resistencias de 220Ω entre la tarjeta y el LED, esto
ayuda a prolongar la vida de LED, sin embargo no es necesario conectarlas.

27
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

10. Práctica 5.2: Arreglo unidimensional de temperaturas


OBJETIVOS
Entender el funcionamiento de un arreglo unidimensional y como acceder a cada
variable dentro del arreglo.
Crear un programa que obtenga datos del convertidor analógico-digital (pin A0)
conectado a un sensor de temperatura, que ordene estos datos en un arreglo
unidimensional y que muestre el promedio de las temperaturas

MATERIAL
 1 microcontrolador PIC 18F4550
 1 sensor de temperatura LM35 (Ver conexión de pines en Apéndice G)

MARCO TEORICO
Un arreglo se puede definir como un conjunto de datos del mismo tipo. Este tipo de
declaración resulta conveniente cuando se manejan un gran número de variables del mismo
tipo que guardan una correlación entre sí. Para poder utilizar dicho arreglo hay que reservar
el espacio de memoria, por eso siempre se debe especificar el tamaño del arreglo. Según el
número de parámetros que ocupe el arreglo se pueden clasificar como unidimensionales o
multidimensionales. En esta práctica sólo se ocupará un arreglo unidimensional.
La sintaxis para declarar un arreglo en lenguaje C es el siguiente:
𝑇𝑖𝑝𝑜 Nombre[𝑡𝑎𝑚𝑎ñ𝑜];

PSEUDOCÓDIGO
El código consiste en hacer un programa que obtenga la temperatura cada determinado
tiempo, que almacene los datos obtenidos en un arreglo unidimensional y que encuentre el
promedio de todas las temperaturas. Las temperaturas deberán ser mostradas con 2
decimales, es decir, el arreglo, tanto como el promedio deberán ser variables de tipo
flotantes.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

Programa: Sensado de temperatura con comunicación USB


Define constante MEDICIONES = 5
tiempo = 1000

28
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Inicio del programa


Imprime “Programa que trabaja temperaturas de un día”
Mientras índice < MEDICIONES
Recibirpaquete (ADC_ON, datoadc1, datoadc2)
Esperar (tiempo)
datocompleto = ( corrimiento 8 lugares a la izquierda de datoadc2) + datoadc1
temperatura[índice] = (5.0/1023.0)*100* datocompleto
promedio = promedio + temperatura[índice]
Imprime “La medición de temperatura” índice + 1 “es de” temperatura[índice]
índice = índice +1
Fin de Mientras
promedio = promedio / MEDICIONES
Imprime “El promedio de temperaturas es de:” promedio
Fin del programa
La instrucción Recibir paquete (ADC, datoadc1, datoadc2) esta descrita en la biblioteca
“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐1, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐2);

La instrucción Esperar (tiempo) es una función en la biblioteca standard de c, la cual le dice


al sistema que espere un periodo de tiempo en milisegundos. El código para esta
instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑡𝑖𝑒𝑚𝑝𝑜);
Información adicional.
A continuación se presenta la conexión del sensor LM35 con la tarjeta Miuva sobre un
protoboard. Es necesario tener cuidado en el momento de conectar el sensor debido a que si
se conecta de manera incorrecta puede quemarse.

29
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura 10.1 Conexión de la tarjeta Miuva con el sensor LM35

De igual manera se presenta la conexión del sensor con la tarjeta ATA-NQH. Como se puede
observar la salida del sensor va conectada al pin A0.

Figura 10.2 Conexión de la tarjeta ATA-NQH con el sensor LM35

30
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

11. Práctica 6: Cadena de caracteres


OBJETIVOS
Entender el funcionamiento de las cadenas de caracteres y como unir varias cadenas en
una sola.
Comprobar dicho funcionamiento con un programa que pida el nombre de la persona
y que el programa conteste con un saludo y el nombre ingresado. El dato debe mostrarse
en el LCD.

MATERIAL
 Circuito PIC 18F4550
 Un LCD de 2x16
MARCO TEORICO
El lenguaje C permite manejar cadenas de caracteres las cuales consisten esencialmente en
arreglos unidimensionales, los cuales almacenan en cada variable un caracter. Algunas
funciones para manejo de cadenas de caracteres se muestran a continuación junto con la
descripción de estas.
Función Descripción
Strcpy Copia el contenido de una cadena dentro de
otra
Strcmp Compara dos cadenas
Strlen Determina la longitud de una cadena
strncpy Copia un número determinado de caracteres
de una cadena a otra
Strcat Concatena dos cadenas de caracteres
Figura 10.1 Funciones para manejo de cadenas.

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y pedir un
nombre al usuario para que el programa muestre en el LCD el nombre junto con un saludo,
esto con la finalidad de unir dos cadenas de caracteres, una que contenga el nombre (variable)
y otra que contenga un saludo (“Constante”). Ya que se leerá una cadena de caracteres,
las variables deberán ser arreglos unidimensionales de mínimo 16 datos (Esto debido al
LCD)
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

31
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Programa: Manejo de cadenas de caracteres

Inicio del programa


InciarLCD(TARJETA)
Imprime “Introduzca su nombre en un máximo de 11 caracteres”
Lee nombre
número = strlen(nombre)
Imprime “Su nombre tiene” número “letras”
Imprime “El nombre que ha escrito se muestra en el LCD”
strcat(saludo, “Hola”)
strcat(saludo, nombre)
Mientras i < 16
Si saludo[i] == ‘\0’
i = 16
Sino
mandarcaracterLCD(TARJETA, saludo[i])
Fin de Si
i = i +1
Fin de Mientras
Fin del programa
La función InciarLCD(TARJETA) es una función descrita en la biblioteca
“Comunicación.h” la cual permite inicializar el LCD según la configuración de la tarjeta
(para más información revisar el apéndice G). Esta función recibe un parámetro el cual
distingue entre la tarjeta Miuva y la ATA-NQH. La instrucción para la tarjeta Miuva es:
𝑖𝑛𝑖𝑐𝑖𝑎𝑟𝑙𝑐𝑑(𝑀𝐼𝑈𝑉𝐴);
Mientras que para la ATA-NQH es:
𝑖𝑛𝑖𝑐𝑖𝑎𝑟𝑙𝑐𝑑(𝐴𝑇𝐴𝑁𝑄𝐻);
De igual manera, la función mandarcaracterLCD(TARJETA, saludo[i]) se encuentra en la
biblioteca “Comunicación.h”, la cual envía datos al LCD dependiendo de qué tarjeta se

32
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

ocupe. Esta función tiene dos parámetros: el primero que le indica que tarjeta se esta
ocupando y el segundo el dato que se desea mandar. La instrucción para la tarjeta Miuva es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑐𝑎𝑟𝑎𝑐𝑡𝑒𝑟𝐿𝐶𝐷(𝑀𝐼𝑈𝑉𝐴, 𝑠𝑎𝑙𝑢𝑑𝑜[𝑖]);
Mientras que para la tarjeta ATA-NQH es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑐𝑎𝑟𝑎𝑐𝑡𝑒𝑟𝐿𝐶𝐷(𝐴𝑇𝐴𝑁𝑄𝐻, 𝑠𝑎𝑙𝑢𝑑𝑜[𝑖]);

33
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

12. Práctica 7. Matriz de temperaturas


OBJETIVOS
Entender el funcionamiento de un arreglo bidimensional y como acceder a cada
variable dentro del arreglo.
Crear un programa que obtenga datos del convertidor analógico-digital conectado a un
sensor de temperatura y que ordene estos datos en un arreglo bidimensional separando
las muestras según el día en que fueron tomadas.
Mostrar el promedio de las temperaturas, máximo y mínimo por día y finalmente el
promedio total de todas las temperaturas, máximo y mínimo de todas las temperaturas
sensadas.

MATERIAL
 1 microcontrolador PIC 18F4550
 Un sensor de temperatura LM35(Ver conexión de pines en Apéndice G)

MARCO TEORICO
Un arreglo se puede definir como un conjunto de datos del mismo tipo. Este tipo de
declaración resulta conveniente cuando se manejan un gran número de variables del mismo
tipo que guardan una correlación entre sí. Para poder utilizar dicho arreglo hay que reservar
el espacio de memoria, por eso siempre se debe especificar el tamaño del arreglo. Según el
número de parámetros que ocupe el arreglo se pueden clasificar como unidimensionales o
multidimensionales. En esta práctica se ocupará un arreglo de dos dimensiones, el cual puede
entenderse fácilmente como una matriz de datos
La sintaxis para declarar una matriz en C es el siguiente:
𝑇𝑖𝑝𝑜 Nombre[𝑓𝑖𝑙𝑎][𝑐𝑜𝑙𝑢𝑚𝑛𝑎];

PSEUDOCÓDIGO
Las temperaturas deberán ser mostradas con 2 decimales, es decir, el arreglo tanto
como el promedio deberán ser variables de tipo flotantes.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

Programa: Sensado de temperatura con comunicación USB


Define constante DIAS = 5

34
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Define constante MEDICIONES = 5


Define constante TIEMPOMUESTREO = 1000
Inicio del programa
Imprime “Programa que trabaja temperaturas de varios días”
fila = 0
columna = 0
Mientras fila < DIAS
Mientras columna < MEDICIONES
Imprime “Temperatura día” fila+1 “mediciones” columna+1
Recibir paquete (ADC_ON, datoadc1, datoadc2)
dato = ( corrimiento 8 lugares a la izquierda de datoadc2) + datoadc1
temperatura [fila] [columna] = (5.0/1023.0)*100* dato
Imprime temperatura[fila][columna]
promedio = promedio + temperatura[fila][columna]
Esperar (TIEMPOMUESTREO)
columna = columna +1
fila = fila + 1
Fin de Mientras
Fin de Mientras
Imprime “La matriz de temperaturas es:”
max = temperatura[2][2]
mín = temperatura[0][1]
fila = 0
columna = 0
Mientras fila < DIAS
Imprime “Día” fila+1
promedios[fila] = 0
máximos[fila]= temperatura[fila][0]

35
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

mínimos[fila]= temperatura[fila][0]
Mientras columna < MEDICIONES
Imprime temperatura[fila][columna]
Si temperatura[fila][columna] > máximos[fila]
máximos[fila] = temperatura[fila][columna]
Si temperatura[fila][columna] < mínimo[fila]
mínimo[fila]= temperatura[fila][columna]
Fin de Si
promedios[fila] = promedios[fila] + temperatura[fila][columna]
columna = columna + 1
Fin de Mientras
promedios[fila] = promedios[fila]/ MEDICIONES
Imprime “Promedio día” fila+1 “es” promedios[fila]
Imprime “Máximo” máximos[fila]
Imprime “Mínimo” mínimos [fila]
fila = fila +1
Fin de Mientras
promedio = promedio /(DIAS*MEDICIONES)
Imprime “El promedio de TODAS las temperaturas es” promedio
fila = 0
Mientras fila < DIAS
Si min > minimos[fila]
min = minimos[fila]
Si max < máximos[fila]
max= máximos[fila]
Fin de Si
fila = fila +1
Fin de Mientras

36
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Imprime “La temperatura mayor es” max “la temperatura menor es” min
Fin del programa
La instrucción Recibir paquete (ADC, datoadc1, datoadc2) esta descrita en la biblioteca
“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐1, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐2);

La instrucción Esperar (TIEMPOMUESTREO) es una función en la biblioteca standard de


c, la cual le dice al sistema que espere un periodo de tiempo en milisegundos. El código
para esta instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑇𝐼𝐸𝑀𝑃𝑂𝑀𝑈𝐸𝑆𝑇𝑅𝐸𝑂);

37
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

13. Práctica 8.1: Funciones vacías.


OBJETIVO:
Comprender la importancia de las funciones vacías en programación.
Comprobar dicho funcionamiento ocupando funciones vacías para organizar el código
de la práctica 4 (SWITCH-CASE)

MATERIAL:
 1 microcontrolador PIC 18F4550
 8 LEDS de cualquier color.
MARCO TEORICO
Una función es un bloque de código que realiza una tarea específica, esto con la finalidad de
organizar el código principal. Algunos ejemplos de funciones ya conocidas son 𝑝𝑟𝑖𝑛𝑡𝑓o
𝑠𝑐𝑎𝑛𝑓las cuales tienen protocolos bien definidos para el envío o recepción de datos.
El lenguaje C permite al programador definir sus propias funciones las cuales pueden ser de
diferentes tipos. En esta práctica sólo se ocuparan funciones de tipo vacías (void).
La principal característica de esta función es que no tiene valor de retorno, esto significa que
ejecuta una parte de código, pero no tiene un valor de retorno asociado. La sintaxis de este
tipo de funciones es:
𝑣𝑜𝑖𝑑 𝑁𝑜𝑚𝑏𝑟𝑒_𝑑𝑒_𝑓𝑢𝑛𝑐𝑖𝑜𝑛(){}

PSEUDOCÓDIGO
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Switch-Case con funciones
Inicio del programa
Imprime “SWITCH CASE con comunicación USB”
Imprime “Indique ejercicio”
Lee ejercicio
Si 𝑒𝑗𝑒𝑟𝑐𝑖𝑐𝑖𝑜 = 1
SeleccionarLED( )
Si 𝑒𝑗𝑒𝑟𝑐𝑖𝑐𝑖𝑜 = 2

38
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

SecuenciaLED( )
Fin de si
Fin del programa
Inicio de SeleccionarLED( )
Mientras (verdadero)
Imprime “Indique posición del LED”
Lee número
Si número = 0
Led = 1
Si número = 1
Led = 2
Si número = 2
Led = 4
Si número = 3
Led = 8
Si número = 4
Led = 16
Si número = 5
Led = 32
Si número = 6
Led = 64
Si número = 7
Led = 128
Sino
Imprime “Introduce un numero entre 0 y 7”
Led = 0
Fin de si
Mandar Paquete (PUERTOD_SALIDA, dato)

39
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Fin de Mientras
Fin de SeleccionarLED( )
Inicio de SecuenciaLED( )
Imprime “Secuencia de LEDS”
Hacer mientras (i<8)
Si i = 0
Led = 1
Si i = 1
Led = 2
Si i = 2
Led = 4
Si i = 3
Led = 8
Si i = 4
Led = 16
Si i = 5
Led = 32
Si i = 6
Led = 64
Si i = 7
Led = 128
Fin de si
i= i +1
Mandar Paquete (PUERTOD_SALIDA, dato)
Fin de hacer
Fin de SecuenciaLED( )
La instrucción Mandar Paquete (PUERTOD_SALIDA, dato) se encuentra en la biblioteca
“Comunicación.h”. Esta instrucción le indica al microcontrolador que se va a utilizar el

40
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

puerto D como salida y que se desea escribir en dicho puerto el número almacenado en dato.
La línea de código para esta instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝑂𝑈𝑇𝑃𝑈𝑇, &𝑑𝑎𝑡𝑜);
Información adicional
En C es necesario declarar las funciones que se desean ocupar antes del código principal, sin
embargo algunos programadores prefieren describir las funciones al final de este. Para
colocar las funciones al final es necesario escribir el nombre de la función antes de la función
principal y escribir la función completa después de éste. Por ejemplo:
𝑣𝑜𝑖𝑑 𝑓𝑢𝑛𝑐𝑖𝑜𝑛();
𝑣𝑜𝑖𝑑 𝑚𝑎𝑖𝑛(){𝑐𝑜𝑑𝑖𝑔𝑜 𝑝𝑟𝑖𝑛𝑐𝑖𝑝𝑎𝑙}
𝑣𝑜𝑖𝑑 𝑓𝑢𝑛𝑐𝑖𝑜𝑛(){𝑐𝑜𝑑𝑖𝑔𝑜 𝑑𝑒 𝑓𝑢𝑛𝑐𝑖ó𝑛}

41
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

14. Práctica 8.2 Funciones tipo entero con parámetros


OBJETIVO:
Comprender la importancia de las funciones de tipo entero en programación.
Comprobar dicho funcionamiento ocupando funciones de tipo entero para organizar el
código de la práctica 1 (Operaciones bit a bit)

MATERIAL
 Microcontrolador PIC 18F4550
 2 Interruptores DIP de 8 conexiones (Dip switch)
 16 resistencias de 1 KΩ
MARCO TEÓRICO
Una función es un bloque de código que realiza una tarea específica, esto con la finalidad de
organizar el código principal. Algunos ejemplos de funciones ya conocidas son 𝑝𝑟𝑖𝑛𝑡𝑓o
𝑠𝑐𝑎𝑛𝑓las cuales tienen protocolos bien definidos para el envío o recepción de datos.
El lenguaje C permite al programador definir sus propias funciones las cuales pueden ser de
diferentes tipos. En esta práctica se ocuparan funciones de tipo entero (int) las cuales siempre
tienen un valor de retorno (evidentemente de tipo entero). La sintaxis de una función de tipo
entero es:
𝑖𝑛𝑡 𝑛𝑜𝑚𝑏𝑟𝑒_𝑑𝑒_𝑓𝑢𝑛𝑐𝑖𝑜𝑛()
{
//𝑐𝑜𝑑𝑖𝑔𝑜 𝑑𝑒 𝑙𝑎 𝑓𝑢𝑛𝑐𝑖ó𝑛
𝑟𝑒𝑡𝑢𝑟𝑛 𝑣𝑎𝑙𝑜𝑟
}

Las funciones además de regresar valores de algún tipo, pueden tener parámetros
provenientes del código principal. La sintaxis de una función con parámetros es:
𝑖𝑛𝑡 𝑛𝑜𝑚𝑏𝑟𝑒(𝑖𝑛𝑡 𝑎, 𝑖𝑛𝑡 𝑏)
Los parámetros deben ser inicializados según el tipo de dato. En este caso se observa que se
inicializan los parámetros 𝑎 y 𝑏 de tipo entero.

42
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

PSEUDOCÓDIGO
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Operación bit a bit con funciones
Inicio del programa
Imprime “Programa que lee los datos del puerto B y D y hace operaciones a nivel bit”
Recibir paquete (Puerto B entrada, puerto B)
Recibir paquete (Puerto D entrada, puerto D)
Imprime “El valor en el puerto B es:” puerto B
Imprime “El valor en el puerto D es:” puerto D
Imprime “El valor en el puerto B es:” puerto B “en sistema octal”
Imprime “El valor en el puerto D es:” puerto D “en sistema octal”
Imprime “El valor en el puerto B es:” puerto B “en sistema hexadecimal”
Imprime “El valor en el puerto D es:” puerto D “en sistema hexadecimal”
Resultado = operacionOR(puertoB,puertoD)
Imprime “La operación OR entre ambos números en decimal es” resultado
Resultado = operacionAND(puertoB,puertoD)
Imprime “La operación AND entre ambos números en decimal es” resultado
Fin del programa
Inicio de operacionOR( pb, pd)
respuesta = pb OR pd
Retorno respuesta
Fin de operacionOR( pb, pd)

Inicio de operacionAND( pb, pd)


respuesta = pb AND pd

43
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Retorno respuesta
Fin de operacionAND( pb, pd)
La instrucción Recibir paquete (Puerto B entrada, puerto B) hace referencia a una función
descrita en la biblioteca “Comunicación.h”, los dos datos dentro del paréntesis son
parámetros, el primero habilita el puerto B como entrada, mientras que el segundo le indica
a la función dónde guardar el dato recibido, que en este caso es la variable puerto_B. La línea
de código correspondiente es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐵_𝐼𝑁𝑃𝑈𝑇, &𝑝𝑢𝑒𝑟𝑡𝑜𝐵);
Es necesario agregar el operador & antes del nombre de la variable, tal y como se hace con
la instrucción 𝑠𝑐𝑎𝑛𝑓.
De igual manera la instrucción Recibir paquete (Puerto D entrada, puerto D) hace referencia
a la misma función explicada anteriormente, con la diferencia de que los parámetros cambian
para que se habilite el puerto D como entrada y se almacene el dato en el segundo parámetro,
es decir, la variable puerto D. El código queda de la siguiente manera:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝐼𝑁𝑃𝑈𝑇, &𝑝𝑢𝑒𝑟𝑡𝑜𝐷);
Información adicional
No es necesario ocupar el valor de retorno, algunos programadores ocupan funciones de tipo
entero, como funciones de tipo vacías. Por ejemplo:
𝑖𝑛𝑡 𝑚𝑎𝑖𝑛(){
//𝐶𝑜𝑑𝑖𝑔𝑜
𝑟𝑒𝑡𝑢𝑟𝑛 0
}
Se puede declarar la función principal (función main) de tipo int con la finalidad de asignar
un valor de retorno diferente de 0 en el caso de que el programa no se ejecute correctamente,
esto puede facilitar la detección de errores en el algoritmo.

44
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

15. Práctica 8.3 Matriz de LEDS multiplexada


OBJETIVO:
Entender la diferencia entre una variable global y local.
Aplicar los conocimientos adquiridos de funciones y arreglos de dos dimensiones para
hacer un programa que pregunte que LED se quiere prender de una matriz, imprimir
en pantalla un arreglo que represente la matriz de LEDS, mostrando un 1 en caso de
que el LED se quiera encender y un 0 en caso de que este apagado.
Finalmente, mandar los datos al microcontrolador para encender los LEDS que el
usuario índico.

MATERIAL
 Microcontrolador PIC 18F4550
 1 matriz de LEDS de 8x8
MARCO TEÓRICO
Existen dos tipos de declaraciones de variables:
 Variables locales: Son variables que sólo se pueden ocupar en la función que son
declaradas, ya sea la función principal (main) o alguna otra función.
 Variables globales: Son variables que se declaran fuera de cualquier función y
pueden ser ocupadas o llamadas por cualquier función.
PSEUDOCÓDIGO
En esta práctica se ocupará un arreglo de dos dimensiones de tipo global llamada
𝒎𝒂𝒕𝒓𝒊𝒛[𝟖][𝟖] que podrá ser accesible para todas las funciones.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Matriz de LEDs
matriz[8][8] = {0}
Inicio del programa
inicial = 0
madarpaquete (PUERTOB_SALIDA, inicial)
madarpaquete (PUERTOD_SALIDA, inicial)
Mientras confirmar = ‘S’

45
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Imprime “Indique la fila del LED que desea encender (1 a 8)”


Lee fila
Imprime “Indique la columna del LED que desea encender (1 a 8)”
Lee columna
fila= fila -1
columna = columna -1
Si matriz[fila][columna]=1
Imprime “Ese LED ya está prendido”
Sino
matriz[fila][columna]=1
Fin de Si
Imprime “El estado de la matriz es el siguiente”
imprimirmatriz()
Imprime “Desea encender otro LED?<S/N>”
Lee confirmar
Fin de Mientras
Imprime “Se ha encendido la matriz de LEDS”
enviardatos()
Fin del programa
Inicio de imprimirmatriz()
i=0
j=0
Mientras i < 8
Imprime “|”
Mientras j <8
Imprime matriz[i][j]
Fin de Mientras
Fin de Mientras

46
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Fin de imprimirmatriz()
Inicio de enviardatos()
puertoB = 0
puertoD = 0
Mientras 1
exponente = 0
i=0
Mientras i < 8
𝑝𝑢𝑒𝑟𝑡𝑜𝐵 = 2𝑒𝑥𝑝𝑜𝑛𝑒𝑛𝑡𝑒
puertoD = escanearfila(i)
mandarpaquete(MATRIZ_LEDS, puertoB, puertoD )
i = i +1
exponente = exponente + 1
Fin de Mientras
Fin de Mientras
Fin de enviardatos()
Inicio escanearfila(f)
memoria =255
Si matriz[f][0] = 1
memoria = memoria -1
Si matriz[f][1] = 1
memoria = memoria -2
Si matriz[f][2] = 1
memoria = memoria -4
Si matriz[f][3] = 1
memoria = memoria -8
Si matriz[f][4] = 1
memoria = memoria -16

47
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Si matriz[f][5] = 1
memoria = memoria -32
Si matriz[f][6] = 1
memoria = memoria -64
Si matriz[f][7] = 1
memoria = memoria -128
Fin de Si
Retorna memoria
Fin de escanearfila(f)
La instrucción Mandar Paquete (PUERTOD_SALIDA, inicial) se encuentra en la biblioteca
“Comunicación.h”. Esta instrucción le indica al microcontrolador que se va a utilizar el
puerto D como salida y que se desea escribir en dicho puerto el número almacenado en
inicial, esto con la finalidad de apagar todos los LEDS de la matriz. La línea de código para
esta instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝑂𝑈𝑇𝑃𝑈𝑇, &𝑖𝑛𝑖𝑐𝑖𝑎𝑙);

De igual manera Mandar Paquete (PUERTOB_SALIDA, inicial) se encuentra en la


biblioteca “Comunicación.h” y le indica al PIC que se mandará el dato inicial al puerto B.
La instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐵_𝑂𝑈𝑇𝑃𝑈𝑇, &𝑖𝑛𝑖𝑐𝑖𝑎𝑙);
La instrucción mandarpaquete(MATRIZ_LEDS, puertoB, puertoD ) manda al mismo
tiempo los datos almacenados en la variable puertoB y puertoD a los puertos respectivos. Se
mandan al mismo tiempo debido al funcionamiento de la matriz de LEDS descrito en el
apéndice G. La instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑀𝐴𝑇𝑅𝐼𝑍_𝐿𝐸𝐷𝑆, &𝑝𝑢𝑒𝑟𝑡𝑜𝐵, &𝑝𝑢𝑒𝑟𝑡𝑜𝐷);

48
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

16. Práctica 9.1. Apuntadores con arreglos unidimensionales.


OBJETIVOS
Entender el funcionamiento de un apuntador y el concepto de aritmética de
apuntadores aplicado a un arreglo unidimensional.
Utilizar el programa de la práctica 5.1 de arreglo unidimensional para mandar los
valores al microcontrolador por apuntadores.
Mostrar los valores en el microcontrolador del primero al último y después mostrarlos
del último al primero.

MATERIAL
 1 microcontrolador PIC 18F4550
 8 LEDS de cualquier color.
MARCO TEORICO
Los apuntadores son un tipo particular de variable que almacena una dirección de memoria
y se ocupan para acceder de manera indirecta a variables. Los apuntadores cuentan con 2
operadores:
 El operador “*” que se coloca antes del nombre del apuntador, el cual devuelve el
valor de la variable que se apunta.
 El operador “&” que se coloca de igual manera, antes del nombre de la variable y
devuelve la dirección de memoria.
Para declarar un apuntador es necesario declararlo con el mismo tipo de variable que se
desea apuntar, es decir si la variable a es de tipo entero, el apuntador apuntoa también debe
ser declarado como entero. Se muestra a continuación la sintaxis de declaración de un
apuntador:
𝑖𝑛𝑡 ∗ 𝑛𝑜𝑚𝑏𝑟𝑒_𝑎𝑝𝑢𝑛𝑡𝑎𝑑𝑜𝑟 = 𝑣𝑎𝑟𝑖𝑎𝑏𝑙𝑒_𝑎𝑝𝑢𝑛𝑡𝑎𝑑𝑎;
Esto no significa que un apuntador sea de tipo entero, sólo le indica al compilador que el
valor que se desea apuntar es de ese tipo.
Un apuntador se puede desplazar fácilmente entre las variables de un arreglo. Esto se conoce
como aritmética de apuntadores. Por ejemplo si se tiene un apuntador asociado a la primera
variable de un arreglo y se suma un 1 al apuntador, el valor apuntado será la segunda variable
del arreglo.

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y crear una
interfaz que pregunte el número de datos a enviar tomando 10 como máximo, luego
guardarlos en el arreglo y finalmente preguntando el intervalo de tiempo para mandar y
mostrar cada variable de la primera a la última en el puerto D del microcontrolador y
posteriormente de la última a la primera.

49
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más


avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

Programa: Manejo de arreglos con comunicación USB

Inicio del programa


*apuntador = arreglo[0];
Imprime “Arreglo unidimensional con comunicación USB”
Imprime “Indique número de datos que desea mandar”
Lee máximo
Mientras i < máximo
Imprime “Numero a guardar en el espacio i”
Lee arreglo + i
Fin del Mientras
Imprime “Indique tiempo en segundos”
Lee tiempo
tiempo = tiempo * 1000
Imprime “Mandando datos al PIC en binario”
i=0
Mientras i < máximo
Mandar Paquete (PUERTOD_SALIDA, apuntador)
Esperar (tiempo)
apuntador= apuntador + 1
Fin de Mientras
Imprime “Mandando datos al PIC en binario del último al primero”
i=máximo

50
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Mientras i > 0
Mandar Paquete (PUERTOD_SALIDA, arreglo-i)
Esperar (tiempo)
i=i -1
Fin de Mientras

Fin del programa


La instrucción Mandar Paquete (PUERTOD_SALIDA, apuntador) es una función descrita
en la biblioteca “Comunicación.h”, los dos datos dentro del paréntesis son parámetros, de los
cuales el primero le indica al microcontrolador que el puerto D será ocupado como salida y
se le mandará el dato en la segunda variable, en este caso apuntador. La instrucción es:
𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝑃𝑂𝑅𝑇𝐷_𝑂𝑈𝑇𝑃𝑈𝑇, & ∗ 𝑎𝑝𝑢𝑛𝑡𝑎𝑑𝑜𝑟
La instrucción Esperar (tiempo) es una función en la biblioteca standard de c, la cual le dice
al sistema que espere un periodo de tiempo en milisegundos. El código para esta
instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑡𝑖𝑒𝑚𝑝𝑜);
Información adicional
Una manera simple de hacer que un apuntador contenga la primera dirección de un arreglo
es asignándola directamente al nombre del arreglo. Por ejemplo:
𝑖𝑛𝑡 𝑎𝑟𝑟𝑒𝑔𝑙𝑜[10];
𝑖𝑛𝑡 ∗ 𝑎𝑝𝑢𝑛𝑡𝑎𝑑𝑜𝑟 = 𝑎𝑟𝑟𝑒𝑔𝑙𝑜;
Esto da como resultado que se apunte a la primera dirección del arreglo. Esto es verdadero
debido a que el nombre de un arreglo también es un apuntador.

51
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

17. Práctica 9.2. Apuntadores con arreglos bidimensionales.


OBJETIVOS
Entender el funcionamiento de un apuntador y el concepto de aritmética de
apuntadores aplicado a un arreglo bidimensional.
Utilizar el programa de la práctica 7 de arreglo bidimensional para acceder
indirectamente a los datos de la matriz de temperatura.

MATERIAL
 1 microcontrolador PIC 18F4550
 1 sensor de temperatura LM35(Ver conexión de pines en Apéndice G)
MARCO TEORICO
Los apuntadores son un tipo particular de variable que almacena una dirección de memoria
y se ocupan para acceder de manera indirecta a variables. Los apuntadores cuentan con 2
operadores:
 El operador “*” que se coloca antes del nombre del apuntador, el cual devuelve el
valor de la variable que se apunta.
 El operador “&” que se coloca de igual manera, antes del nombre de la variable y
devuelve la dirección de memoria.
Para declarar un apuntador es necesario declararlo con el mismo tipo de variable que se
desea apuntar, es decir si la variable a es de tipo entero, el apuntador apuntoa también debe
ser declarado como entero. Se muestra a continuación la sintaxis de declaración de un
apuntador:
𝑖𝑛𝑡 ∗ 𝑛𝑜𝑚𝑏𝑟𝑒_𝑎𝑝𝑢𝑛𝑡𝑎𝑑𝑜𝑟 = 𝑣𝑎𝑟𝑖𝑎𝑏𝑙𝑒_𝑎𝑝𝑢𝑛𝑡𝑎𝑑𝑎;
Esto no significa que un apuntador sea de tipo entero, sólo le indica al compilador que el
valor que se desea apuntar es de ese tipo.
El nombre de un arreglo también es un apuntador que contiene la dirección de la primera
variable, para acceder a las diferentes variables de un arreglo se puede sumar un número
entero, es decir, la instrucción ∗ (𝑎𝑟𝑟𝑎𝑦 + 1) apuntará a la variable 2, siendo 𝑎𝑟𝑟𝑎𝑦 el
nombre de un arreglo. En el caso de un arreglo bidimensional la sintaxis de un apuntador que
contenga la variable de la primera fila y la primera columna es la siguiente:
∗ (∗ (𝑀 + 1) + 1)
Siendo M un arreglo bidimensional.

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y crear un
programa que obtenga datos del convertidor analógico-digital conectado a un sensor de
temperatura, ordenando estos datos en un arreglo bidimensional separando las muestras
según el día en que fueron tomadas. Además de mostrar el promedio de las temperaturas,
52
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

máximo y mínimo por día y finalmente el promedio total de todas las temperaturas, máximo
y mínimo de todas las temperaturas sensadas.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Sensado de temperatura con apuntadores USB
Define constante DIAS = 5
Define constante MEDICIONES = 5
Define constante TIEMPOMUESTREO = 1000
Inicio del programa
Imprime “Programa que trabaja temperaturas de varios días”
fila = 0
columna = 0
Mientras fila < DIAS
Mientras columna < MEDICIONES
Imprime “Temperatura día” fila+1 “mediciones” columna+1
Recibir paquete (ADC_ON, datoadc1, datoadc2)
dato = ( corrimiento 8 lugares a la izquierda de datoadc2) + datoadc1
*(*(temperatura + fila) + columna) = (5.0/1023.0)*100* dato
Imprime *(*(temperatura + fila) + columna)
promedio = promedio + *(*(temperatura + fila) + columna)
Esperar (TIEMPOMUESTREO)
columna = columna +1
fila = fila + 1
Fin de Mientras
Fin de Mientras
max = 0

53
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

mín = 0
fila = 0
columna = 0
Imprime “La matriz de temperaturas es:”
Mientras fila < DIAS
Imprime “Día” fila+1
*(promedios + fila) = 0
*(máximos + fila)= *(*(temperatura + fila))
*(mínimos + fila)= *(*(temperatura + fila))
Mientras columna < MEDICIONES
Imprime *(*(temperatura + fila) + columna)
Si *(*(temperatura + fila) + columna)> *(máximos + fila)
*(máximos + fila) = *(*(temperatura + fila) + columna)
Si *(*(temperatura + fila) + columna) < *(mínimos + fila)

*(mínimos + fila)= *(*(temperatura + fila) + columna)


Fin de Si
*(promedios + fila) = *(promedios + fila) + *(*(temperatura + fila) + columna)
columna = columna + 1
Fin de Mientras
*(promedios + fila) = *(promedios + fila)/ MEDICIONES
Imprime “Promedio día” fila+1 “es” *(promedios + fila)
Imprime “Máximo” *(máximos + fila)
Imprime “Mínimo” *(mínimos + fila)
fila = fila +1
Fin de Mientras
promedio = promedio /(DIAS*MEDICIONES)
Imprime “El promedio de TODAS las temperaturas es” promedio

54
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

fila = 0
max = *máximos
min = *mínimos
Mientras fila < DIAS
Si min > *(mínimos + fila)
min = *(mínimos + fila)
Si max < *(máximos + fila)
max= *(máximos + fila)
Fin de Si
fila = fila +1
Fin de Mientras
Imprime “La temperatura mayor es” max “la temperatura menor es” min

Fin del programa


La instrucción Recibir paquete (ADC, datoadc1, datoadc2) esta descrita en la biblioteca
“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐1, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐2);
La instrucción Esperar (TIEMPOMUESTREO) es una función en la biblioteca standard de
c, la cual le dice al sistema que espere un periodo de tiempo en milisegundos. El código
para esta instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑇𝐼𝐸𝑀𝑃𝑂𝑀𝑈𝐸𝑆𝑇𝑅𝐸𝑂);

55
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

18. Práctica 10. Estructuras


OBJETIVOS
Entender el funcionamiento de las estructuras en C y como acceder a sus variables.
Aplicar el concepto de estructuras y enumeración para desarrollar un programa capaz
de calcular el valor de una resistencia según los colores de sus franjas.
Ocupar el convertidor analógico-digital para leer el valor real de una resistencia
ocupando una resistencia de referencia de 10KΩ.

MATERIAL
 1 microcontrolador PIC 18F4550
 1 resistencia de 10KΩ.
 Resistencias de diferentes valores.
MARCO TEORICO
Una estructura es un tipo de dato que puede contener varias variables a la vez. Esto tiene la
finalidad de relacionar un conjunto de variables a un dato. En lenguaje C la sintaxis de una
estructura es la siguiente:
𝑠𝑡𝑟𝑢𝑐𝑡 𝑁𝑜𝑚𝑏𝑟𝑒_𝑑𝑒_𝑒𝑠𝑡𝑟𝑢𝑐𝑡𝑢𝑟𝑎{} ;
Dentro de los corchetes pueden ir variables de tipo entero, caracteres, etc. Esto permite
agrupar varios datos de un mismo problema. Se muestra a continuación un ejemplo simple
de estructura
𝑠𝑡𝑟𝑢𝑐𝑡 𝑎𝑙𝑢𝑚𝑛𝑜{
𝑐ℎ𝑎𝑟 𝑛𝑜𝑚𝑏𝑟𝑒[10];
𝑖𝑛𝑡 𝑐𝑎𝑙𝑖𝑓𝑖𝑐𝑎𝑐𝑖ó𝑛;
};
La estructura alumno contiene las variables calificación de tipo entero y nombre que es un
arreglo de 10 caracteres. Para acceder a la variable calificación, es necesario hacerlo mediante
la siguiente sintaxis:
𝑎𝑙𝑢𝑚𝑛𝑜 𝐽𝑢𝑎𝑛;
𝐽𝑢𝑎𝑛. 𝑐𝑎𝑙𝑖𝑓𝑖𝑐𝑎𝑐𝑖𝑜𝑛 = 10;
Se declara primero el nombre de mi variable del tipo “alumno”, es decir, la estructura que se
declaró con anterioridad. Debido a que calificación es una variable contenida en la estructura
alumno se accede mediante el nombre de la variable, seguido de un punto y la variable que
se desea modificar.

56
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Por otro lado, una enumeración permite ordenar un código ya que asocia un conjunto de
palabras a una serie de números consecutivos. La sintaxis en lenguaje C para una
enumeración es:
𝑒𝑛𝑢𝑚 𝑁𝑜𝑚𝑏𝑟𝑒{};
Dentro de los corchetes van nombres de lo que se desea enumerar separadas por comas. Se
muestra a continuación una enumeración simple:
𝑒𝑛𝑢𝑚 𝑎𝑙𝑢𝑚𝑛𝑜𝑠{
𝑀𝑎𝑟𝑖𝑜,
𝐿𝑢𝑖𝑠,
𝐺𝑎𝑏𝑟𝑖𝑒𝑙𝑎,
𝐸𝑙𝑒𝑛𝑎};
El programa asigna automáticamente el valor constante de 0 a Mario, 1 a Luis, 2 a Gabriela,
etc.

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y desarrollar
un programa que pregunte el color de las 4 franjas de una resistencia convencional y en base
a esto, calcular el valor de la resistencia en Ohms. Calcular además el valor máximo y
mínimo de la resistencia según el color de la franja de tolerancia. Finalmente utilizar el
convertidor analógico-digital del PIC para leer el valor real de la resistencia y mostrarlo en
pantalla. Todas las variables deben ser estar contenidas en una estructura llamada
“resistencia”.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.

Programa: Manejo de arreglos con comunicación USB


Define constante RESISTENCIAPRUEBA = 10000
Estructura resistencia
Entero franja1, franja2, franja3, resistenciatotal, valortolerancia, adc1,adc2
Real resistencia_real, voltaje
Caracter color1[10], color2[10], color3[10], tolerancia[10]

57
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Fin de estructura
Enumeración COLORES
NEGRO
CAFÉ
ROJO
NARANJA
AMARILLO
VERDE
AZUL
VIOLETA
GRIS
BLANCO
PLATA
ORO = 5
Fin de enumeración
Inicio del programa
Resistencia mi_resistencia
Imprime “Indique el color de la primera franja”
Lee color1
Imprime “Indique el color de la segunda franja”
Lee color2
Imprime “Indique el color de la tercera franja”
Lee color3
Imprime “Indique el color de la franja de tolerancia”
Lee tolerancia
franja1 = escaneocolor(color1) * 10
franja2 = escaneocolor(color2)
franja3 = 10^(escaneocolor(color3))

58
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Imprime “El valor de la primera franja es:” franja1


Imprime “El valor de la segunda franja es:” franja2
Imprime “El valor de la tercera franja es:” franja3
resistenciatotal = (franja1 + franja2)* franja3
Imprime “El valor de la resistencia total es” resistenciatotal
valortolerancia = 0.01*(escaneocolor(tolerancia))*resistenciatotal
Imprime “La resistencia puede variar entre” resistenciatotal – valortolerancia “y”
resistenciatotal + valortolerancia
Recibir paquete (ADC_ON, adc1, adc2)
voltaje = ((corrimiento 8 lugares a la izquierda de adc2) + adc1)*5/1023
resitencia_real = ((5 - voltaje)/voltaje) * RESITENCIAPRUEBA
Imprime “La resistencia medida es ” resistencia_real
Fin del programa
Inicio escaneocolor(caracter color[10])
colores mi_color
Si color[10] = “negro”
mi_color = NEGRO
Si color[10] = “cafe”
mi_color = CAFE
Si color[10] = “rojo”
mi_color = ROJO
Si color[10] = “naranja”
mi_color = NARANJA
Si color[10] = “amarillo”
mi_color = AMARILLO
Si color[10] = “verde”
mi_color = VERDE
Si color[10] = “azul”

59
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

mi_color = AZUL
Si color[10] = “violeta”
mi_color = VIOLETA
Si color[10] = “gris”
mi_color = GRIS
Si color[10] = “blanco”
mi_color = BLANCO
Si color[10] = “plata”
mi_color = PLATA
Si color[10] = “oro”
mi_color = ORO
Sino
mi_color = NEGRO
Fin de Si
Regresa mi_color
Fin escaneocolor(caracter color[10])

La instrucción Recibir paquete (ADC, adc1, adc2) esta descrita en la biblioteca


“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑎𝑑𝑐1, &𝑎𝑑𝑐2);
Información adicional
Para hacer la lectura de el valor de las resistencias es necesario un circuito divisor de
voltaje. A continuación se muestra el circuito con la tarjeta Miuva.

60
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura 18.1 Conexión del divisor de voltaje con tarjeta Miuva.

De igual manera se muestra a continuación la conexión con la tarjeta ATA-NQH.

Figura 18.1 Conexión del divisor de voltaje con tarjeta ATA-NQH.

61
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

19. Práctica 11. Memoria dinámica


OBJETIVOS
Entender el funcionamiento de la memoria dinámica en C.
Utilizar el programa de la práctica 5.2 de arreglo de temperaturas declarando el
número de mediciones durante la ejecución del programa.

MATERIAL
 1 microcontrolador PIC 18F4550
 1 sensor de temperatura LM35(Ver conexión de pines en Apéndice G)
MARCO TEORICO
La reserva de memoria dinámica permite al usuario definir la cantidad de variables que va a
ocupar durante la ejecución del programa. Para esto existen dos funciones importantes en C.
La primera es 𝑚𝑎𝑙𝑙𝑜𝑐 la cual tiene la siguiente sintaxis:
𝑡𝑖𝑝𝑜 ∗ 𝑎𝑝 = (𝑡𝑖𝑝𝑜 ∗ )𝑚𝑎𝑙𝑙𝑜𝑐(𝑡𝑎𝑚 ∗ 𝑒𝑠𝑝𝑎𝑐𝑖𝑜);
En donde:
𝑎𝑝 Es un apuntador definido anteriormente.
𝑡𝑖𝑝𝑜 Es el tipo de variable, ya sea entero, caracter, flotante, etc.
𝑡𝑎𝑚 Es el tamaño a reservar.
𝑒𝑠𝑝𝑎𝑐𝑖𝑜 Es la cantidad de espacio que ocupa la variable seleccionada. Usualmente se ocupa
la función sizeof(), la cual devuelve la cantidad de espacio del tipo de variable especificado.
Por ejemplo si se desea saber el tamaño que ocupa una variable de tipo flotante, se puede
saber mediante la instrucción 𝑠𝑖𝑧𝑒𝑜𝑓(𝑓𝑙𝑜𝑎𝑡).
Esta función genera un arreglo, el cual se asocia con el apuntador al que es asignado. El
acceso a estas variables es de manera indirecta.
La segunda función es 𝑓𝑟𝑒𝑒(𝑎𝑝) en dónde ap es el nombre del apuntador. Esta función libera
la memoria reservada y es necesario llamarla cuando se deje de ocupar el arreglo.

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y crear un
programa que pregunte cuantas mediciones de temperatura se harán, que tome ese número
de muestras y que las almacene en un arreglo de memoria dinámica. El programa debe
mostrar las temperaturas medidas y el promedio de estas.
En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más
avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del

62
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas


variables, sin embargo no debe cambiar el tipo de variable.

Programa: Manejo de memoria dinámica


Define constante TIEMPOMUESTREO = 1000
Inicio del programa
*aptemperaturas tipo real
Mediciones tipo entero
Promedio tipo real
Índice, datoadc1, datoadc2, datocompleto tipo entero
Imprime “Programa que trabaja temperaturas”
Imprime “Indique número de mediciones de temperatura”
Lee mediciones
*aptemperaturas = Reserva memoria dinámica de tamaño mediciones
Mientras índice < mediciones
Recibir paquete (ADC_ON, datoadc1, datoadc2)
datocompleto = ( corrimiento 8 lugares a la izquierda de datoadc2) + datoadc1
*(aptemperaturas + índice)= (5/1023) * 10 * datocompleto
Promedio = promedio + *(aptemperaturas + índice)
Imprime “La medición de temperatura ” índice + 1 “ es” *(aptemperaturas + índice)
Esperar (TIEMPOMUESTREO)
índice = índice + 1
Fin de Mientras
Promedio = Promedio / mediciones
Imprime “El promedio de temperaturas es de” Promedio
Liberar memoria
Fin del programa

63
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

La instrucción Recibir paquete (ADC, datoadc1, datoadc2) esta descrita en la biblioteca


“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐1, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐2);
La instrucción Esperar (TIEMPOMUESTREO) es una función en la biblioteca standard de
c, la cual le dice al sistema que espere un periodo de tiempo en milisegundos. El código
para esta instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑇𝐼𝐸𝑀𝑃𝑂𝑀𝑈𝐸𝑆𝑇𝑅𝐸𝑂);

64
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

20. Práctica 12. Archivos


OBJETIVOS
Entender el funcionamiento de archivos en C.
Desarrollar un programa que lea temperaturas de un archivo existente y cree un nuevo
archivo leyendo las temperaturas guardadas y nuevas lecturas con el sensor LM35
Utilizar el programa de la práctica 5.2 de arreglo de temperaturas.

MATERIAL
 1 microcontrolador PIC 18F4550
 1 sensor de temperatura LM35(Ver conexión de pines en Apéndice G)
MARCO TEORICO
El lenguaje de programación C permite la creación y lectura de archivos, esto con la finalidad
de obtener datos guardados con anterioridad o caso contrario, para almacenar nuevos datos.
Para manejar archivos, es necesario crear 2 variables; un apuntador de tipo FILE y un
apuntador de tipo caracter que contenga el nombre del archivo que se desea abrir. Por
ejemplo, si se desea abrir el archivo Mediciones.txt es necesario crear las siguientes
variables:
𝐹𝐼𝐿𝐸 ∗ 𝑀𝑖_𝑎𝑟𝑐ℎ𝑖𝑣𝑜;
𝑐ℎ𝑎𝑟 ∗ 𝑛𝑜𝑚𝑏𝑟𝑒 = "𝑀𝑒𝑑𝑖𝑐𝑜𝑛𝑒𝑠. 𝑡𝑥𝑡";
Para abrir un archivo en lenguaje C se utiliza la función 𝑓𝑜𝑝𝑒𝑛. La sintaxis de esta función
es:
𝑀𝑖_𝑎𝑟𝑐ℎ𝑖𝑣𝑜 = 𝑓𝑜𝑝𝑒𝑛(𝑛𝑜𝑚𝑏𝑟𝑒, "𝑥" );
Donde:
Mi_archivo es un apuntador hacia una variable de tipo FILE.
nombre es un apuntador hacia una variable de tipo caracter que contiene el nombre del
archivo a abrir.
x es un parámetro que le indica cómo debe manejar el archivo. Este puede ser:
w Archivo sólo de escritura (El archivo se crea en caso de que no exista)
r Archivo sólo de lectura (El archivo debe existir)
a Archivo de escritura agregando el dato al final del contenido
rt Archivo de lectura y escritura (El archivo debe existir)
wt Archivo de escritura y lectura (El archivo se crea en caso de que no exista)

65
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Todos los archivos deben cerrarse al final de cada programa, para esto es necesario utilizar
la función 𝑓𝑐𝑙𝑜𝑠𝑒, la cual tiene la siguiente sintaxis:
𝑓𝑐𝑙𝑜𝑠𝑒(𝑀𝑖_𝑎𝑟𝑐ℎ𝑖𝑣𝑜 );
Donde:
Mi_archivo es un apuntador hacia una variable de tipo FILE.
Para leer un dato de un archivo se ocupa la función "𝑓𝑠𝑐𝑎𝑛𝑓" (𝑓𝑖𝑙𝑒 𝑠𝑐𝑎𝑛𝑓), la cual es
bastante parecida a la función 𝑠𝑐𝑎𝑛𝑓, la sintaxis de esta función es:
𝑓𝑠𝑐𝑎𝑛𝑓(𝑀𝑖_𝑎𝑟𝑐ℎ𝑖𝑣𝑜, "%𝑓" , &𝑣𝑎𝑟);
Donde:
Mi_archivo es un apuntador hacia una variable de tipo FILE.
var es la variable que se desea leer.
El segundo parámetro indica el formato del dato a leer siendo f para flotante, d para entero
o c para caracter.
Esta función leerá la primera línea del archivo. En caso de ejecutarse de nuevo leerá la
siguiente línea del archivo, así sucesivamente hasta encontrar el caracter de final de línea
(\n).
Por otra parte, para escribir un dato en un archivo se ocupa la función
"𝑓𝑝𝑟𝑖𝑛𝑡𝑓" (𝑓𝑖𝑙𝑒 𝑝𝑟𝑖𝑛𝑡𝑓), la cual tiene la siguiente sintaxis:
𝑓𝑝𝑟𝑖𝑛𝑡𝑓(𝑀𝑖_𝑎𝑟𝑐ℎ𝑖𝑣𝑜, "𝐷𝑎𝑡𝑜𝑠 𝑎 𝑒𝑠𝑐𝑟𝑖𝑏𝑖𝑟" );
Donde:
Mi_archivo es un apuntador hacia una variable de tipo FILE.
El segundo parámetro contiene la cadena de caracteres a escribir en el archivo.

PSEUDOCÓDIGO
El código consiste en hacer uso de las funciones ya incluidas en las bibliotecas y crear un
programa que lea 5 mediciones de temperatura de un archivo llamado “TempMedidas”, que
las almacene en un arreglo de tamaño 10. El programa debe tomar 5 muestras más con ayuda
del microcontrolador y finalmente debe guardar todas las mediciones y el promedio de todas
en un nuevo archivo llamado “Temperaturas”. Además, el programa debe mostrar las
temperaturas y el promedio de estas en la consola.
Antes de iniciar el programa es necesario crear el archivo “TempMedidas” con extensión .txt
y guardarlo en la carpeta que contiene el código principal en el Visual Studio. Este archivo
debe contener las temperaturas 25, 31, 27, 26, 28 en diferentes líneas.

66
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

En el pseudocódigo se encuentran instrucciones subrayadas que corresponden a temas más


avanzados, por lo que el código es proporcionado al final de esta sección. Para evitar
cualquier ambigüedad con la declaración de variables, los nombres de las variables del
pseudocódigo se encuentran en cursiva, el usuario puede cambiar el nombre de estas
variables, sin embargo no debe cambiar el tipo de variable.
Programa: Manejo de archivos en C
Define constante MED_TOTALES = 10
Define constante MED_ARCHIVOS = 5
Define TIEMPOMUESTREO = 1000
Inicio del programa
archivo_lectura tipo Archivo
archivo_escritura tipo Archivo
temp[MED_TOTALES] tipo real
promedio tipo real
indice, datoadc1, datoadc2, datocompleto tipo entero
Imprime “Programa que trabaja temperaturas y las almacena en un archivo”
Archivo_lectura = Abrir archivo (nombre_lectura, formato lectura)
Imprime “Leyendo datos de archivo”
Mientras índice < MED_ARCHIVOS
Lee de archivo Temp[Indice]
índice = índice +1
Fin de Mientras
Cerrar archivo archivo_lectura
archivo_escritura = Abrir archivo (nombre_escritura, formato escritura)
índice = 0
Mientras índice < MED_ARCHIVOS
Promedio = Promedio + temp[índice]
Imprime en archivo “La medición de temperatura” índice + 1 “es” temp[índices]
Imprime “La medición de temperatura” índice + 1 “es” temp[índices]

67
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

índice = índice +1
Fin de Mientras
índice = MED_ARCHIVOS
Mientras índice < MED_TOTALES
Recibir paquete (ADC_ON, datoadc1, datoadc2)
datocompleto = ( corrimiento 8 lugares a la izquierda de datoadc2) + datoadc1
temp[índices] =(5/1023) * 10 * datocompleto
Promedio = promedio + temp[índices]
Imprime “La medición de temperatura ” índice + 1 “ es” temp[índices]
Imprime en archivo “La medición de temperatura ” índice + 1 “ es” temp[índices]
índice = índice + 1
Esperar (TIEMPOMUESTREO)
Fin de Mientras
Promedio = Promedio / MED_TOTALES
Imprime “El promedio de temperaturas es de” Promedio
Imprime en archivo “El promedio de temperaturas es de” Promedio
Cerrar archivo archivo_escritura
Fin del programa
La instrucción Recibir paquete (ADC, datoadc1, datoadc2) esta descrita en la biblioteca
“Comunicación.h”, esta función tiene tres parámetros debido al funcionamiento del
convertidor analógico-digital. El primer parámetro habilita el convertidor, mientras que los
otros dos almacenan el dato leído. La instrucción es:
𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒(𝐴𝐷𝐶_𝑂𝑁, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐1, &𝑑𝑎𝑡𝑜𝑎𝑑𝑐2);
La instrucción Esperar (TIEMPOMUESTREO) es una función en la biblioteca standard de
c, la cual le dice al sistema que espere un periodo de tiempo en milisegundos. El código
para esta instrucción es:
𝑆𝑙𝑒𝑒𝑝(𝑇𝐼𝐸𝑀𝑃𝑂𝑀𝑈𝐸𝑆𝑇𝑅𝐸𝑂);

68
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice A. Circuito y Tarjetas de desarrollo


Para realizar todas las prácticas descritas en este manual se ocupó el PIC 18F4550, se pueden
desarrollar todas las prácticas armando el circuito correspondiente o si se prefiere puede
adquirir una tarjeta de desarrollo. Las tarjetas con las que se desarrollaron las prácticas son
las siguientes:
 Miuva de la empresa Intesc.
 ATA-NQH 0714
Se explicará a continuación la construcción del circuito y una descripción detallada de cada
tarjeta de desarrollo resaltando sus diferencias.

Construcción de circuito.
El circuito con el que funciona el microcontrolador es simple y de fácil construcción, para
armarlo se necesitan los siguientes componentes:
 1 microcontrolador PIC 18F4550 de 40 Pines.
 1 cristal de 20 MHz
 2 capacitores de 22 pF
 1 capacitor de 100 nF
 1 capacitores de 1 µF
 1 botón de 2 pines
 1 resistencia de 100 KΩ
 1 LED
 1 Protoboard
El microcontrolador implementado en estas prácticas tiene varias características que
permiten la interacción e interpretación de diferentes tipos de datos. Se enlistan algunas de
las características importantes en la figura A.1
Característica Ubicación
3 Interrupciones externas RB0, RB1 y RB2
4 Módulos TIMER -
2 Módulos comparación/captura/PWM RC1 y RC2
Convertidor A/D de 10 bits 13 canales distribuidos en puerto A y B
1 modulo USB RD4 y RD5
Puerto bidireccional de 8 bits Puerto A
Puerto bidireccional de 8 bits Puerto B
Puerto bidireccional de 7 bits Puerto C
Puerto bidireccional de 8 bits Puerto D
Puerto bidireccional de 4 bits Puerto E
Figura A.1. Características del microcontrolador PIC 18F4550.

El diagrama del circuito se muestra en la figura A.2

69
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura A.2. Circuito básico para el funcionamiento del PIC 18F4550.

El componente etiquetado como J1 es en realidad un cable USB, es necesario cortar en un


extremo el conector y pelar los 4 hilos que contiene. A continuación en la figura A.3 se
muestra el color que corresponde a D+, D-, Vbus y GND.

Figura A.3. Nomenclatura del cable USB.

Este diagrama fue elaborado en el software DipTrace V2.4 edición Freeware. Si se desea
armar el circuito en lugar de adquirir una tarjeta, será necesario ocupar el código y la
configuración para la ATA-NQH 0714 ya que es esencialmente el circuito de esta placa.

70
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Tarjeta de desarrollo Miuva.

Se muestran las características de esta tarjeta en la siguiente figura.

Componente Característica
1 Microcontrolador PIC18F4550
1 Cristal oscilador 8Mhz
1 conexión USB Puerto micro USB
1 LED RGB Conectado a los pines E0, E1 y E2
1 Botón Conectado al pin C0
1 Quemador integrado Compatible con el programador PicKit2
1 Cristal oscilador 20MHz para el quemador
1 Microcontrolador PIC18F2550 que funciona como quemador
1 Entrada para LCD Pines hembra conectados al puerto D
1 Potenciómetro de contraste Para controlar el contraste de la LCD
8 Pines tipo M Conectados al Puerto B
6 Pines tipo M Conectados al Puerto A(A0-A5)
4 Pines tipo F Conectados al puerto C(C1-C4)
8 Pines tipo M Conectados al Puerto D
1 Botón de RESET Para reiniciar el microcontrolador
1 Selector Permite activar el puerto USB conectado al
PIC 18F4550 o al quemador (PIC 18F2550)
Figura A.4. Características de la placa de desarrollo Miuva.

Se muestra además, el diagrama de la tarjeta de desarrollo con la conexión de todos sus


periféricos.

71
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura A.5. Diagrama general de tarjeta de desarrollo Miuva.

Esta tarjeta cuenta con un LED RGB el cual está conectado a 5 Volts y para encender el
LED es necesario mandar un 0 lógico lo cual ya está contemplado en el código del
microcontrolador. Se muestra la conexión de dicho LED en la figura A.6

Figura A.6. Conexión del LED RGB en la tarjeta Miuva.

La configuración del botón conectado al puerto C es normalmente abierto esto quiere decir
que siempre se lee un 0 lógico en la entrada PC0 a menos que se presione el botón. Se
muestra el esquemático de este botón.

Figura A.7. Conexión del botón pulsador en la tarjeta Miuva

Finalmente se muestre el direccionamiento del puerto para LCD en la figura A.8

72
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura A.8. Conexión del puerto para LCD en la tarjeta Miuva

Se puede observar que debido al direccionamiento de los pines del puerto, no se puede
manejar el LCD a 8 bits, esto se debe tomar en consideración cuando se trabaje con este
dispositivo.

Tarjeta de desarrollo ATA-NQH 0714.

De igual manera se muestran las características de esta tarjeta en la tabla que se muestra a
continuación.
Componente Característica
1 Microcontrolador PIC18F4550
1 Cristal oscilador 20Mhz
1 conexión USB Puerto micro USB o USB tipo B
1 LED Conectado a pin E1
2 Botones Conectado a los pines E0 y E2
8 LEDs Conectados directamente al puerto D
1 Entrada para LCD Pines hembra conectados al puerto D

73
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

2 Selectores del puerto D 2 pines Macho que permiten habilitar los


LEDs del puerto D o el LCD para cada uno.
2 Entradas para potenciómetros Conectados a los pines A1 y A3 (ADC)
1 Puerto de 5 Pines M Destinado para programación por ICSP
2 Salidas del módulo PWM Conectados a los pines C1 y C2
1 Puerto de 10 Pines M Conectado al Puerto A, VCC y GND
1 Puerto de 10 Pines M Conectado al Puerto B, VCC y GND
1 Puerto de 10 Pines M Conectado al Puerto C, VCC y GND
1 Puerto de 10 Pines M Conectado al Puerto D, VCC y GND
1 Puerto de 14 Pines F Conectado al Puerto B y GND adaptado
para conectar un Dipswitch
1 Botón de RESET Para reiniciar el microcontrolador
Figura A.9. Características generales de la tarjeta ATA-NQH

Principales diferencias entre ambas tarjetas.


La principal diferencia entre estas 2 tarjetas se encuentra en el cristal oscilador, mientras que
para la tarjeta Miuva es de 8 MHz, para la tarjeta ATA-NQH 0714 es de 20 MHz. Es
importante tener siempre esta diferencia en cuenta debido a que si no se programa el código
apropiado la tarjeta no será reconocida por la computadora a la hora de tratar de hacer la
conexión USB.
Otra diferencia importante entre las tarjetas se encuentra en el puerto E. Mientras que para la
tarjeta Miuva este puerto contiene un LED RGB, es decir, los 3 pines configurados como
salidas; la tarjeta ATA-NQH 0714, por otra parte, tiene conectado un LED y dos botones, en
otras palabras, 1 pin de entrada y 2 pines de salida.
La conexión del LED RGB de la tarjeta Miuva es a 5V en la parte positiva y al
microcontrolador en la parte negativa, esto provoca que para poder apagar el LED RGB se
mande un 1 lógico (esto es 5V a la salida), mientras que para apagarlos se debe mandar un 0
lógico. Esto no ocurre con el LED de la tarjeta ATA-NQH 0714 la cual tiene la parte positiva
al microcontrolador y la negativa a 0. Para no cambiar los pseudocódigos de este manual, los
códigos de las 2 diferentes tarjetas permiten encender los LEDS mandado un 1 lógico.
Finalmente la diferencia más obvia es el hecho que la tarjeta ATA-NQH 0714 tiene 8 pines
conectados directamente al puerto D por lo que no es necesario conectar más LEDs en las
prácticas que ocupen este puerto como salidas a LEDs. Por otro lado la tarjeta Miuva no
cuenta con estos LEDs por lo que es necesario conectar 8 LEDs.

74
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice B. Bits de configuración (PCWHD)


El programa del microcontrolador fue desarrollado en el programa PCWHD Compiler
versión 4.114(PIC C). En este compilador es necesario agregar los bits de configuración
(también llamados fusibles o fuses) al inicio de cada código, los cuales indican información
importante sobre algunas funciones del microcontrolador.
A continuación se enlistan algunas de estas instrucciones y su funcionamiento.
Instrucción Descripción
PUT Temporizador por encendido. Permite un
retardo por cierto tiempo al energizar el
microcontrolador como medida de
precaución dejando que la fuente de
alimentación se estabilice.
HSPLL Cristal resonador de alta velocidad con PLL
activado. Se activa cuando se quiere trabajar
arriba de los 4MHz.
NOWDT Deshabilitar perro guardián (En la literatura
se le llama también centinela o simplemente
guardián). Se trata de una característica de
seguridad que impide que el
microcontrolador se quede bloqueado en un
ciclo infinito, reseteando el dispositivo.
NOPROTECT Deshabilitar protección. Permite que el
código en el microcontrolador pueda ser
extraído desde la computadora, es decir,
permite la lectura del código.
NOLVP Deshabilitar programación de bajo voltaje.
NODEBUG Deshabilitar modo depuración.
USBDIV Reloj de USB. Define la fuente del reloj del
USB como el PLL dividido entre 2.
PLL# Pre escalador. Define cuantas veces se
divide la entrada del oscilador, donde el #
puede ser 1,2,3,4,5,6,10,12 dependiendo del
cristal que se ocupe, ya que siempre se debe
cumplir la siguiente condición:
𝐹𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎𝑐𝑟𝑖𝑠𝑡𝑎𝑙
= 4𝑀𝐻𝑧
#𝑃𝑟𝑒𝑒𝑠𝑐𝑎𝑙𝑎𝑑𝑜𝑟
CPUDIV1 Desactiva el Post escalador.
VREGEN Regulador activado. Habilita el regulador de
voltaje del USB.
NOXINST Deshabilitar modo de direccionamiento
indexado.
Figura B.1. Bits de configuración para el microcontrolador

75
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Estos bits de configuración ya se encuentran incluidos en el código proporcionado para el


microcontrolador, se recomienda tener cuidado en caso de que se modifiquen estas
instrucciones debido a que pueden causar problemas en la comunicación.

76
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice C. Código del Microcontrolador (PCWHD).


Se dividen los códigos para las dos tarjetas de desarrollo con una reseña al final sobre los
cambios que se hacen de manera general. El código recibe y manda 5 datos de tipo entero en
un arreglo unidimensional. Dentro de los 5 datos se ocupó el primero (nombrado dentro del
código datos [0]) como la variable de control, es decir, el dato que le indica al
microcontrolador como debe interpretar los demás datos contenidos en el arreglo. Las
funciones del microcontrolador están organizadas de la siguiente manera:
 Datos [0] = 0. Esta opción deshabilita todas las funciones del microcontrolador, esto
quiere decir que apaga el LED del puerto E, deshabilita el módulo de conversión
analógica-digital, apaga los módulos de PWM.
 Datos [0] = 1. Habilita la función más simple del microcontrolador, la cual, prende y
apaga el LED conectados al puerto E. La variable que controla esta función es datos
[1], Si se manda un 1 se activara el LED. Para apagarlo se debe mandar un 0.
 Datos [0] = 2. Configura el puerto B como salida y al mismo tiempo manda el dato
entero guardado en la variable datos [1] a este puerto. Este dato llega en su valor
binario al puerto, siendo B0 el bit menos significativo y B7 el bit más significativo.
 Datos [0] = 3. Configura el puerto D como salida y manda el dato entero guardado
en la variable datos [1] a este puerto. Este dato se interpreta en su forma binaria
siendo D0 el bit menos significativo y D7 el bit más significativo.
 Datos [0] = 4. Configura el puerto B como entrada y guarda el dato que se encuentra
en este puerto en la variable datos [1]. Al guardar el dato en una variable de tipo
entero, el dato se convierte de binario a decimal.
 Datos [0] = 5. Configura el puerto D como entrada y guarda el dato que se
encuentra en este puerto en la variable datos [1]. Al guardar el dato en una variable
de tipo entero, el dato se convierte de binario a decimal.
 Datos [0] = 6. Configura el pin A0 como entrada y habilita el convertidor
analógico-digital del PIC. Debido a que es convertidor de 10 bits, se guardan los
primeros ocho bits menos significativos en la variable datos [1] y los dos últimos
bits más significativos en la variable datos [2].
 Datos [0]= 7. Habilita el módulo de PWM CCP1 del PIC al rango de frecuencias
más bajo6 posible para la función utilizada. Este módulo se encuentra conectado al
pin C2. Mediante las variables datos [1] y datos [2] se modifica la frecuencia del
módulo y el porcentaje de ciclo de trabajo. Como medida de seguridad desactiva el
módulo CCP2.

6
En el apéndice G se muestra el rango de frecuencias entre las diferentes opciones de PWM

77
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

 Datos [0]= 8. Habilita el módulo de PWM CCP2 del PIC al rango de frecuencias
más bajo posible para la función utilizada. Este módulo se encuentra conectado al
pin C1. Mediante las variables datos [1] y datos [2] se modifica la frecuencia del
módulo y el porcentaje de ciclo de trabajo. De igual manera desactiva
automáticamente el módulo CCP1.
 Datos [0]= 9. Habilita el módulo de PWM CCP1 del PIC a un rango de frecuencias
medio, aunque no alcanza ni la frecuencia más alta, ni la más baja. Este módulo se
encuentra conectado al pin C2. Mediante las variables datos [1] y datos [2] se
modifica la frecuencia del módulo y el porcentaje de ciclo de trabajo. Como medida
de seguridad desactiva el módulo CCP2.
 Datos [0]= 10. Habilita el módulo de PWM CCP2 del PIC a un rango de
frecuencias medio, aunque no alcanza ni la frecuencia más alta, ni la más baja. Este
módulo se encuentra conectado al pin C1. Mediante las variables datos [1] y datos
[2] se modifica la frecuencia del módulo y el porcentaje de ciclo de trabajo. De
igual manera desactiva automáticamente el módulo CCP1
 Datos [0]=11. Habilita el módulo de PWM CCP1 del PIC al rango de frecuencias
más alto posible por la función utilizada. Este módulo se encuentra conectado al pin
C2. Mediante las variables datos [1] y datos [2] se modifica la frecuencia del
módulo y el porcentaje de ciclo de trabajo. Como medida de seguridad desactiva el
módulo CCP2.
 Datos [0]= 12. Habilita el módulo de PWM CCP2 del PIC al rango de frecuencias
más alto posible por la función utilizada. Este módulo se encuentra conectado al pin
C1. Mediante las variables datos [1] y datos [2] se modifica la frecuencia del
módulo y el porcentaje de ciclo de trabajo. De igual manera desactiva
automáticamente el módulo CCP1
 Datos [0] = 13. Desactiva ambos módulos de PWM.
 Datos [0] = 14. Manda el estado del botón conectado a C0 o a E0 según la tarjeta de
desarrollo que se ocupe.
 Datos [0] = 15. Configura los puertos B y D como salida y manda al mismo tiempo
los datos contenidos en las variables datos[1] y datos[2] al puerto B y D
respectivamente.
 Datos [0] = 16. Configura el pin A5 como salida y recibe en la variable datos[1] un
valor entre 0 a 255 que controla una señal de 50Hz con un tiempo activo de 0.5ms a
2ms siendo 0 el valor mínimo y 255 el valor máximo. Esta señal se describió de esta
manera para controlar un servo motor.
 Datos [0] = 17. Manda el estado del botón conectado a E2 (Esta opción sólo es
válida en la tarjeta ATA-NQH 0714 )

Tarjeta Miuva
Se muestra el código que se ocupó para el desarrollo de todas las prácticas contenidas en este
manual.
#include <18F4550.h>
#device ADC=10 //Define ADC a 10 bits

78
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

#fuses
PUT,HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL2,CPUDIV1,
VREGEN,NOXINST
//El PLL2 es porque el cristal de 8MHz entre 2 = 4, siempre debe dar 4 con cualquier cristal
#use delay(clock=48,000,000

/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines. For dynamic configuration of the CCS Library
// for your application several defines need to be made. See the comments
// at usb.h for more information. Have some fun.
//
/////////////////////////////////////////////////////////////////////////////
#define USB_HID_DEVICE FALSE
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK
#define USB_EP1_TX_SIZE 10
#define USB_EP1_RX_SIZE 10

#include <pic18_usb.h>
#include <PicUSB.h>
#include <usb.c>
/*#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)*/

int datos[10];
int16 valord; //Para la conversion A/D de 10 bits
void main(void) //int es de 8 bits...
{
//Instrucciones del PWM

output_low(PIN_C2);
output_low(PIN_C1);

//////////////////////////////////
setup_adc_ports(NO_ANALOGS); //digitales los pines

output_high(PIN_E1); //enciende el led al conectar el pic


usb_init(); //inicializamos el USB
usb_task(); //habilita periferico usb e interrupciones
usb_wait_for_enumeration();

79
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

output_low(PIN_E1); // se apaga el led al existir comunicación usb


delay_ms(300);
output_high(PIN_E1);
delay_ms(300);
output_low(PIN_E1);
delay_ms(300);
output_high(PIN_E1);
while (TRUE)
{
if(usb_enumerated()) //si el PicUSB está configurado
{
if (usb_kbhit(1)) //si el endpoint de salida contiene datos del host
{
usb_get_packet(1, datos, 5);
switch(datos[0])
{
case 0: output_high(PIN_E0);//Apaga todos los LEDS
output_high(PIN_E1);
output_high(PIN_E2);
output_D(0x00); //Puerto D=0
output_B(0x00); //Puerto B=0
setup_adc(ADC_OFF);//Apaga ADC
setup_ccp1(CCP_OFF);//Deshabilita modulos CCP
setup_ccp2(CCP_OFF);
break;
case 1: if(datos[1]==0)
{
output_high(PIN_E0);
}
else if(datos[1]==1)
{
output_low(PIN_E0);
}
else if(datos[1]==2)
{
output_high(PIN_E1);
}
else if(datos[1]==3)
{
output_low(PIN_E1);
}
else if(datos[1]==4)
{
output_high(PIN_E2);
}
else if(datos[1]==5)

80
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

{
output_low(PIN_E2);
}
break;
case 2: output_B(datos[1]);
break;
case 3: output_D(datos[1]);
break;
case 4: datos[1]= INPUT_B();
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
case 5: datos[1]= INPUT_D();
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
case 6: setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN4 | VSS_VDD);
set_adc_channel(datos[1]); //the next read_adc call will read channel
delay_us(10);
valord = read_adc(); //ADC de 10 bits (9:0)
datos[1]= valord; //manda 8 bits menos sign. en datos[1] y
datos[2]= valord >> 8;
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
case 7: setup_ccp2(CCP_OFF);
setup_ccp1(CCP_PWM); //Enciende el CCP1
setup_timer_2(T2_DIV_BY_16,datos[1],1); //Frecuencia maxima
set_pwm1_duty(datos[2]);
break;
case 8: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,datos[1],1); //Frecuencia maxima
set_pwm2_duty(datos[2]);
break;
case 9: setup_ccp2(CCP_OFF);
setup_ccp1(CCP_PWM); //Enciende el CCP1
setup_timer_2(T2_DIV_BY_4,datos[1],1); //Frecuencia media
set_pwm1_duty(datos[2]);
break;
case 10: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,datos[1],1); //Frecuencia media
set_pwm2_duty(datos[2]);
break;
case 11: setup_ccp2(CCP_OFF);
setup_ccp1(CCP_PWM); //Enciende el CCP1
setup_timer_2(T2_DIV_BY_1,datos[1],1); //Frecuencia baja

81
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

set_pwm1_duty(datos[2]);
break;
case 12: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,datos[1],1); //Frecuencia baja
set_pwm2_duty(datos[2]);
break;
case 13: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
break;
case 14: datos[1]= input(PIN_C0);
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
case 15: output_B(datos[1]);
output_D(datos[2]);
break;
case 16:
retp = datos[1];
retn = 1530 -(retp*6);
output_high(PIN_A5);
delay_us(490);
delay_us(retp);
delay_us(retp);
delay_us(retp);
delay_us(retp);
delay_us(retp);
delay_us(retp);
output_low(PIN_A5);
delay_us(18470);
delay_us(retn);
break;
default: output_B(0x00);
output_D(0x00);
}
}
}
}
}
Figura C.1. Código para la tarjeta Miuva.

Tarjeta ATA-NQH 0714


Se muestra el código que se ocupó para el desarrollo de todas las prácticas contenidas en este
manual.
#include <18F4550.h>
#device ADC=10 //Define ADC a 10 bits

82
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

#fuses
PUT,HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,
VREGEN,NOXINST
#use delay(clock=48,000,000) //Número de ciclos necesarios para que la instrucción delay
esté en milisegundos

/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines. For dynamic configuration of the CCS Library
// for your application several defines need to be made. See the comments
// at usb.h for more information. And have some fun
//
/////////////////////////////////////////////////////////////////////////////
#define USB_HID_DEVICE FALSE
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK
#define USB_EP1_TX_SIZE 10 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 10 //size to allocate for the rx endpoint 1 buffer

#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB
driver
#include <PicUSB.h> //Configuración del USB y los descriptores para este dispositivo
#include <usb.c> //handles usb setup tokens and get descriptor reports
/*#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)*/

int datos[10];
int16 valord; //Para la conversion A/D de 10 bits
void main(void) //int es de 8 bits...
{
//Instrucciones del PWM

output_low(PIN_C2);
output_low(PIN_C1);
output_D(0x00); //Manda a 0 el puerto D

//////////////////////////////////
setup_adc_ports(NO_ANALOGS); //digitales los pines

output_high(PIN_E1); //enciende el led al conectar el pic


usb_init(); //inicializamos el USB

83
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

usb_task(); //habilita periferico usb e interrupciones


usb_wait_for_enumeration();
output_high(PIN_E1); // se apaga el led al existir comunicación usb
delay_ms(300);
output_low(PIN_E1);
delay_ms(300);
output_high(PIN_E1);
delay_ms(300);
output_low(PIN_E1);

while (TRUE)
{
if(usb_enumerated()) //si el PicUSB está configurado
{
if (usb_kbhit(1)) //si el endpoint de salida contiene datos del host
{
usb_get_packet(1, datos, 5);
switch(datos[0])
{
case 0:
output_low(PIN_E1);//Apaga el LED independientemende de datos[1]
output_D(0x00); //Puerto D=0
output_B(0x00); //Puerto B=0
setup_adc(ADC_OFF);//Apaga ADC
setup_ccp1(CCP_OFF);//Deshabilita modulos CCP
setup_ccp2(CCP_OFF);
break;
case 1: if(datos[1]==0)
{
output_low(PIN_E1);
}
else if(datos[1]==1)
{
output_high(PIN_E1);
}

break;
case 2: output_B(datos[1]);
break;
case 3: output_D(datos[1]);
break;
case 4: datos[1]= INPUT_B();
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
case 5: datos[1]= INPUT_D();
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);

84
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

break;
case 6: setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN4 | VSS_VDD);
set_adc_channel(datos[1]); //the next read_adc call will read channel
delay_us(10);
valord = read_adc(); //ADC de 10 bits (9:0)
datos[1]= valord; //manda 8 bits menos sign. en datos[1] y
datos[2]= valord >> 8;
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
case 7: setup_ccp2(CCP_OFF);
setup_ccp1(CCP_PWM); //Enciende el CCP1
setup_timer_2(T2_DIV_BY_16,datos[1],1); //Frecuencia alta
set_pwm1_duty(datos[2]);
break;
case 8: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,datos[1],1); //Frecuencia alta
set_pwm2_duty(datos[2]);
break;
case 9: setup_ccp2(CCP_OFF);
setup_ccp1(CCP_PWM); //Enciende el CCP1
setup_timer_2(T2_DIV_BY_4,datos[1],1); //Frecuencia media
set_pwm1_duty(datos[2]);
break;
case 10: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,datos[1],1); //Frecuencia media
set_pwm2_duty(datos[2]);
break;
case 11: setup_ccp2(CCP_OFF);
setup_ccp1(CCP_PWM); //Enciende el CCP1
setup_timer_2(T2_DIV_BY_1,datos[1],1); //Frecuencia baja
set_pwm1_duty(datos[2]);
break;
case 12: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,datos[1],1); //Frecuencia baja
set_pwm2_duty(datos[2]);
break;
case 13: setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
break;
case 14: datos[1]= input(PIN_E0);
if (datos[1]==1){datos[1]=0;}
else if (datos[1]==0){datos[1]=1;}

85
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);


break;
case 15: output_B(datos[1]);
output_D(datos[2]);
break;
case 16:
retp = datos[1];
retn = 1530 -(retp*6);
output_high(PIN_A5);
delay_us(490);
delay_us(retp);
delay_us(retp);
delay_us(retp);
delay_us(retp);
delay_us(retp);
delay_us(retp);
output_low(PIN_A5);
delay_us(18470);
delay_us(retn);
break;
case 17: datos[1]= input(PIN_E2);
if (datos[1]==1){datos[1]=0;}
else if (datos[1]==0){datos[1]=1;}
usb_put_packet(1, datos, 5, USB_DTS_TOGGLE);
break;
default: output_B(0x00);
output_D(0x00);
}
}
}
}
}

Figura C.2. Código para la tarjeta ATA-NQH 0714.

Diferencias entre códigos


Las diferencias principales entre códigos se muestran se muestran en la figura C.3.
Tarjeta Miuva Tarjeta ATA-NQH 0714
 Puerto E:  Puerto E:
Está conectado a un LED RGB a Está conectado a 2 botones en E0 y
voltaje, es decir que si se desea E2 y a un LED en E1 a tierra, es
apagar este LED se deben mandar decir que para prenderlo se debe
un 0 lógico al puerto. Por lo tanto la mandar un 1 lógico. Por lo tanto
opción datos [0] = 1 permite datos [0]=1 sólo enciende el LED
encender estos 3 LEDs mediante en E1.

86
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

los valores 1,3 y 5 y apagarlos con


los valores 0,2 y 4 respectivamente.
 Botones pulsadores:  Botones pulsadores:
Tiene un botón pulsador Tiene dos botones pulsadores
normalmente abierto conectado en normalmente cerrados conectados
el puerto C, el pin 0. Para leer el en el puerto E, en el pin 0 y 2. Para
dato se ocupa la opción datos[0]=14 leer el dato se ocupa la opción
datos[0]=14 y datos[0]=16
Figura C3. Principales diferencias entre códigos

Como se puede observar los códigos permiten encender los LEDS en el puerto E de cualquier
tarjeta mandando un 1 independientemente de su conexión. Lo mismo ocurre con los botones
pulsadores, leyendo un 0 cuando no están presionados.

87
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice D. Programador del microcontrolador


Para programar el microcontrolador es necesario el software PicKit2 y un programador
compatible con este software, para el caso de la tarjeta Miuva este programador viene
incluido en la tarjeta. El programa reconoce automáticamente el microcontrolador, en caso
de que no lo haga, se puede configurar la familia de PIC con la que se trabaja en el menú
“Device Family”.

Figura D.1. Ventana del programa PicKit2.

La figura D.1 se muestra la ventana principal del programa PicKit2 en su versión 2.6, esta
versión fue la ocupada para programar todos los ejercicios descritos en este manual.
Para programar el microcontrolador se deben seguir los siguientes pasos:
1. Importar el archivo del programa (con extensión .HEX) que se desea quemar, para
esto se selecciona la opción Importar, en el menú Archivo.
2. Una vez importado el archivo se da click en el botón Escribir.

88
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice F. Compilador para el microcontrolador (PIC C)


El compilador ocupado para el desarrollo de este manual fue el PCWHD Compiler, también
conocido como PIC C Compiler. Se muestra en la figura F.1 la pantalla de inicio del programa

Figura F.1 Ventana principal del compilador PIC C

Existen varias formas de crear un proyecto en este compilador, se muestra a continuación


una forma simple de hacerlo:
I. Dar click en el ícono de la carpeta (icono ubicado en la parte superior izquierda),
seleccionar “New” y seleccionar la opción “Proyect Wizard”.

II. Se selecciona la ubicación dónde se guardará el proyecto y se elige un nombre

89
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

III. Emergerá una pantalla que permite configurar el compilador para el PIC a ocupar.
Sin embargo el código proporcionado en el apéndice C contiene las debidas
configuraciones, por lo que se da click en Ok, sin importar los datos que contenga.

90
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

IV. El compilador generará una biblioteca por default con las configuraciones
preestablecidas.

V. Se borra todo el código contenido en este archivo y se escribe el código descrito en


el Apendice C.

VI. A continuación es necesario agregar la biblioteca “PicUSB.h”, está biblioteca


contiene los descriptores para este dispositivo y configura el puerto USB. Este archivo
no está descrito en el manual, pero será proporcionado con éste. Para agregarla debe
estar guardada en la misma carpeta del proyecto, posteriormente se da click en la
pestaña lateral llamada “Files”, se da click derecho sobre la carpeta “Source” y se
selecciona la opción “Add Document”

91
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

VII. Una vez agregado, el archivo “PicUSB”, éste debe aparecer en la carpeta
“Documentation”

VIII. Finalmente se procede a compilar el archivo seleccionando la pestaña “Compile” y el


ícono “Compile”

92
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

IX. Una vez hecho esto, se puede utilizar el archivo .HEX (generado en la carpeta del
proyecto) el cual se carga en el programador PicKit 2.

93
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice G. Periféricos del microcontrolador y dispositivos


externos.
Convertidor analógico-digital.
El microcontrolador PIC 18F4550 cuenta con un convertidor analógico digital de 10 bits
integrado el cual permiten interpretar sensores de temperatura, de corriente, de campo
magnético (efecto hall) o simplemente un potenciómetro. Este periférico lee la dirección A07
y lo convierte a un valor entre 0 y 1023 (Este valor se deduce de la siguiente relación 210 =
1024 es decir se tienen 1024 combinaciones posibles).
Debido a que es un convertidor de 10 bits se deben ocupar dos bytes para mandar el dato del
microcontrolador a la computadora, para interpretar este dato es necesario hacer un
corrimiento de bits que indique que en el primer byte se mandan los 8bits menos
significativos del dato leído, mientras que en el segundo se mandan los 2 bits más
significativos como se muestra en la Figura G.1 con un ejemplo.

Figura G.1. Organización de los Bits en la recepción de datos

Módulos de PWM (Modulación de ancho de pulso).


La modulación por ancho de pulso (PWM) es una técnica en la cual se modifica el ciclo de
trabajo (Duty Cicle) de una señal periódica, dicho de otra manera se modifica el tiempo que
la señal está en alto. En el caso del PIC es una señal cuadrada, ya sea para transmitir
información o para controlar la energía aplicada (a un motor por ejemplo). Se muestra en la

7
En realidad el microcontrolador puede leer 13 diferentes canales para el mismo convertidor, incluso puede
tener un voltaje de referencia para leer valores negativos. Para más información consulte la hoja de
especificaciones del microcontrolador.

94
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

figura G.2 tres diferentes variaciones de ciclo de trabajo, la primera corresponde a 5%, la
segunda a 50% y la última a 90%.

Figura G.2. Modulación por ancho de pulso

El microcontrolador PIC 18F4550 cuenta con dos módulos CCP (Captura, comparación y
PWM). Ambos módulos funcionan con el temporizador TIMER 2, el cual regula la
frecuencia de trabajo. El software PIC C utiliza la siguiente función para controlar el
temporizador TIMER 2:
𝑠𝑒𝑡𝑢𝑝_𝑡𝑖𝑚𝑒𝑟_2(𝑚𝑜𝑑𝑜, 𝑝𝑒𝑟𝑖𝑜𝑑𝑜, 𝑝𝑜𝑠𝑡𝑒𝑠𝑐𝑎𝑙𝑎𝑑𝑜𝑟);
En esta función los parámetros importantes son el periodo y el modo. El periodo es un
número de tipo entero entre 10 y 254 que indica cuando reinicia el reloj, siendo 255 es el
periodo más largo y 10 el periodo más corto. El modo, por otro lado, puede ser:
 𝑇2_𝐷𝐼𝑉_𝐵𝑌_16. Con este parámetro se logra el rango de frecuencias más bajo, que
va de 3KHz, hasta 68KHz aproximadamente.
 𝑇2_𝐷𝐼𝑉_𝐵𝑌_4. Con el que se logra un rango de frecuencias intermedio entre 12kHz
y 270KHz aproximadamente
 𝑇2_𝐷𝐼𝑉_𝐵𝑌_1. Parámetro con el cual se alcanza el rango de frecuencias más alto, el
cual es de 45KHz a 2MHz aproximadamente.
Se muestra en la figura G.3 la gráfica que relaciona el parámetro que modifica el periodo
con las frecuencias alcanzables para el rango bajo.

95
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura G.3. Gráfica de relación entre el parámetro leído y el rango de frecuencia bajo.

Se muestra en la figura G.4 la gráfica que relaciona el parámetro que modifica el periodo
con las frecuencias alcanzables para el rango medio.
300000
273000

250000

200000
FRECUENCIA (HZ)

142900
150000

96700
100000
73200
58830
49200
42260
50000 37040 32890
29750 27030
24750 22900 21280
19840 18620 17540 16580 15700
14900 14200 13570 13000 12450 11960

0
0 50 100 150 200 250 300
PARÁMETRO(0-250)

Figura G.4. Gráfica de relación entre el parámetro leído y el rango de frecuencia medio.

Se muestra en la figura G.5 la gráfica que relaciona el parámetro que modifica el periodo
con las frecuencias alcanzables para el rango alto.

96
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

2500000

2180000

2000000

1500000
FRECUENCIA (HZ)

1000000

571700

500000 387100
292500
235300196700
169000148200131900
118800108100 99180 91620 85120
79470 74560 70180 66310 62830 59710 56880 54300 51950 49800 47810

0
0 50 100 150 200 250 300
PARÁMETRO(0-250)

Figura G.5. Gráfica de relación entre el parámetro leído y el rango de frecuencia más alto.

Para modificar el ciclo de trabajo se ocupa la siguiente función:


𝑠𝑒𝑡_(𝑝𝑤𝑚1_𝑑𝑢𝑡𝑦 (𝒗𝒂𝒍𝒐𝒓) );
Donde el parámetro valor mueve el ciclo de trabajo. Este valor depende del parámetro que
modifica la frecuencia en la función anterior. Es decir, si la frecuencia elegida es 50, el
valor debe ser un número entre 50 y 0, siendo 50 el 100% de ciclo de trabajo y 0 el 0% del
ciclo de trabajo.

Pantalla de cristal líquido.


La pantalla de cristal mejor conocida como LCD por sus siglas en inglés (Liquid Crystal
Display) es un dispositivo que permite mandar caracteres, palabras y algunos incluso gráficos
creando así una interfaz para el usuario. El LCD ocupado en este manual es de tipo 16x2, es
decir, permite mandar hasta 16 caracteres por cada fila.
El LCD se puede manejar a 8 o 4 bits, se recomienda trabajar a 4 bits debido a que estos bits
son sólo para enviar el dato, para controlarlo son necesarios 2 bits más. La información de
cómo inicializar el LCD así como el protocolo de envío de datos se encuentra en la hoja de
especificaciones de este dispositivo.
Las tarjetas Miuva y ATA-NQH 0714 tienen puertos especiales para el manejo de un LCD
de 16x2, sin embargo el dato se manda de manera diferente debido a la conexión de estas
tarjetas. Se muestra en la figura G.3 las conexiones del LCD para cada tarjeta. Es por esta
razón que en la biblioteca “Comunicacion.h” se encuentran diferentes funciones para cada
tarjeta.

97
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

LCD RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
MIUVA D5 X D4 X X X X D0 D1 D2 D3
ATA-NQH D1 D2 D0 X X X X D4 D5 D6 D7
Figura G.3. Conexión de pines de LCD según el puerto de cada tarjeta

Matriz de LEDs
Como su nombre lo indica es un arreglo de LEDs, la matriz ocupada en este manual fue una
de 8x8. Cuando se trabaje con este dispositivo se deben tener las siguientes consideraciones:
 La matriz puede ser de ánodo común o cátodo común, esto es importante debido a
que se debe identificar que pines van a Vcc y cuáles van a tierra.
 Los pines que corresponde a filas y los que corresponden a columnas se encuentran
en desorden. Un error muy común cuando se trabaja con matrices es creer que los
pines de filas corresponden a una hilera y los de columnas corresponden a la otra.
 Finalmente se debe considerar que la configuración de pines puede variar entre
matrices (esto depende enteramente del fabricante) por lo que se recomienda verificar
la configuración de pines con ayuda de un multímetro.
Se muestra a continuación la diferencia entre una matriz de ánodo común y una de cátodo
común:

Figura G.4. Conexión de una matriz de LEDS de ánodo común y de cátodo común.

Este es sólo una de las múltiples configuraciones de pines que se puede encontrar para cada
matriz. Se puede resaltar que los pines de la fila se encuentran completamente en desorden,
siendo estos los pines número 9, 14, 8, 12, 1, 7,2 y 5.
Debido a la conexión de la matriz es necesario utilizar una técnica llamada multiplexado.
Esta técnica envía varios datos en diferentes instantes de tiempo, a un tiempo muy corto para
que la vista no detecte el cambio. Esto permite encender, por ejemplo, los 8 LEDS de la
diagonal de la matriz. Si no se utiliza esta técnica el resultado de querer encender la diagonal
de LEDS sería encender la matriz completa.

98
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Zumbador.
El zumbador (también conocido como Buzzer) es un dispositivo que emite un sonido cuando
se le alimenta con una señal cuadrada a una frecuencia de aproximadamente 500Hz hasta
3800Hz, esto depende del material con el que este hecho este dispositivo. Dependiendo de la
frecuencia el tono puede variar.

Sensor de temperatura
El sensor de temperatura utilizado es el LM35, el cual es un sensor de temperatura calibrado
a Celsius el cual tiene un factor lineal de 10mV/°C y un rango de temperatura de 2°C a 150°C
(usando su configuración básica ya que puede medir también temperaturas bajo cero). Este
sensor puede alimentarse con un voltaje de 4V a 20V, sin embargo el voltaje de 5V con el
que trabaja el microcontrolador es suficiente para las aplicaciones que este manual menciona.
La resolución que se alcanza con el convertidor analógico-digital está descrita por la siguiente
ecuación:
5𝑣 𝑚𝑉
𝑅𝑒𝑠𝑜𝑙𝑢𝑐𝑖ó𝑛 = = 4.88
1023𝑏𝑖𝑡𝑠 𝑏𝑖𝑡
Por lo tanto la relación centígrados-bits es:

4.88 𝑚𝑉⁄𝑏𝑖𝑡 °𝐶
= 0.488
10 𝑚𝑉⁄°𝐶 𝑏𝑖𝑡

Se muestra a continuación la conexión de cada pin del sensor LM35

Figura G.5 Conexión de pines del sensor LM35.

99
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Puente H
Para controlar un motor (de cualquier tipo) con un microcontrolador es necesario una etapa
de potencia, esto se debe a que un microcontrolador no puede suministrar la corriente
necesaria. Un puente H es precisamente una etapa de potencia capaz de separar el
microcontrolador del motor, utilizando una fuente de alimentación externa.
Un puente H está construido esencialmente por 4 transistores que operan en la región de corte
y saturación funcionando como interruptores y activados por una corriente muy pequeña la
cual puede provenir de un microcontrolador.
Se recomienda ocupar un integrado como L293 el cual contiene 2 puentes H y soporta una
corriente de 600mA. Para aplicaciones que requieren más corriente se recomiende el
integrado L298 o armar su propio puente H con transistores.

Servomotor
Un servomotor es esencialmente un motor con la capacidad de controlar el ángulo del eje,
llevándolo a posiciones específicas. Se compone principalmente de un circuito integrado
capaz de controlar la posición, un motor de corriente directa, una caja de engranajes para
reducir la velocidad y aumentar el torque y finalmente un potenciómetro que permite saber
la posición del eje de acuerdo a la variación de voltaje que proporciona el motor.
El movimiento de un servomotor está limitado a 180° y la posición se controla por medio de
una señal de PWM. La frecuencia de trabajo entre los servomotores varía desde 100Hz hasta
400Hz. Normalmente para posicionar el eje de un servo en 0° es necesario ajustar el ciclo de
trabajo a 0.3ms, mientras que para llevar el eje a 180° se debe aumentar el ciclo de trabajo a
2.1ms. Esto significa que no se ocupa completamente el ciclo de trabajo, por esto y por la
frecuencia baja de trabajo, se describió en el programa del PIC una opción particular para
controlar un servomotor sin ocupar los módulos de PWM. A continuación se muestra
gráficamente la relación de ciclo de trabajo y posición del servo.

Figura G.6 Control de servo motor con ciclo de trabajo.

100
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice H. Circuitos adicionales


En este apéndice se encuentran algunos de los circuitos utilizados en las prácticas de este
manual. Los esquemas fueron desarrollados en los programas DipTrace y Fritzing.

Conexión del Dipswitch


Se muestra en la figura H.1 el esquema de conexión para los interruptores.

Figura H.1. Conexión de interruptores al puerto D.

Se puede observar que las conexiones del microcontrolador están entre el interruptor y las
resistencias, esto con la finalidad de asegurar que se lee un 0 lógico. Las resistencias pueden
ser de cualquier valor, sin embargo se recomienda utilizar de 1KΩ.
Para ilustrar de manera más precisa este circuito se muestra a continuación un la conexión de
los interruptores en una tabla de pruebas (protoboard).

101
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura H.2. Conexión de interruptores al puerto D sobre un protoboard.

Conexión del LCD


Se muestra en la figura H.2 el esquema de conexión para el LCD.

Figura H.2. Esquema de conexión para LCD

En el pin número 3 del LCD se puede conectar un potenciómetro para variar el contraste de
este dispositivo. Esta conexión coincide con la conexión de la tarjeta ATA-NQH 0714.

Conexión del motor de corriente directa


Se muestra en la figura H.3 el esquema de conexión para el control de motor de DC con el
puente H integrado de matrícula L293.

102
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Figura H.3. Esquema de conexión para puente H.

.Se recomienda tener extrema precaución ya que una fuente de voltaje externa mal conectada
puede quemar el puente H, el microcontrolador o incluso el puerto USB.

Apéndice I. Biblioteca de comunicación


Para lograr comunicar la computadora y el microcontrolador se ocupó la biblioteca
“Comunicación.h”. A continuación se explica el funcionamiento de esta biblioteca:

Bibliotecas
Esta biblioteca contiene a su vez dos bibliotecas necesarias para la comunicación:
 USB.h
 Usb2550.h
En estas se encuentra descrito el protocolo de envío y recepción de datos.

Constantes
Se definen constantes que corresponden a las instrucciones de control descritas en el apéndice
C. Las constantes se nombraron de acuerdo a la función que desempeñan. Se muestra la
constante definida y la función que realizan:
 PAQUETE. Es el tamaño del arreglo que se envía o se recibe en la comunicación. Se
definió con tamaño 5, aunque sólo se ocupan 3 variables.
 LED_OFF. Apaga el LED o LEDs conectados al puerto E.
 LED_ON. Permite encender el LED del puerto E.
 PORTB_OUTPUT. Le indica al microcontrolador que el puerto B será utilizado
como salida.
 PORTD_OUTPUT. Le indica al microcontrolador que el puerto D será utilizado
como salida.

103
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

 PORTB_INPUT. Le indica al microcontrolador que el puerto B será utilizado como


entrada.
 PORTD_INPUT. Le indica al microcontrolador que el puerto B será utilizado como
entrada.
 ADC_ON. Habilita el convertidor analógico-digital ubicado en el pin A0.
 PWM1_ON. Habilita el módulo de PWM ubicado en el pin C2 al rango de frecuencia
más bajo que va de 3KHz, hasta 68KHz aproximadamente.
 PWM2_ON. Habilita el módulo de PWM ubicado en el pin C1 al rango de frecuencia
más bajo que va de 3KHz, hasta 68KHz aproximadamente.
 PWM1M_ON. Habilita el módulo de PWM ubicado en el pin C2 a un rango de
frecuencia intermedio de 12kHz a 270KHz aproximadamente
 PWM2M_ON. Habilita el módulo de PWM ubicado en el pin C1 a un rango de
frecuencia intermedio de 12kHz y 270KHz aproximadamente
 PWM1F_ON. Habilita el módulo de PWM ubicado en el pin C2 al rango de
frecuencia más rápido que se encuentra de 45KHz a 2MHz aproximadamente.
 PWM2F_ON. Habilita el módulo de PWM ubicado en el pin C1 al rango de
frecuencia más rápido que se encuentra de 45KHz a 2MHz aproximadamente.
 PWM_OFF. Deshabilita ambos módulos de PWM
 PB_ON. Define el pin conectado al botón pulsador (dependiendo de la tarjeta de
desarrollo puede ser C0 o E0) como entrada y manda el valor digital de la entrada, es
decir manda un 1 cuando se encuentra presionado y un 0 cuando no.
 MATRIZ_LEDS. Define el puerto B y D como salida con la finalidad de controlar
ambos puertos al mismo tiempo y poder controlar una matriz de LEDs.
 MIUVA . Se recibe como parámetro para inicializar un LCD o mandar caracteres
según la configuración de la tarjeta Miuva.
 ATANQH. Se recibe como parámetro para inicializar un LCD o mandar caracteres
según la configuración de la tarjeta ATA-NQH.
Variables
Se mencionan las variables definidas en esta biblioteca con la finalidad de comprender el uso
de estas:
 𝑒𝑠𝑐𝑟𝑖𝑏𝑖𝑟𝑢𝑠𝑏. Esta es un arreglo de tipo caracter de tamaño 5 (definida por la
constante PAQUETE) el cual almacena los datos que se desean enviar al
microcontrolador.
 𝑙𝑒𝑒𝑟𝑢𝑠𝑏. Esta es un arreglo de tipo caracter de tamaño 5 (definida por la constante
PAQUETE) el cual almacena los datos que se reciben del microcontrolador.
 𝑎. Esta variable de tipo largo, no tiene ninguna aplicación útil, sólo se usa como in
parámetro requerido en la función de recepción de datos.
 𝑚𝑦𝑢𝑠𝑏. Es un objeto de tipo USB el cual esta descrito en las bibliotecas incluidas. El
concepto de objeto pertenece a un tipo de programación más avanzado el cual es
llamado programación orientada a objetos.

104
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Funciones
En esta biblioteca se encuentran descritas las funciones que permiten el envío y recepción de
datos:
 𝑚𝑎𝑛𝑑𝑎𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒. Esta función (como su nombre lo indica) envía información al
microcontrolador, ésta se encuentra sobrecargada (esto quiere decir que la misma
función hace diferentes cosas según los parámetros que se agreguen). Cabe señalar
que los datos se manejan como apuntadores, por lo que se requiere el operador “&”
seguida de la variable que contiene los datos. Las opciones de parámetros son:
 𝑟𝑒𝑐𝑖𝑏𝑖𝑟𝑝𝑎𝑞𝑢𝑒𝑡𝑒. Esta función, recibe la información del microcontrolador. Como
parámetros tiene una variable de control y una de dato. También se sobrecargo la
función para enviar 1 o 2 datos al mismo tiempo.
 𝑖𝑛𝑖𝑐𝑖𝑎𝑟𝑙𝑐𝑑. Esta función manda una serie de instrucciones al LCD, las cuales lo
inicializan y permiten utilizar el dispositivo a 4 bits. Acepta como parámetro el
nombre de la tarjeta que se esté ocupando.
 𝑚𝑎𝑛𝑑𝑎𝑟𝑐𝑎𝑟𝑎𝑐𝑡𝑒𝑟𝐿𝐶𝐷. Permite mandar caracter por caracter al LCD. Acepta 2
parámetros, el primero es el nombre de la tarjeta y el segundo es el dato tipo caracter.
 𝐵𝑜𝑟𝑟𝑎𝑟𝐿𝐶𝐷. Deja en blanco en LCD y acepta como parámetro el nombre de la
tarjeta a ocupar.
 𝐿𝐶𝐷𝐿𝑖𝑛𝑒𝑎2. Desplaza el cursor a la segunda línea y permite escribir en ésta.

105
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Apéndice J. Instalación de Drivers


Los archivos necesarios para instalar los drivers se encuentran en la carpeta driver_vista_7,
la cual será proporcionada con este manual. En esta se encuentran los archivos:
 loctls.h
 mchpusb.cat
 mchpusb.inf
 mchpusb.sys
 mchpusb64.sys

Para instalar estos archivos en versiones posteriores a Windows 7 es necesario desactivar la


restricción de instalación de drivers sin firma. Se muestra a continuación para cada versión
de Windows los pasos para desactivar esta restricción. Si se desea instalar en Windows 7 o
anteriores puede saltarse directamente a la parte 2.

Parte 1
Para Windows 8
Es necesario entrar al menú de configuración (PC settings para versiones en inglés) dando
click en la opción de “cambiar configuración” como se muestra en la siguiente imagen.

Una vez abierta la ventana de configuración se selecciona la opción de “Uso general” y se


presiona el botón de Reiniciar ahora en la sección de Inicio Avanzado.

106
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Una vez reiniciado el sistema se mostrarán las siguientes opciones. Se seleccionará


Solucionar problemas (Troubleshoot).

Se selecciona Opciones avanzadas (Advanced ptions)

107
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Se selecciona Configuración de inicio (Startup settings)

Se selecciona la opción de Reiniciar (Restart).

Una vez aparezca el menú que se muestra a continuación se debe presionar la tecla 7 o F7,
esto reiniciará el equipo y la restricción de drivers quedará deshabilitada.

108
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Para Windows 8.1


Es necesario entrar al menú de configuración (PC settings para versiones en inglés) dando
click en la opción de “cambiar configuración” como se muestra en la siguiente imagen.

Se selecciona la opción Actualizar y recuperar

Se selecciona la opción recuperación y se da Click en el botón de “Reiniciar ahora”

109
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Una vez reiniciado el sistema se mostrarán las siguientes opciones. Se seleccionará


Solucionar problemas (Troubleshoot).

Se selecciona Opciones avanzadas (Advanced ptions)

110
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Se selecciona Configuración de inicio (Startup settings)

Se selecciona la opción de Reiniciar (Restart).

Una vez aparezca el menú que se muestra a continuación se debe presionar la tecla 7 o F7,
esto reiniciará el equipo y la restricción de drivers quedará deshabilitada.

111
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Para Windows 10
Se da click en el botón de inicio y se selecciona Opciones (Settings). Se abrirá la siguiente
ventana y se seleccionará la opción de Actualización y seguridad (Update & Security).

Se abrirá la siguiente ventana y se debe seleccionar la opción de Reiniciar ahora (Restart


now) en la pestaña de Recuperación como se muestra.

112
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Una vez reiniciado el sistema se mostrarán las siguientes opciones. Se seleccionará


Solucionar problemas (Troubleshoot).

Se selecciona Opciones avanzadas (Advanced ptions)

Se selecciona Configuración de inicio (Startup settings)

113
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Se selecciona la opción de Reiniciar (Restart).

Una vez aparezca el menú que se muestra a continuación se debe presionar la tecla 7 o F7,
esto reiniciará el equipo y la restricción de drivers quedará deshabilitada.

Parte 2
Una vez desactivada la restricción se puede proceder a instalar los drivers. Se abre el
administrador de dispositivos, el cual se encuentra en el panel de control.

114
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Una vez abierta la ventana de Administrado de dispositivos se conecta el microcontrolador


con el programa cargado. Al actualizarse la lista de dispositivos el microcontrolador
aparecerá con un signo de advertencia en la pestaña otros dispositivos

Se da click derecho en el dispositivo con el símbolo de advertencia y se selecciona la opción


de propiedades. Se abrirá la siguiente ventana y será necesario dar click en actualizar
controlador

115
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Se selecciona la opción Buscar software de controlador en el equipo.

Se busca la carpeta donde se encuentran los drivers y se selecciona siguiente

El sistema abrirá una ventana de seguridad, es necesario ignorar la advertencia y seleccionar


la opción de instalar el software de todas formas.

El sistema tardara unos minutos en instalar el driver, al final mostrara una ventana la cual
dice que se ha instalado el software exitosamente.

116
MANUAL DE PRÁCTICAS DE PROGRAMACIÓN.

Al cerrar esta ventana se puede observar en el menú de Administrador de dispositivo un


nuevo icono llamado Prototipos PIC USB con el dispositivo PIC 600. Una forma de
corroborar la instalación correcta del driver es que el PIC debe hacer parpadear un LED sólo
si la computadora lo ha reconocido correctamente.

117

Вам также может понравиться