Kitabı oku: «Compilador C CCS y Simulador Proteus para Microcontroladores PIC», sayfa 3
2.11 Librerías, drivers y ejemplos
CCS también suministra una serie de ficheros que facilitan su uso. Entre ello se encuentran librerías de estándar C, drivers de lcd gráficos, teclados, memorias serie, etc; además incluye un número importante de ejemplos.
2.12 Entorno de trabajo de CCS C Compiler
2.12.1 Introducción
CCS suministra tres compiladores básicos, el PCB, el PCM y el PCH; PCB se utiliza para PIC de 12 bits, el PCM para 14 bits y el PCH para 16 bits. Las limitaciones en la utilización de todos los elementos del CCS dependerán del PIC empleado.
Además, incluye los compiladores con Windows IDE (PCW y PCWH) que engloban a los compiladores anteriores. El PCW puede compilar con PCB y PCM y el PCWH con cualquiera de los tres.
Los ficheros de salida que maneja el compilador son de 8-bit hexadecimales, 16-bit hexadecimales y binarios. Los ficheros de depuración son compatibles con Microchip: ficheros COD, MAP y COF.
Los ficheros más habituales son:
•.C: son los ficheros fuente que contienen el código en lenguaje C.
•.H: son ficheros de cabecera estándar o creados por el usuario y permiten definir patillas, registros, funciones, etc.
•.PJT: fichero de proyecto; contiene toda la información relacionada con el proyecto.
•.LST: muestra un listado con el código C y el código ensamblador asociado para cada línea de código.
•.SYM: muestra las posiciones y valores de los registros y las variables del programa.
•.STA: muestra una estadística de la utilización de la RAM, ROM y la PILA.
•.TRE: muestra un árbol del programa donde se especifican las funciones y sus llamadas, con la ROM y RAM usada en cada una de ellas.
•.HEX: fichero estándar para la programación del PIC.
•.COF: fichero binario que incluye el código máquina y la información para la depuración correspondiente.
2.12.2 Entorno de trabajo
El entorno de trabajo del CCS en PCW y PCWH permite compilar y también suministra una gran variedad de herramientas auxiliares. En la figura 2 se muestra los distintos elementos básicos del entorno de trabajo. Existen dos formas de iniciar una sesión: abriendo un fichero de código fuente o creando un proyecto.

Figura 2. Entorno de Trabajo
Para abrir un fichero fuente directamente se realiza una pulsación sobre el icono para el manejo de ficheros (figura 3) y aparece un menú donde podemos crear, abrir, guardar o cerrar ficheros. Con el comando NEW podemos crear un fichero fuente, un proyecto, un fichero RTF o un fichero de diagrama de flujo.

Figura 3. Los menús para el manejo de los ficheros
Con la opción NEW → SOURCE FILE, el programa pide el nombre del nuevo fichero y crea una nueva ventana en blanco donde podemos empezar a escribir (Figura 4).

Figura 4. Fichero fuente nuevo
Si se ejecuta el comando PROJECT WIZARD, tras pedir el nombre del nuevo proyecto aparece la ventana de configuración con dos pestañas, una para configurar las distintas opciones que se muestran en la barra de la izquierda (figura 5) y otra donde se muestra el código resultante de la configuración (figura 6). Recorriendo las distintas opciones (general, communications, etc.) se llega a obtener el código de configuración deseado (figura 7), tras lo cual ya podemos empezar a escribir el resto del código del programa. Debemos observar como se incluye un fichero de cabecera *.h donde se encuentra la configuración del dispositivo (figura 8).

Figura 5. Ventana de configuración de las opciones

Figura 6. Ventana de configuración con el código resultante

Figura 7. El código después de una configuración

Figura 8. El fichero de cabecera con la configuración del PIC
2.12.2.1 El primer programa
La opción del PROJECT WIZARD es muy cómoda pero para comenzar a trabajar con CCS C, se recomienda iniciar los ficheros de código fuente directamente hasta que el programador adquiera los conocimientos básicos para manejar esta opción.
Así pues abrimos un fichero fuente nuevo donde se escribirá un programa para encender y apagar un led durante 1 segundo. El led se conectará a la patilla RB7 de un PIC16F876 trabajando a una frecuencia de 4 MHz. En los siguientes temas se irán explicando cada una de las sentencias utilizadas, ahora lo interesante es manejar el entorno de trabajo y no tanto lo que hace cada sentencia.
Lo primero es utilizar el fichero de cabecera donde se especifican las características del microcontrolador PIC:

