154537554-Tutorial-XC8

download 154537554-Tutorial-XC8

of 32

Transcript of 154537554-Tutorial-XC8

  • 8/13/2019 154537554-Tutorial-XC8

    1/32

    [Tutorial XC8] Introduccin

    Aqu se presenta un tutorial del compilador XC8que pretende proporcionar los conocimientos bsicos para comenzar a desarrollar con

    el mismo, para ello daremos una introduccin de cmo es un microcontrolador PIC y su funcionamiento, los lenguajes de programacin

    y la ventaja de usar C, como crear un proyecto, la estructura de un programa en C y lo necesario para ir creando ejemplos. Espero sea de

    utilidad

    Licencia

    La misma se expresa al pie de cada articulo.

    Indice

    Introduccin al microcontrolador El lenguaje de programacin Comenzando a desarrollar en C Nuestro primer proyecto en un PIC18F4550 y XC8 Operadores, variables y estructura for Estructura if y arreglos de variables

    Introduccin al microcontrolador

    Un microcontrolador es un dispositivo electrnico capaz de ejecutar una secuencia de comandos previamente programados. Estos

    comandos son proyectados por el usuario utilizando algn lenguaje de programacin y luego grabados en la memoria del

    microcontrolador.

    Los microcontroladores PIC de gama baja poseen arquitectura Harvard, esto quiere decir que utilizan dos memorias distintas, una para

    almacenar las instrucciones y otra para manejar los datos. Entonces est compuesto principalmente por un procesador (CPU), memoria

    RAM, memoria ROM y buses de comunicaciones (cada tipo de memoria tiene un bus de datos, uno de direcciones y uno de control)

    Adicionalmente tambin dispone de puertos de entrada y salida, y diversos perifricos que nos facilitan el desarrollo tales como

    osciladores, temporizadores/contadores, mdulos de comunicacin serial y paralela, comparadores analgicos, conversores analgicos

    a digital, memoria eeprom, etc.

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/http://www.micros-designs.com.ar/tutorial-xc8-el-lenguaje-de-programacion/http://www.micros-designs.com.ar/tutorial-xc8-el-lenguaje-de-programacion/http://www.micros-designs.com.ar/tutorial-xc8-comenzando-a-desarrollar-en-c/http://www.micros-designs.com.ar/tutorial-xc8-comenzando-a-desarrollar-en-c/http://www.micros-designs.com.ar/tutorial-xc8-nuestro-primer-proyecto-en-un-pic18f4550-y-xc8/http://www.micros-designs.com.ar/tutorial-xc8-nuestro-primer-proyecto-en-un-pic18f4550-y-xc8/http://www.micros-designs.com.ar/xc8_variables_for/http://www.micros-designs.com.ar/xc8_variables_for/http://www.micros-designs.com.ar/tutorial-xc8-estructura-if-y-arreglos-de-variables/http://www.micros-designs.com.ar/tutorial-xc8-estructura-if-y-arreglos-de-variables/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/inicio/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/inicio/http://www.micros-designs.com.ar/tutorial-xc8-estructura-if-y-arreglos-de-variables/http://www.micros-designs.com.ar/xc8_variables_for/http://www.micros-designs.com.ar/tutorial-xc8-nuestro-primer-proyecto-en-un-pic18f4550-y-xc8/http://www.micros-designs.com.ar/tutorial-xc8-comenzando-a-desarrollar-en-c/http://www.micros-designs.com.ar/tutorial-xc8-el-lenguaje-de-programacion/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/
  • 8/13/2019 154537554-Tutorial-XC8

    2/32

    Pero vayamos por partes, as entenderemos como es su funcionamiento, igualmente cabe aclarar que seremos concisos, sin describir

    profundamente.

    La memoria ROMes del tipo no voltil, esto significa que los datos almacenados no se pierden aunque no est energizada. Se destina

    principalmente a contener la lista de instrucciones que conforman la aplicacin, por ello suele llamarse memoria de programa y en

    microcontroladores de la actualidad ronda desde los 512 bytes a 128 kbytes, correspondientes a los de gama baja de Microchip. Son del

    tipoFlash, de bajo consumo, que se pueden escribir y leer, y de gran densidad de almacenamiento. Adems tienen la ventaja que

    permiten ser reprogramadas en circuito, sin necesidad de extraer el circuito integrado de la tarjeta.

    La memoria RAM,memoria voltil, es la destinada a guardar las variables y datos temporales que sern utilizados por el procesador

    para realizar clculos u otro tipo de operaciones lgicas. El espacio de direcciones de memoria RAM se divide en dos sectores: registros

    de propsito general (GPR), espacio destinado para crear variables por el usuario y variables propias del compilador; y registros de

    funciones especiales (SFR), espacio que contiene bits de configuracin y control de los perifricos del microcontrolador. En la

    actualidad se pueden encontrar microcontroladores con memoria RAM de unos 32 bytes hasta 4 kbytes.

    Un registro es una pequea porcin de la memoria y su tamao se mide generalmente en bits (8-bits, 16-bits, 32-bits). Est

    representado por un numero que denominamos direccin de memoria, pero dentro del lenguaje de programacin existe la posibilidad

    de asignarle un nombre, de esta manera es ms sencillo de manejar.

    El CPUo unidad central de procesamiento es el encargado de direccionar la memoria ROM, decodificar la instruccin y ejecutar la

    operacin que implica. El primer paso es leer la instruccin de la memoria, la posicin es controlada por un contador de programa (PC

    que almacena un nmero que identifica la posicin actual a ejecutar. La instruccin que el CPU lee desde la memoria es usada para

    determinar qu operacin debe hacer el CPU, en este paso hay una decodificacin, en donde la instruccin es dividida en partes que

    tienen significado para otras unidades del CPU. Despus de los pasos de lectura y decodificacin, es llevado a cabo el paso de

    la ejecucin de la instruccin. Durante este paso, varias unidades del CPU son conectadas de tal manera que ellas pueden realizar la

    operacin deseada. Si, por ejemplo, una operacin de adicin fue solicitada, una unidad aritmtico lgica (ALU) ser conectada a un

    conjunto de entradas (nmeros a ser sumados) y un conjunto de salidas (suma). Luego el paso final, simplemente la obtencin del

    resultado, escribindolo en un registro interno del CPU de acceso rpido, modificando un registro de la memoria RAM o modificando e

    contador de programa para generar saltos o bucles, etc.

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/bloques01/
  • 8/13/2019 154537554-Tutorial-XC8

    3/32

    La siguiente animacin intenta dar a comprender como es el funcionamiento, pero tener en cuenta que es muy genrica:

    Actualmente existen 3 tipos de arquitectura:

    CISC(Computadores de juego de instrucciones complejo): Disponen de un conjunto amplio de instrucciones donde muchas de ellas

    son complejas, permitiendo realizar operaciones sofisticadas y potentes, pero que ocupan varios ciclos.

    RISC(Computadores de juego de instrucciones reducido): En este caso el repertorio de instrucciones mnimo y muy sencillo, y

    generalmente ocupa entre 1 o 2 ciclos. La ventaja de stos es que la sencillez y rapidez de las instrucciones permiten optimizar el

    hardware y el software del procesador.

    SISC (Computadores de juego de instrucciones especficos): Se utiliza para microcontroladores destinados a aplicaciones concretas

    donde el set de instrucciones es reducido y especfico para las tareas a desarrollar, adaptndose a las necesidades de la aplicacin

    prevista.

    Los microcontroladores de gama baja de Microchip se basan en la arquitectura RISC, con 35 instrucciones para los 16F y 75

    instrucciones para los 18F, en este ltimo caso parecen muchas pero son simples y que ocupan pocos ciclos.

    El PIC18F4550

    Ahora tenemos un conocimiento general de que compone un microcontrolador y como es su funcionamiento, as que pasaremos a uno

    puntual. En este tutorial nos basaremos en el microcontrolador PIC18F4550 de la familia PIC18 de Microchip que tiene las siguientes

    caractersticas bsicas:

    Arquitectura RISC avanzada Harvard de 16-bits con 8-bits de datos.

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/simulacion/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/bloques02/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/simulacion/http://www.micros-designs.com.ar/tutorial-xc8-introduccion/bloques02/
  • 8/13/2019 154537554-Tutorial-XC8

    4/32

    Mxima frecuencia de operacin 48 MHz, 12 MIPS. Memoria de programa de 32 kBytes. Memoria RAM de 2 kBytes. Memoria EEPROM de 256 Bytes. Multiplicador por hardware de 88 Pila de 32 niveles. 2 niveles de prioridad para las interrupciones. 20 fuentes de interrupcin. 4 temporizadores. 2 comparadores analgicos. 13 canales de conversin analgica. Comunicacin UART, SPI, I2C, USB. PLL y oscilador interno de 8 MHz.En el mismo datasheet podemos encontrar el siguiente diagrama de bloques de su estructura interna:

    Como hemos comentado anteriormente, en la memoria de programa existe una lista de instrucciones que el microcontrolador ejecuta

    de forma secuencial. Estas instrucciones son nmeros binarios de ancho establecido por la arquitectura (12, 14, 16 bits, etc.) y que, como

    es ms fcil de trabajar, se representan de forma hexadecimal. Entonces a esta lista de instrucciones se la suele denominar cdigo HEX.

    Para generar este cdigo HEX existen varios lenguajes de programacin, tenemos de bajo nivel denominado Assembler y de alto nivel

    entre los cuales podemos encontrar C, C++, Basic, Pascal, lenguaje de tipo visual, etc.

    El lenguaje Assembler no es ms que una traduccin de las instrucciones en hexadecimal que entiende el microcontrolador en

    abreviaturas ms sencillas de recordar y manejar por un programador. Requiere tener mucho conocimiento de la arquitectura y para

    proyectos grandes es extremadamente compleja su utilizacin, adems de requerir mucho ms tiempo de trabajo.

    Los lenguajes de programacin de alto nivel fueron creados con el propsito de superar estas desventajas, otorgando un mayor

    entendimiento de cmo es el flujo del programa, generando sentencias simples de entender para una persona, ya no es necesario

    conocer en profundidad el conjunto de instrucciones de la arquitectura y adems proporcionan portabilidad. O sea, un programa

    (funciones, libreras) escrito en lenguaje de alto nivel en determinado microcontrolador es mucho ms sencillo portarlo a otro

    microcontrolador, ya sea de distintas prestaciones dentro de la misma marca o un microcontrolador de otra empresa. (Principalmente

    C)

    Algunas de las ventajas de usar C son:

    Es un lenguaje simple y flexible. Permite incorporar ASM dentro del cdigo. Proporciona facilidades para realizar programas modulares y/o utilizar cdigo o libreras existentes. Sencillo de corregir errores. Es un lenguaje utilizado en todas las arquitecturas, lo que permite la portabilidad.

  • 8/13/2019 154537554-Tutorial-XC8

    5/32

    Desventajas:

    Se tiene poco control en el HEX generado. A diferencia de un programa realizado en Assembler, es menos eficiente ocupando ms espacio y siendo ms lento. Algunas sentencias pueden ser complicadas de entender.

    XC8es un nuevo compilador que ha presentadoMicrochip para las familias de microcontroladores de 8-bits (PIC10, PIC12, PIC16

    PIC18) que rene de forma integral a los antiguos compiladores Hitech PICC, Hitech PICC18 y MPLAB C18. Es un compilador

    multiplataforma, compatible con Windows, Linux y Mac. Hay diferentes opciones de descarga segn la necesidad, Pro, Estndar y Free

    con distintos niveles de optimizacin.

    XC8 puede utilizarse por medio de lnea de comandos o integrarse a un entorno de desarrollo, como MPLAB IDE o MPLAB X. Se

    encarga de realizar la compilacin de los archivos fuente del proyecto y de realizar el enlace de stos con libreras pre compiladas para la

    generacin del HEX.

    El compilador leelo escrito por el programador e intenta interpretarlo segn las reglas del lenguaje y la sintaxis de C. Si no encuentra

    errores, produce un archivo intermedio llamado objeto(con la extensin obj). En caso de tener un archivo fuente escrito en asm, este es

    ensamblado para as tambin generar un archivo objeto.

    Luego el paso siguiente para la generacin del HEX es el enlazado (link en ingles). Este toma los archivos objetos del proceso de

    compilacin y ensamblado, toma archivos objetos de libreras pre compiladas segn la necesidad del proyecto y genera el HEX que

    puede ser grabado en el microcontrolador. Adicionalmente a ste se generan otros archivos que permiten realizar depuraciones

    (simulaciones) del proyecto, como los archivos cof.

    Esto se puede ver en la siguiente imagen incluida en el manual de usuario de XC8:

    http://www.micros-designs.com.ar/tutorial-xc8-el-lenguaje-de-programacion/xc8/
  • 8/13/2019 154537554-Tutorial-XC8

    6/32

    En este tutorial utilizaremos como entorno de desarrolloMPLAB X, el cual permite integrarXC8y los pasos indicados anteriormente

    los realiza de forma automtica. Para ello crea archivos makefile que contienen los comandos y argumentos a ejecutar para generar el

    HEX. O sea, nosotros presionaremosBuild Ally si todo est correcto obtendremos los archivos objeto, el archivo cof y el archivo HEX

    listo para grabar en el microcontrolador.

    Creando un proyecto en MPLAB X y XC8

    Para comenzar a desarrollar con XC8 y MPLAB X es necesario que ambos estn instalados en la PC. Los podemos bajar directamente

    desde www.microchip.com, en este caso usaremos MPLAB X v1.2 y XC8 v1.1. El siguiente vdeo muestra los pasos para crear un

    proyecto y comenzar a trabajar:

    Una vez creado el proyecto ya podemos comenzar a desarrollar nuestro programa en C. El archivo principal, o sea el que contiene la

    funcin principal (main) generalmente tiene la siguiente estructura:

    /* Archivo: main.cAutor: SukyFecha: 20/08/12*/ Cabecera, informacin sobre el archivo pero sin importancia para el proceso de compilacin.

    #includeInclusin de archivos cabecera con informacin necesaria para las funciones implementadas en el

    proyecto. Para ello se hace uso de directivas de preprocesador.

    #pragmaconfig PLLDIV=5#pragmaconfigCPUDIV=OSC1_PLL2#pragmaconfig USBDIV=2

    #pragmaconfigFOSC=HSPLL_HS

    En los microcontroladores PIC el HEX puede contener la configuracin de los fusibles. Estosgeneralmente se colocan en el archivo fuente principal.

    unsigned charVariable1,

    Variable2;

    Declaracin de variables globales, pueden ser utilizadas por cualquiera de las funcin que se encuentran

    en el archivo fuente.

    voidvFuncion1(void);void vFuncion2(unsigned

    charData); Declaracin del prototipo de las funciones implementadas en el archivo fuente.

    http://www.micros-designs.com.ar/tutorial-xc8-el-lenguaje-de-programacion/compilacion/
  • 8/13/2019 154537554-Tutorial-XC8

    7/32

    voidmain(void){.

    vFuncion1();

    .

    while(1){

    .

    vFuncion2(45);

    .

    }

    }

    Funcin principal que el 99% de las veces incluye el ciclo infinito.

    voidvFuncion1(void){}

    voidvFuncion2(unsignedcharData){}

    Definicin de las funciones implementadas.

    Los comentarios

    Es una buena prctica comentar el cdigo fuente que vamos desarrollando, ya sea para uno mismo que despus de un tiempo retoma e

    proyecto o para otra persona que lo desea modificar o ampliar. Tenemos dos maneras de realizar los comentarios, cortos (comienzan

    con//) y multi-lineas (comienzan con /*y terminan con */). Un ejemplo:

    /* Funcin que escribe en el puerto B.

    Parmetro: Un byte a escribir

    Retorna: Nada

    */

    voidvWritePortB(charData){

    TRISB=000; // Seteamos el Puerto B como salida.

    LATB=Data; // Escribimos en el Puerto B el valor de Data.

    }

    Las directivas de preprocesador

    El preprocesador es el primer programa que se ejecuta en el proceso de compilacin y trata directivas especiales

    como#include, #define, #if, etc. Algunas de las ventajas de utilizar directivas de preprocesador son las siguientes:

    Los programas son ms fciles de leer. Son ms fciles de modificar. Permite generalizar para varias arquitecturas y compiladores.#include

  • 8/13/2019 154537554-Tutorial-XC8

    8/32

    Esta directiva de preprocesador le indica al compilador que debe incluir un archivo fuente antes de continuar. Este archivo fuente ( .h

    tendr las declaraciones de las funciones que implementa dicha librera y/o macros tiles en el proyecto. En el ejemplo mostrado

    incluimosxc.h, si buscamos que contiene encontraremos que incluye otros archivos fuente dependiendo de que microcontrolador

    estemos usando y entre esos archivos fuente encontraremos macros que nos ayudarn a crear nuestro cdigo. Como por ejemplo:

    #define Nop() asm(" nop")

    #define Sleep() asm(" sleep")

    #define WRITETIMER0(x) ((void)(TMR0H=((x)>>8),TMR0L=((x)&0xFF)))

    Adems encontraremos la declaracin de los puertos y pines del microcontrolador, registros y bits de configuracin de los perifricos

    etc., por lo tanto no tendremos que saber cual es su direccin o nmero de bit para poder trabajar con ellos.

    El archivo a incluir se puede indicar mediante comillas () o entre ngulos (). Con la primer opcin el compilador busca en la misma

    carpeta donde se encuentra el archivo que realiza el llamado o la direccin que indique el mismo y entre ngulos busca en las carpetas

    definidas como contenedoras de archivos cabecera (Path include). Ejemplos:

    #include

    #includeMiLibreria.h

    #include../Include/MiLibreria.h

    En este ltimo caso al colocar doble punto (..) el compilador sale de la carpeta donde se encuentra el archivo que hace el llamado, busca

    la carpetaIncludey dentro el archivoMiLibreria.h.

    #define

    Esta directiva permite crear un identificador para una secuencia de caracteres de la siguiente forma:

    #defineIdentificadorsecuencia_de_caracteres

    El preprocesador buscar los identificadores creados y los reemplazar por la secuencia de caracteres para su posterior compilacin

    Esto es muy til para crear cdigo que sea ms entendible a la lectura. Veamos ejemplos:

    #define FALSO 0

    #define VERDADERO 1

    #define PI 3.141592

    #define Deg2Rad(x) (x*PI/180.0)

    #define PIN_ENTRADA 1

    #define PIN_SALIDA 0

    #define ENCENDIDO 1

    #define APAGADO 0

    #define LED1 RB0

    Tengamos en cuenta que podemos crear macros que se asemejen a funciones, la ventaja que otorga es que nos ahorramos esos ciclos de

    llamada a dicha funcin pero ocupamos ms cdigo, dado que el preprocesador solo reemplaza texto por texto.

    #ifdef, #ifndef, #else, #elif y #endif

  • 8/13/2019 154537554-Tutorial-XC8

    9/32

    Estas directivas son utilizadas para realizar compilaciones condicionadas, por ejemplo para hacer una librera generalizada para varias

    arquitecturas, para ser utilizada por varios compiladores o simplemente para seleccionar el nivel de uso de cierto proyecto.

    Por ejemplo podemos crear una definicin para realizar o no debugger por puerto serial, y en cdigo si est habilitado compilar dichas

    sentencias y sino no:

    #define USE_DEBUG

    Ifdef USE_DEBUG

    printf(Debug habilitado);

    #endif

    O dependiendo de la arquitectura que se use incluir ciertos archivos fuente:

    /* HI-TECH PICC / PICC-Lite compiler */

    #if defined(__PICC__) || defined(__PICCLITE__)

    #include

    #endif

    /* HI-TECH PICC-18 compiler */

    #if defined(__PICC18__)

    #include

    #endif

    /* MPLAB C18 Compatibility Header */

    #ifdef __18CXX

    #include

    #endif

    Puede que en un principio en sus programas no implemente tantas opciones y solo se enfoque en una arquitectura, pero tener

    conocimiento ayudar a entender archivos fuentes que encontremos incluidos en el compilador (libreras) y despus con mucha ms

    practica comenzar a implementarlos

    http://www.opengroup.org/onlinepubs/009695399/functions/printf.htmlhttp://www.opengroup.org/onlinepubs/009695399/functions/printf.htmlhttp://www.opengroup.org/onlinepubs/009695399/functions/printf.html
  • 8/13/2019 154537554-Tutorial-XC8

    10/32

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/pic18f4550_bloques/
  • 8/13/2019 154537554-Tutorial-XC8

    11/32

    Su memoria de programa de de 32768 bytes, pero las instrucciones ocupan 2 bytes (excepto call, goto, movff, lsfr que ocupan 4), por lo

    que se pueden almacenar hasta 16384 instrucciones como mximo. Las direcciones especiales son 000que corresponde al reset de

    microcontrolador, 008correspondiente a la interrupcin de alta prioridad y 018correspondiente a la interrupcin de baja

    prioridad. Las prioridades de interrupciones pueden no habilitarse y comportarse como un PIC16F, o habilitarse y cada fuente de

    interrupcin (excepto la interrupcin externa por RB0, solo es de alta prioridad) tiene un bit que la configura como de alta prioridad o

    baja prioridad.

    La memoria RAM es de 2048 bytes, 8 bancos de 256 bytes donde

    4 de ellos son utilizados por el mdulo USB en caso de utilizarlo. Adems se tiene 160 bytes dedicados a los registros de funciones

    especiales utilizados para la configuracin de los mdulos del microcontrolador.

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/memoriaprograma/
  • 8/13/2019 154537554-Tutorial-XC8

    12/32

    Fsicamente es un dispositivo de 40/44

    pines donde, excepto los de alimentacin, los pines tienen varias funciones segn como se lo configure. Se puede encontrar con los

    package TQFP, QFN o DIP. Este ltimo, el ms utilizado para el aprendizaje y los hobbystas, tiene el siguiente pinout:

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/memoriaram/
  • 8/13/2019 154537554-Tutorial-XC8

    13/32

    Hay mucho ms por agregar respecto a este microcontrolador, pero no es la intensin de este tutorial, para profundizar ms es

    recomendable leer el datasheet.

    Teniendo una idea general de cmo es la estructura de un archivo fuente de C pasaremos a realizar un primer ejemplo como para

    llevarlo al hardware y ver su funcionamiento. Para trabajar nuestro microcontrolador necesita una fuente de reloj, que provea una seal

    a frecuencia constante que permita ir leyendo y ejecutando las sentencias secuencialmente. Generalmente los microcontroladores

    modernos ofrecen la posibilidad de recibir esta seal de reloj desde varias fuentes, cristales externos, osciladores externos u osciladores

    internos, pero adems permiten elevar la frecuencia de trabajo internamente (PLL). Esto permite mayor flexibilidad y adems a

    aumentar la frecuencia ejecutar ms instrucciones por segundo.

    El microcontroladorPIC18F4550que se utiliza en este tutorial incluye un PLL que permite multiplicar la frecuencia de un cristal u

    oscilador externo, pero no as del oscilador interno.

    A tener en cuenta, los microcontroladores de gama baja de Microchip necesita 4 ciclos de reloj para ejecutar una instruccin simple

    entonces tenemos que Fcy=Fosc/4. Un PIC18F4550 que puede trabajar hasta 48 MHz ejecuta como mximo 12 millones de

    instrucciones por segundo, o sea 12 MIPS.

    Para seleccionar qu tipo de fuente de reloj se utilizar y la configuracin del PLL se utilizan los bits de configuracin del

    microcontrolador que solo pueden ser modificados al ser programados. Adems de estas opciones los bits de configuracin permiten

    establecer otras caractersticas como por ejemplo, habilitar o no el reset, proteger contra lectura ciertos sectores de programa, habilitar

    el perro guardian, etc. Para ms detalles hay que estudiarse el datasheet del microcontrolador especfico, dado que en PICs pueden

    variar entre familias.

    Para configurar el reloj y PLL delPIC18F4550veamos el siguiente esquema extrado del datasheet:

    http://www.micros-designs.com.ar/tutorial-xc8-introduccion/pinout-4/
  • 8/13/2019 154537554-Tutorial-XC8

    14/32

    Vamos a fijar como frecuencia de trabajo los 48 MHz mximos que soporta el microcontrolador, para ello vamos a utilizar como fuente

    un cristal externo de 12 MHz. Para lograr los 48MHz es necesario habilitar el PLL, esto lo hacemos mediante los bits FOSC3:FOSC0.

    Para un cristal de 12 MHz se debe colocar 111x = HS oscillator, PLL enabled (HSPLL) y revisando la documentacin que provee XC8

    (doc/pic18_chipinfo.html) se debe colocar FOSC=HSPLL_HS. Si observamos la figura anterior, al habilitar el PLL la frecuencia de

    entrada del mismo debe ser 4 MHz, y para ello se provee de un divisor de frecuencia controlado por PLLDIV, en este caso los 12 MHz los

    dividimos por 3, por lo tanto debemos hacer PLLDIV=3. La frecuencia de salida del PLL es de 96 MHz, los cuales sirven de fuente de

    clock para el mdulo USB y tambin para el microcontrolador. Pero para el microcontrolador los 96 MHz los podemos dividir en 2, 3, 4

    o 6! O sea, podemos obtener gran variedad de frecuencias. Como nos establecimos como meta obtener 48 MHz debemos

    hacer CPUDIV=OSC1_PLL2. En resumen en los bit de configuraciones establecemos:

    #pragma config FOSC=HSPLL_HS, PLLDIV=3, CPUDIV=OSC1_PLL2

    http://www.micros-designs.com.ar/tutorial-xc8-nuestro-primer-proyecto-en-un-pic18f4550-y-xc8/clock/
  • 8/13/2019 154537554-Tutorial-XC8

    15/32

  • 8/13/2019 154537554-Tutorial-XC8

    16/32

    TRISB0=0;// Lo establecemos como salida

    while(TRUE){

    // _delay(x) 197120 cycles max

    LATB0=0;// Apagamos led

    __delay_ms(10);

    LATB0=1;// Encendemos led

    __delay_ms(10);

    }

    }

    Nota: Tener en cuenta que la demora generada es solo de 10ms, en simulacin se podr visualizar el titilar del led pero en una

    implementacin real no, pronto lo mejoraremos

    Pero hagamos uso de los macros!!! El ejemplo quedara as:

    /*

    * File: main.c

    * Author: Suky

    */

    #define _XTAL_FREQ 48000000

    #include

    #pragma config FOSC=HSPLL_HS, PLLDIV=3, CPUDIV=OSC1_PLL2

    #pragma config IESO=OFF, FCMEN=OFF

    #pragma config PWRT=OFF, BOR=OFF, BORV=3, VREGEN=ON, WDT=OFF

    #pragma config MCLRE=ON, XINST=OFF, LVP=OFF, PBADEN=OFF

    #define PIN_DIR_LED TRISB0

    #define PIN_LED LATB0

    #define OUTPUT 0

    #define INPUT 1

    #define ON 1

    #define OFF 0

    voidmain(void) {

    PIN_DIR_LED=OUTPUT;

    while(TRUE){

    // _delay(x) 197120 cycles max

    PIN_LED=OFF;

    __delay_ms(10);

    PIN_LED=ON;

    __delay_ms(10);

  • 8/13/2019 154537554-Tutorial-XC8

    17/32

    }

    }

    Se dan cuenta que si quiero cambiar de pin para controlar el Led se hace mucho ms sencillo? Y eso que solo es un ejemplo muy

    sencillo!

    En este ejemplo solo implementamos la funcin principal (void main(void)) que debe estar si o si en nuestro proyecto, pues el

    compilador tiene una funcin que es llamada al ocurrir un reset (vector 000) la cual inicializa el puntero de la pila (Stack en ingles)

    las variables inicializadas, etc. y luego llama a la funcin main().

    Esta funcin puede contener el cdigo para inicializar el hardware de la forma que nosotros queramos, o llamar a funciones adicionales

    que hagan esta tarea y luego generalmente tiene el bucle infinito. Este bucle debe estar si o si, sino al terminar de ejecutar las

    instrucciones el microcontrolador se resetea. Dentro del bucle tendremos lo que queremos que el microcontrolador ejecute

    peridicamente hasta ser reseteado. En C un bucle infinito se puede hacer de varias formas, aqu usamos la sentencia while:

    while(Condicion){Sentencias}

    Esta sentencia o estructura de control de C permite ejecutar las sentencias que contiene de forma cclica mientras la condicin sea

    verdadera. Tener en cuenta que primero se pregunta si la condicin es cierta y luego ejecuta las sentencias. Como la condicin en

    nuestro caso es TRUE (1), se ejecuta de forma infinita.

    Esto representado en un diagrama de flujo sera la siguiente:

    Otra forma de implementarlo es usando la sentencia do-while:

    http://www.micros-designs.com.ar/tutorial-xc8-nuestro-primer-proyecto-en-un-pic18f4550-y-xc8/flujo_001/
  • 8/13/2019 154537554-Tutorial-XC8

    18/32

    do{Sentencias}while(Condicion);

    En este caso las sentencias se ejecutan primero y luego se pregunta la condicin, por lo que las sentencias se ejecutan mnimo una vez.

    El hardware mnimo para poder implementar el ejemplo seria el siguiente:

    Operadores en C

    Operador de asignacin: Permite asignar un valor al operando izquierdo en base al operando derecho. El valor

    puede truncarse dependiendo del tipo de variable del operando izquierdo. Veamos unos ejemplos.

    unsignedcharK;// Variable que puede tomar valores enteros entre 0 y 255.

    floatJ;// Flotante de 24-bits

    K=150;// k adquiere el valor 150.

    K= 796;// k adquiere el valor 28. 796 necesita 16-bits para ser almacenado, pero como la variable

    es de 8-bits, los 8-bits altos se pierden.

    J=10; // J adquiere el valor 10.0

    J=95000.0;// J adquiere el valor 95000.0

    J=95001.0;// J adquiere el valor 95002.0. Esto es debido a la resolucin que se logra con 24-bits,

    si cambiamos a 32-bits podremos almacenar 95001.0.

    El truncamiento tambin ocurre cuando la asignacin es mediante otra variable:

    unsignedcharK;

    unsignedintA=796;

    http://www.micros-designs.com.ar/tutorial-xc8-nuestro-primer-proyecto-en-un-pic18f4550-y-xc8/esquema001/
  • 8/13/2019 154537554-Tutorial-XC8

    19/32

    K=A;// K adquiere el valor 28.

    Operadores de comparacin:Permiten comparar dos operandos y determinar si es falso o verdadero. La

    siguiente tabla los describe:

    Operador Descripcin Ejemplo

    == Retorna true si los operandos son iguales

    k==0, k==0,

    k==a

    = Retorna true si los operandos son distintos k!=0, k!=0, k!=a

    =a

    Operadores aritmticos:Bsicamente, permiten realizar clculos aritmticos como suma, resta, divisin, etc..

    Operador Descripcin Ejemplo

    + Suma A=5+4; // A adquiere el valor 9

    - Resta A=20-8; // A adquiere el valor 12

    * Multiplicacin A=15*10; // A adquiere el valor 150

    / Divisin

    A=15/6; // Si A en un entero adquiere el valor 2

    // Si A es un flotante adquiere el valor 2.5

    ++ Incremento A++; // Es igual a realizar A+1

    Decremento A; // Es igual a realizar A-1

    Operadores lgicos:Retornan un valor lgico, true o false, en base a las denominadas tablas de verdad. Los

    operadores son:

    Operador Descripcin Ejemplo

    && AND (k0)

  • 8/13/2019 154537554-Tutorial-XC8

    20/32

    || OR (k==3) || (k==15)

    ! NOT !(k

    0b10101010

    B=0xF0 ->

    0b11110000

    C=A&B=0xA0 ->

  • 8/13/2019 154537554-Tutorial-XC8

    21/32

    0b10100000

    |

    OR, compara dos bits, si cualquiera de los dos bits es 1 el

    resultado es 1, en otro caso ser 0.

    A=0x0A ->

    0b00001010

    B=0xF0 ->

    0b11110000

    C=A|B=0xFA ->

    0b11111010

    ^

    XOR, compara dos bits, si cualquiera de los dos bits es 1 pero

    no ambos el resultado es 1, en otro caso ser 0.

    A=0xFA -> 0b11111010

    B=0xAF -> 0b10101111

    C=A^B=055 ->

    0b01010101

    ~ Complemento, retorna el complemento a 1 del operando

    A=0xAA ->

    0b10101010

    B=~A=055 ->

    0b01010101

    >>

    Desplazamiento a derecha, desplaza a la derecha un numero

    de bit especificado

    A=037 -> 0b00110111

    B=A>>2=0x0D ->

    0b00001101

    0b00110111

    B=A> tiene diferente comportamiento dependiendo el tipo de dato al que se le va a aplicar. Ms

    precisamente si la variable fue creada con signo o sin signo.

    EJEMPLO:creamos dos variables

  • 8/13/2019 154537554-Tutorial-XC8

    22/32

    unsignedcharA=100;

    signedcharB=-100;

    Valor de A= 100, valor decimal.

    Valor de A en binario: 01100100.

    Valor de A en binario luego de aplicarle shift >> 2:

    Valor en binario: 00011001, en este caso el bit ms significativo se indica con un cero y los bits que se

    desplacen hacia la derecha del bit ms significativo se completan con ceros 0.

    Valor de B= -100, valor decimal

    Valor de B en binario: 10011100

    Valor de B en binario luego de aplicarle shift >> 2:

    Valor de B en binario: 11100111, en este caso el bit ms significativo se mantiene para indicar el signo negativo y

    los bits que se desplacen hacia la derecha del bit ms significativo se completan con unos 1.

    Variables en CUna variable no es ms que la asignacin de un nombre a una direccin de memoria, la cual dependiendo del

    tipo puede ocupar uno o ms bytes. La sintaxis es la siguiente:

    ;

    Tenemos dos tipos de variables, variables globales que pueden ser utilizadas/modificadas por cualquiera de las

    funciones dentro del mismo archivo fuente o variables locales que pueden ser utilizadas solo en la funcin que

    ha sido declarada.

    unsignedcharVariableGlobal;

    voidvMiFuncion(void){

    unsignedcharVariableLocal;

    VariableGlobal=10;

    VariableLocal=55;

    }

    voidmain(void){

    VariableGlobal=60;

    }

    En XC8 disponemos de los siguientes tipos de datos:

  • 8/13/2019 154537554-Tutorial-XC8

    23/32

    Los tipos bit y short long son tipos no estndar disponibles en XC8. En el caso de los tipos flotantes se puede

    ver que dice 24 o 32 bits, esto depende de la configuracin del proyecto que por defecto viene establecido en

    24-bits.

    Adicionalmente al tipo se pueden implementar modificadores que darn informacin adicional del modo en

    que sern utilizadas las variables. XC8 admite los modificadores estndar de ANSI C y modificadores

    especiales que son tiles en sistemas embebidos en microcontroladores de 8-bits.

    Const: Indicara que la variable es solo de lectura y que no se modificar. Al definirse de esta manera la variable

    se localiza en la memoria de programa. Puede indicarse la direccin absoluta de donde ubicarla de la siguiente

    manera:

    const char MiConstante @ 0100=50;

    Volatile: Indicar al compilador que no se asegura que se mantendr su valor en accesos sucesivos. Este tipo de

    modificador debe utilizarse en variables que son modificadas en interrupciones y que son testeadas en el

    programa principal. Esto es para evitar que el compilador al detectar que la variable no es modificada en dos

    puntos dados del cdigo haga un cacheo del valor de la variable. Ejemplo:

    http://www.micros-designs.com.ar/xc8_variables_for/variables/
  • 8/13/2019 154537554-Tutorial-XC8

    24/32

    volatilebit MiBandera=0;

    voidinterrupcin(void){// Evento impredecible generado asincrnicamente por el hardware.

    MiBandera=1;

    }

    voidmain(void){

    while(1){

    if(MiBandera==1){

    MiBandera=0;

    }

    }

    }

    Pesistent: Le indica al compilador que dicha variable no debe ser inicializada a 0 en el inicio. Por default si a

    una variable no se le asigna un valor al declararla en el inicio es establecida en 0, al colocar persisten esto se

    evita y mantiene su valor al ocurrir un reset.

    persisten char VariablePesistente;

    Near: Le indica al compilador que la variable debe estar en el banco de acceso (PIC18), con lo cual puede ser

    accedida sin importar el banco de memoria que este seleccionado. Esto reduce el cdigo y los tiempos de

    ejecucin ya que no es necesario el cambio de banco.

    near char VariableAcceso;

    En la siguiente imagen podemos ver la diferencia entre el modo de acceso a una variable near y otra ubicada en

    otros bancos:

    near unsignedchark;

    unsignedcharj @ 0x100;

    unsignedchari @ 0x200;

  • 8/13/2019 154537554-Tutorial-XC8

    25/32

    EEPROM: Le indica al compilador que la variable ser ubicada en la memoria EEPROM. Tengan en cuenta que

    se crea cdigo adicional para acceder a esta memoria y que es mucho ms lento.

    Static: Le indica al compilador que le asigne una posicin fija automtica, pero que reserve su espacio incluso

    en variables locales. Las variables locales estticas slo tiene alcance en la funcin o bloque en el que se

    definen, pero a diferencia de las variables no-static, su memoria se reserva para toda la duracin del programa.

    Sirven para retener el valor de la variable en llamadas sucesivas a dicha funcin.

    Extern: Le indica al compilador que la variable declarada pertenece a otro mdulo (otra funcin u otro archivo

    fuente), por lo que no es necesario reservar memoria para ella.

    Hemos dado un vistazo general de que es una variable y de qu modo se comportara dependiendo de con que

    modificadores sea declarada. Ahora presentaremos la estructura de control for, para de esta manera mejorar

    nuestro primer ejemplo.

    Estructura de control for

    Esta estructura se usa para ejecutar un bloque de cdigo cierto nmero de veces. Posee un valor de inicio, un

    valor final y un valor de incremento.

    for(Valor inicial, condicin, incremento){

    Sentencias.

    }

    http://www.micros-designs.com.ar/xc8_variables_for/near/
  • 8/13/2019 154537554-Tutorial-XC8

    26/32

    Ejemplo:

    unsignedchark, a;

    for(k=0;k

  • 8/13/2019 154537554-Tutorial-XC8

    27/32

    #define PIN_DIR_LED TRISB0

    #define PIN_LED LATB0

    #define OUTPUT 0

    #define INPUT 1

    #define ON 1

    #define OFF 0

    voidmain(void) {

    Unsigned chark;

    PIN_DIR_LED=OUTPUT;

    while(TRUE){

    // _delay(x) 197120 cycles max

    PIN_LED=OFF;

    for(k=0;k

  • 8/13/2019 154537554-Tutorial-XC8

    28/32

    if(){

    // Sentencias 1

    }else{

    // Sentencias 2

    }

    Ejemplos:

    If(RB0==1){// Es RB0 igual a 1?

    LATB1=1; // Si

    }else{ // No, entonces

    LATB1=0;

    }

    if(MiVariable>=5){

    LATC0=1;

    LATC1=1;

    }else{

    LATC0=1;

    LATC1=0;

    }

    Cuando se utilizan estructuras de control y operadores lgicos hay que tener en cuenta la precedencia

    Las expresiones vinculadas por &&o ||son evaluadas de izquierda a derecha, y la evaluacin se

    detiene tan pronto como se conoce el resultado verdadero o falso. Ejemplo:

    if((k

  • 8/13/2019 154537554-Tutorial-XC8

    29/32

    unsignedcharVector[10];

    unsignedintMatriz[5][5];

    // Cargamos un valor a un elemento:

    Vector[4]=150;

    Matriz[2][4]=1024;

    // Leemos un valor:LATB=Vector[0];

    LATC=Matriz[0][4];

    Cuando declaramos el arreglo podemos cargar los valores iniciales de la siguiente manera:

    unsignedcharVector[10]={10,0x15,A,};

    unsignedintMatriz[5][5]={78,0x56,1,0b11,};

    Nota:Esto solo se puede hacer al declararse, en otro caso debe accederse al elemento mediante un

    ndice.Cadenas.

    Para manejar string (cadena de caracteres ascii) en C se deben crear arreglos de char con suficiente

    espacio como para manejar los string a utilizar ms un byte adicional para almacenar el carcter nulo

    (0, \0), el cual indica final de string. Entonces si sabemos que los string a utilizar dentro del

    algoritmo van a tener como mximo 10 caracteres, el arreglo a crear debe ser de 11 posiciones:

    charstring[11]=Mi arreglo;

    Esto equivale a:

    charstring[11]=M,i, a,r ,r ,e ,g ,l ,o ,\0;

    Como C no maneja string, no podemos utilizar los operandos como para enteros o flotantes, se deben

    utilizar funciones especificas para trabajar con ellos. C en su biblioteca estndar incluye la

    librera string.h la cual dispone de funciones para comparar strings, para concatenar strings, para

    copiar strings, para buscar caracteres dentro del string, etc. Para ms informacin leer el help de la

    misma.

    Un ejemplo que vamos a realizar para ejercitar lo mostrado hasta el momento ser visualizar

    mediante un display de 7 segmentos la cuenta de pulsaciones que realicemos. El hardware a utiliza

    sera el siguiente:

  • 8/13/2019 154537554-Tutorial-XC8

    30/32

    Cdigo:

    /*

    * File: main.c

    * Author: Suky

    */

    #define _XTAL_FREQ 48000000

    #include

    #pragma config FOSC=HSPLL_HS, PLLDIV=3, CPUDIV=OSC1_PLL2

    #pragma config IESO=OFF, FCMEN=OFF

    #pragma config PWRT=OFF, BOR=OFF, BORV=3, VREGEN=ON, WDT=OFF

    #pragma config MCLRE=ON, XINST=OFF, LVP=OFF, PBADEN=OFF

    #define PIN_DIR_SW TRISB4

    #define PIN_SW RB4

    #define PORT_DIR_DISPLAY TRISD

    #define PORT_DISPLAY LATD

    #define OUTPUT 0

    #define INPUT 1

    #define ON 1

    #define OFF 0

    constunsignedcharDisplay7SegAC[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}

    ;

    voidmain(void) {

    unsignedchark,j;

    PIN_DIR_SW=INPUT;

    http://www.micros-designs.com.ar/tutorial-xc8-estructura-if-y-arreglos-de-variables/esquema002/
  • 8/13/2019 154537554-Tutorial-XC8

    31/32

    PORT_DIR_DISPLAY=0x00;

    // Comienza en 0

    PORT_DISPLAY=Display7SegAC[0];// El display es de Anodo Comun, como el arreglo..

    // ..es para Catodo Comun se realiza el complemento

    xD

    k=0;

    while(TRUE){if(PIN_SW==0){

    __delay_ms(10);// Preguntamos, esperamos y volvemos a preguntar para evitar

    el efecto rebote..

    if(PIN_SW==0){ // .. de esta manera nos aseguramos que es una pulsacin

    valida.

    if(++k==10){// Primero se incrementa k, luego se compara..

    k=0;

    }

    PORT_DISPLAY=Display7SegAC[k];// Cargamos nuevo valor

    while(PIN_SW==0);// Esperamos a que se suelte

    }

    }

    }

    }

    Diagrama de flujo:

  • 8/13/2019 154537554-Tutorial-XC8

    32/32

    http://www.micros-designs.com.ar/tutorial-xc8-estructura-if-y-arreglos-de-variables/flujo_002/