Chapter 3 – Methodology
3.5 Ethnography
3.5.6 Interviews
Según la plantilla para la escritura de un programa en lenguaje C, definida en el capítulo 1, se creó el código fuente.
3.2.2.1 Directivas de Preprocesador.
En la figura 3.2 se muestran las directivas de preprocesador usadas al principio del programa. A pesar de que en el formato de la plantilla las directivas de preprocesador aparecen al principio, estas también se pueden encontrar en otra posición dentro del código, como pueden ser las directivas que califican una función, las usadas para escribir código en lenguaje ensamblador, etc.
Estas directivas se dividieron en dos bloques.
a) El primero (figura 3.2) pregunta si está definido un compilador para PICs de gama media (PCM), o para PICs de gama alta (PCH). Con el objetivo de hacer compatible este programa para dos tipos de procesadores. En cada caso se define:
• El fichero .h inherente al dispositivo que se usará mediante una directiva
#include.
• La palabra de configuración que se usará a la hora de quemar el programa en el microcontrolador mediante la directiva #fuses.
• La frecuencia del oscilador que usará el microcontrolador mediante la directiva #use.
• El uso del modulo USART, la razón de baudios de la comunicación, y los pines de transmisión y recepción mediante la directiva #use.
b) El segundo (figura 3.2) incluye los ficheros string.h e input.c mediante la directiva #include. Estos ficheros contienen funciones de trabajo con cadenas de caracteres y funciones de recepción de caracteres a por el pin RS232 RCV.
Figura 3.2 Directivas de Preprocesador.
3.2.2.2 Definición de Constantes.
El uso de constantes permite simplicidad y proporciona un código más comprensible y claro, por lo que esta aplicación no está exenta al uso de las mismas. En la figura 3.3 se muestran las constantes usadas.
Figura 3.3 Definición de constates.
3.2.2.3 Declaraciones de Variables Globales.
El uso de variables globales no es buena práctica de programación, porque cualquier función podrá modificarlas. Por tanto si ocurre algún error en tiempo de ejecución con la involucración de estas variables, la corrección del mismo puede tornarse difícil. (Colectivo de Autores, 2004)
Debido a que se está programando para un microcontrolador, con el uso de las variables globales se gana en eficiencia, en comparación con el paso de variables por referencia o por valor. En la figura 3.4 se muestra la declaración de las variables globales utilizadas en el programa.
Figura 3.4 Declaración de variables globales.
En esta declaración se ven tres tipos de datos distintos, char, int8, int1.Los dos primero utilizan 8 bits, mientras que el último utiliza solo un bit. Al utilizar el calificativo const en la declaración del arreglo Morse_Code, este va a permanecer constante durante la ejecución del programa. Aprovechándose de esto el compilador automáticamente lo ubica en la memoria de programas, la cual es más extensa que la de datos. Este arreglo no se muestra completo producto de su extensión (ver anexo VI).
3.2.2.4 Prototipos de Funciones.
Las funciones tienen dos formas de escribirse en el código fuente. Una sería escribiéndolas completamente antes de usarlas. En la otra forma se escribe solo el prototipo antes de usarlas, y luego se definen. Esta última forma es la recomendada, brindando más claridad en el código fuente. (Colectivo de Autores, 2004)
En los prototipos de funciones se escriben todas las funciones utilizadas excepto las llamadas para la atención de una interrupción. En la figura 3.5 se muestran los prototipos de las funciones utilizadas en el programa.
Figura 3.5 Prototipos de funciones.
Los prototipos de funciones también sirven como un resumen de las funciones utilizadas, cuando se desea comprender un código. En este caso se puede ver que existen solamente cinco funciones aparte de la función principal y las funciones de atención a las interrupciones. Estas funciones tienen como objetivo:
• Inicializar_Registros: inicializar los registros internos del microcontrolador usados en la aplicación.
• Enviar_Oracion_en_RAM: transmitir el código Morse de una oración almacenada en memoria RAM.
• Enviar_Oracion_en_EEPROM: transmitir el código Morse de una oración almacenada en memoria EEPROM.
• Enviar_Serie_Oracion_en_EEPROM: transmitir serie una oración almacenada en memoria EEPROM.
• Guardar_Oracion_en_EEPROM: Guardar una oración en memoria EEPROM.
3.2.2.5 Definición de Funciones de Atención a las Interrupciones.
Utilizando la directiva de preprocesador #int _xxx, se le dice al compilador que la función siguiente debe ser llamada cuando ocurra la interrupción xxx. En el programa se utilizó la interrupción del temporizador 1. Ver figura 3.6.
Figura 3.6 Atención a la interrupción del temporizador 1.
En la figura se puede ver que la función clock_isr ( ), que se encarga de la forma de onda de salida y de la conversión de caracteres a su correspondiente código Morse, será llamada cada vez que ocurra un desbordamiento del temporizador 1. Para esto anteriormente se debió habilitar la interrupción global mediante la función enable_interrupts pasándole como parámetro la constante GLOBAL, y la interrupción del temporizador 1, mediante la llamada a la misma función, pasándole como parámetro la constante INT_TIMER1, ver el anexo VI.
El número de interrupciones que permite cada microcontrolador está definido en el fichero .h del dispositivo. La tabla 3.1 muestra solo algunas de las interrupciones. Otras directivas de interrupciones relevantes son:
• #int_default. Indica que la función que le sigue será llamada cuando ocurra una interrupción la cual no tiene asignada ninguna función.
• #int_global. Indica que la función que le sigue será llamada cuando ocurra cualquier interrupción. Dicha función reemplazará la forma en que el compilador maneja las interrupciones. Esta forma normalmente no se usa, pero en caso de hacerse deberá ser con cuidado, debido a que el compilador no salvará los registros. (Custom Computer Services, Inc., 2007)
Tabla 3.1 Interrupciones.
Directiva de Preprocesador Fuente de interrupción.
#INT_AD Conversión análogo-digital completa. #INT_EEPROM Escritura en EEPROM completada.
#INT_EXT1 Externa 1
#INT_EXT2 Externa 2
#INT_I2C Bus I2C
#INT_LOWVOLT Bajo voltaje detectado
#INT_RB Cambio en el nibble alto del Puerto B
#INT_RDA Datos recibidos y disponibles en el módulo USART #INT_TBE Buffer de transmisión del USART vacio
#INT_RTCC Desbordamiento del temporizador 0 (RTCC) #INT_TIMER0 Desbordamiento del temporizador 0 (RTCC) #INT_TIMER1 Desbordamiento del temporizador 1
#INT_TIMER2 Desbordamiento del temporizador 2 #INT_USB Actividad en el Bus Serie Universal (USB)
3.2.2.6 Función Principal.
Esta función tiene como nombre main, y es por donde comienza a ejecutarse el código escrito por el programador. En esta subrutina se debe plantear el esquema lógico de sucesión de acciones del programa. Aquí se ubicarán los lazos principales, donde puede haber encuestas, barridos, etc. Cualquier variable que se desee declarar dentro de esta o cualquier otra función, deberá hacerse al principio del bloque. Estas variables tendrán vida solo dentro de dicho bloque (ver anexo VI).
3.2.2.7 Definición de Funciones.
En este paso se definen las funciones cuyos prototipos fueros escritos antes de usarlas. Esto se realiza cumpliendo con el estándar ANSI, en la figura 3.7 se muestra parte de la definición de funciones utilizada en el programa.
Figura 3.7 Definición de funciones.