Este fichero lo suministra CCS y lo incorpora en el directorio de dispositivos (devices). El compilador tiene una ruta de búsqueda para los ficheros #include; esta ruta se puede modificar en el caso de querer incluir ficheros que se encuentren en otros directorios. Con el comando OPTIONS → PROJECTS OPTIONS → INCLUDE FILES se accede a una ventana (figura 9) donde se puede añadir, eliminar o modificar el orden de búsqueda de los ficheros #include (también podemos observar que se pueden configurar los ficheros de trabajo –FILES– o los ficheros de salida –OUTPUT FILES–).

Figura 9. Ruta de búsqueda de los ficheros #include
A continuación se definen, mediante las correspondientes directivas, la velocidad del PIC y el puerto utilizado. Es importante definir la velocidad inmediatamente después del PIC ya que muchos drivers (como el LCD) la necesitan para configurarse.

Ahora se puede describir la función principal MAIN ( ). Los cambios de color, letra, etc., se puede configurar desde la opción OPTIONS → EDITOR PROPERTIES…
Al escribir el programa (figura 10) podemos observar como aparece un árbol de funciones a la izquierda de la ventana de programa; esto permite expandir o contraer las funciones y declaraciones de control para optimizar la visualización de los programas más complejos (figura 11).

Figura 10. El programa

Figura 11. Contrayendo el árbol
En el editor de texto se puede pulsar el botón derecho sobre cualquier línea (figura 12); en el caso de los ficheros #include permite abrirlos en una pestaña adicional.

Figura 12. Las opciones del botón derecho
Como ayuda para escribir el programa, CCS ofrece el comando VIEW (figura 13) que permite visualizar las interrupciones (Valid Interrupts), fusibles de configuración (Valid Fuses), hojas de características (Data Sheet) y una ventana completa donde se describe el PIC (Device Table Editor) mediante distintas pestañas (esta opción también es accesible desde la opción TOOLS → DEVICE EDITOR (ver figura 15).

Figura 13. Comando VIEW
Se puede proceder a la compilación, que se puede hacer con el comando COMPILE → COMPILE o directamente con la tecla de función <F9>. Durante la compilación aparece una ventana donde se informa del proceso de compilación y si hay errores (figura 14). Tras la compilación aparece una ventana con los mensajes de error si los hubiese o el porcentaje de utilización de la memoria RAM y ROM si la compilación ha sido correcta (figura 15).
NOTA |
¡ATENCIÓN! Si se escribe un fichero fuente y a continuación se abre o se crea un segundo fichero fuente, al compilar este último se compilará el primero. Se compila siempre el PRIMER fichero abierto. También si se renombra un fichero, al compilar se hará sobre el anterior, por lo que hay que cerrar el fichero y abrirlo de nuevo. |

Figura 14. Ventana de compilación

Figura 15. Mensajes de compilación
Tras la compilación se obtiene, entre otros, el fichero HEX para programar o simular el PIC. En OPTIONS → PROJECT OPTIONS → OUPUT FILES, se pueden configurar los ficheros de salida (figura 16).

Figura 16. Ficheros de salida
En la parte izquierda del fichero fuente aparecen unas ventanas auxiliares (Identifiers, Projects, Files) en las que se pueden observar la estructura de fichero del programa compilado (figura 17). Haciendo una pulsación en cualquiera de ellos se abre una pestaña con su contenido.

Figura 17. Ventana auxiliar para ficheros
En la barra estándar –figura 18– (para activarla: OPTIONS → TOOLBAR… → TOOLBARS, figura 19), también aparecen distintos comandos entre los que se encuentran la visualización de los ficheros de salida.

Figura 18. Barra estándar

Figura 19. Activación barras de herramientas
Hay un fichero de salida especialmente útil para la simulación con el PROTEUS VSM, se trata del fichero RAM SYMBOL MAP (*.SYM) donde aparecen todas las variables de la memoria RAM y sus correspondientes direcciones. Por ejemplo, si en un programa existe una variable FLOAT llamada TEMP, se puede consultar su dirección a través de este fichero (figura 20) para utilizarla en el WATCH del PROTEUS (figura 21 y figura 22).

Figura 20. Fichero de salida SYM

Figura 21. Configuración del WATCH en el PROTEUS

Figura 22. Ventana de WATCH con la variable
Capítulo 3
La gestión de los puertos
3.1 Introducción
Los microcontroladores PIC tienen terminales de entrada/salida divididos en puertos, que se encuentran nombrados alfabéticamente A, B, C, D, etc. Cada puerto puede tener hasta 8 terminales que, de forma básica, se comportan como una entrada/ salida digital. Según las características del PIC, cada puerto puede tener, además, asignado un bloque funcional: convertidor AD, USART, I2C, etc.
Por ejemplo, en la familia PIC16F87X (figura 1), pueden llegar hasta 5 puertos en el PIC16F877 donde se pueden encontrar bloques de TIMERS, CCP, MSSP, USART, PSP y convertidores AD.

Figura 1. Características de la familia PIC16F87X
Considerando a los puertos como entradas/salidas digitales, los puertos se caracterizan por ser independientes, es decir, se puede programar cada terminal del puerto para que se comporte como una entrada o una salida digital (figura 2). La habilitación como entrada o salida se realiza a través del registro TRISx (TRISA: 85h, TRISB: 86h, TRISC: 87h, TRISD: 88h o TRISE: 89h en el BANCO 1 de la memo-ria RAM).
NOTA |
Un valor 0 en estos registros indica que el terminal correspondiente del puerto es de salida, mientras que un valor 1 indica que será de entrada. |
La gestión del bus de datos se realiza a través de los registros PORTx (PORTA: 05h, PORTB: 06h, PORTC: 07h, PORTD: 08h o PORTE: 09h en el BANCO 0 de la memoria RAM).

Figura 2. Estructura básica de un terminal
También existen algunos terminales que poseen unas características especiales, por ejemplo:
•En el puerto A, el terminal RA4 tiene salida en drenador abierto lo que obliga a utilizar una resistencia de pull-up en el caso de funcionar como salida. Este terminal tiene entrada en trigger-schmitt lo que permite su utilización como entrada de contador de eventos externos en conjunción con un modulo temporizador (TIMER).
•En el puerto B, los terminales tienen una resistencia de pull-up interna que se puede habilitar a través del bit RBPU del registro OPTION_REG (81h, 181h). Si dicho bit es 1, todas las resistencias de pull-up estarán deshabilitadas, si es un 0 estarán habilitadas sólo en el caso de que el terminal funcione como entrada (figura 3).

Figura 3. Registro OPTION_REG
Bit 7: | RPBU: Habilita las resistencias de pull-up. 1=Las deshabilita. 0=Las habilita todas. |
Las características eléctricas de los puertos delimitan su utilización para manejar cargas de forma directa.

Figura 4. Características eléctricas de los puertos de un PIC16F84
Estos niveles de tensión permiten trabajar con cargas de bajo consumo como leds, displays de 7 segmentos o LCD, pero para activar cargas de mayor consumo es necesaria la utilización de transistores.
3.2 Gestión de puertos en C
En lenguaje C se pueden gestionar los puertos de dos formas:
•Se declaran los registros TRISX y PORTX definiendo su posición en la memoria RAM como variables de C.
•Utilizando las directivas específicas del compilador (#USE FAST_IO, #USE FIXED_IO, #USE STANDARD_IO).
3.2.1 A través de la RAM
Se definen los registros PORTx y TRISx como bytes y se sitúan en la posición correspondiente de la memoria RAM. La directiva utilizada de C es #BYTE:
#BYTE variable=constante;


Una vez definidas estas variables se pueden configurar y controlar los puertos a través de los comandos de asignación.

Escritura en los puertos:

Lectura de puertos:

Manejo de sentencias:

Existen unas funciones de C que permiten trabajar bit a bit con los registros o variables definidas previamente. Estas funciones son las siguientes:
bit_clear (var,bit); | // Pone a 0 el bit específico (0 a 7) de la variable. |
bit_set (var , bit); | // Pone a 1 el bit específico (0 a 7) de la variable. |
bit_test (var , bit); | // Muestra el bit específico (0 a 7) de la variable. |
swap (var); | // Intercambia los 4 bits de mayor peso por los 4 de // menor peso de la variable |

Se puede declarar un bit de un registro con una variable mediante la directiva #BIT, lo que permite trabajar directamente con el terminal:
#BIT nombre = posición.bit

Ejemplo 1: Se configuran los terminales RB1 como salida y el RB0 como entrada (con resistencia de pull-up). La salida debe tener el mismo valor que la entrada. Se utiliza un interruptor en la entrada y un led en la salida (figura 5). Componentes ISIS: PIC16F876, RES, LED-BLUE y SW-SPST-MOM.

Figura 5. El esquema del ejemplo 1

Figura 6. El programa del ejemplo 1
3.2.2 A través de las directivas
El compilador ofrece funciones predefinidas para trabajar con los puertos. Estas funciones son:
output_X (valor); | // Por el puerto correspondiente saca el valor (0-255). |
input_X(); | // Se obtiene el valor en el puerto correspondiente. |
set_tris_X(valor); | // Carga el registro TRISx con el valor (0-255). |
port_b_pullups (valor); | // Mediante valor = TRUE o valor = FALSE habilita // o deshabilita las resistencias de pull-up en PORTB. |
get_trisX() | // Devuelve el valor del registro TRISx |
Donde la X es la inicial del puerto correspondiente (A, B, C,…).

Existen una serie de funciones asociadas a un terminal o pin*. El parámetro pin* se define en un fichero include (por ejemplo, 16F876.h) con un formato del tipo PIN_Xn, donde X es el puerto y n es el número de pin.
#define PIN_A0 40
#define PIN_A1 41
Las funciones son:
output_low (pin*); | // Pin a 0. |
output_high (pin*); | // Pin a 1. |
output_bit (pin* , valor); | // Pin al valor especificado. |
output_toggle(pin*); | // Complementa el valor del pin. |
output_float (pin*); | // Pin de entrada, quedando a tensión flotante…// (simula salida en drenador abierto) |
input_state(pin*); | // Lee el valor del pin sin cambiar el sentido del// terminal. |
input(pin*); | // Lee el valor del pin. |
Hay que asegurarse de que los registros TRIS están correctamente definidos. Entonces, el ejemplo 1 quedaría :

#USE STANDARD_IO (PUERTO) [PUERTO: A…]
Con la función output_x() el compilador se asegura de que el terminal, o terminales correspondientes, sean de salida mediante la modificación del TRIS correspondiente. Con la función input_x() ocurre lo mismo pero asegurando el terminal (terminales) como entrada. Es la directiva por defecto. Entonces, el ejemplo 1 quedaría:

#USE FIXED_IO (PUERTO_OUTPUTS=pin* , ...) [PUERTO: A...]
El compilador se encarga de generar el código para definir los puertos de acuerdo con la información que indica la directiva (donde sólo se indican los terminales de salida), sin tener en cuenta si la operación es de entrada o de salida. Entonces, el ejemplo 1 quedaría:

3.2.3 Con punteros
En C se puede acceder a la memoria de datos mediante punteros. Los punteros se deben definir como INT:


Ejemplo 2: Realizar un contador de 0 a 99 con un doble display de 7 segmentos de cátodo común. La cuenta debe ser continua y de 0 a 9 el digito de las decenas debe estar apagado. Componentes ISIS: PIC16F876, RX8 y 7SEG-MPX2-CA-BLUE.

Figura 7. El esquema del ejemplo 2


Figura 8. El programa del ejemplo 2
Los terminales de los dos displays son comunes por lo que el dato es común; para que aparezca el digito sólo en las unidades, o sólo en las decenas, se debe apagar el otro display mediante el terminal de cátodo. Es decir, si se desea visualizar las unidades se pasa el código “10” al display y si son las decenas se pasa el “01” (con un 1 el display está apagado y con un 0 está encendido). La alternancia entre los dos cátodos debe ser tan rápida que el ojo no se de cuenta del parpadeo. En el caso que las decenas sean cero, su display se apagará.
CONST DISPLAY[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} permite visualizar de 0 a 9 mediante la combinación de dígitos típica de los displays de 7 segmentos (figura 9). Por ejemplo, en el 0 se encienden a, b, c, d, e y f, lo que significa 111111, 0x3F en hexadecimal.

Figura 9. Los 7 segmentos del display
Ücretsiz ön izlemeyi tamamladınız.